diff --git a/home/models.py b/home/models.py index 80c57b405821f9dc2ab41906c4a26075575b01b2..6b4e563acc4667c21257c7e0740fdec00401d506 100644 --- a/home/models.py +++ b/home/models.py @@ -6,6 +6,7 @@ from taggit.models import TaggedItemBase from wagtail.admin.panels import ( FieldPanel, MultiFieldPanel, + InlinePanel, ObjectList, TabbedInterface, ) @@ -403,6 +404,21 @@ class HomeArticlePage(HomeContentPageMixin): verbose_name="Obrázek", ) + content = RichTextField( + verbose_name="Obsah", + features=[ + "h2", "h3", "h4", + "bold", "italic", + "ol", "ul", + "hr", + "link", + "document-link", + "image", + "embed", + "footnotes", + ], + ) + show_image_on_homepage = models.BooleanField( verbose_name="Zobrazovat obrázek na homepage", default=False, @@ -431,6 +447,7 @@ class HomeArticlePage(HomeContentPageMixin): FieldPanel("perex", icon="pilcrow"), FieldPanel("tags", icon="tag"), FieldPanel("content", icon="pilcrow"), + InlinePanel("footnotes", label="Footnotes", icon="pilcrow"), ] class Meta: diff --git a/home/templates/home/home_article_page.html b/home/templates/home/home_article_page.html index 64cf5efee700a3ac944aad39eeea71118ecce69b..b3f3ccf723583a19581d12f007a7322a4931531d 100644 --- a/home/templates/home/home_article_page.html +++ b/home/templates/home/home_article_page.html @@ -1,5 +1,5 @@ {% extends "base.html" %} -{% load static wagtailcore_tags wagtailimages_tags %} +{% load static wagtailcore_tags wagtailimages_tags footnotes %} {% block content %} <main class="flex flex-col items-center gap-10 pt-14"> @@ -42,7 +42,9 @@ <p class="mb-3">{{ page.perex }}</p> - {{ page.content|richtext }} + {% richtext_footnotes page.content|richtext %} + + {% include "home/includes/footnotes.html" %} </div> </div> </main> diff --git a/home/templates/home/includes/footnotes.html b/home/templates/home/includes/footnotes.html new file mode 100644 index 0000000000000000000000000000000000000000..39cfae52ade19493b384900307ce9276a2c0a154 --- /dev/null +++ b/home/templates/home/includes/footnotes.html @@ -0,0 +1,20 @@ +{% load wagtailcore_tags %} + +{% if page.footnotes_list %} + <div class="footnotes" id="footnotes"> + <hr class="my-8"> + <ol> + {% for footnote in page.footnotes_list %} + <li id="footnote-{{ forloop.counter }}"> + <div class="[&>p:last-of-type]:inline-block"> + {{ footnote.text|richtext }} + <a + href="#footnote-source-{{ forloop.counter }}" + aria-label="Přeskočit na obsah" + >↩</a> + </div> + </li> + {% endfor %} + </ol> + </div> +{% endif %} diff --git a/home/templatetags/footnotes.py b/home/templatetags/footnotes.py new file mode 100644 index 0000000000000000000000000000000000000000..9331bd6876355bad3a26658083ce84ae24d6073e --- /dev/null +++ b/home/templatetags/footnotes.py @@ -0,0 +1,42 @@ +from django.template import Library +import re +from wagtail.models import Page +from django.utils.safestring import mark_safe + +register = Library() + + +@register.simple_tag(takes_context=True) +def richtext_footnotes(context, html): + """ + example: {% richtext_footnotes page.body|richtext %} + + html: already processed richtext field html + Assumes "page" in context. + """ + FIND_FOOTNOTE_TAG = re.compile(r'<footnote id="(.*?)">.*?</footnote>') + + if not isinstance(context.get("page"), Page): + return html + + page = context["page"] + if not hasattr(page, "footnotes_list"): + page.footnotes_list = [] + footnotes = {str(footnote.uuid): footnote for footnote in page.footnotes.all()} + + def replace_tag(match): + try: + index = process_footnote(match.group(1), page) + except (KeyError, ValidationError): + return "" + else: + return f'<a href="#footnote-{index}" id="footnote-source-{index}"><sup>[{index}]</sup></a>' + + def process_footnote(footnote_id, page): + footnote = footnotes[footnote_id] + if footnote not in page.footnotes_list: + page.footnotes_list.append(footnote) + # Add 1 to the index as footnotes are indexed starting at 1 not 0. + return page.footnotes_list.index(footnote) + 1 + + return mark_safe(FIND_FOOTNOTE_TAG.sub(replace_tag, html)) diff --git a/institut/settings/base.py b/institut/settings/base.py index 7330ad8c0a96fe5a050dec7f09e62ac45f291e12..e2ebb9eba361c10b26fee7d26266011775f8cfc4 100644 --- a/institut/settings/base.py +++ b/institut/settings/base.py @@ -48,6 +48,7 @@ INSTALLED_APPS = [ "wagtail.images", "wagtail.search", "wagtail.admin", + "wagtail_footnotes", "wagtail", "modelcluster", "taggit", diff --git a/institut/urls.py b/institut/urls.py index 1768475890857365c9f964bc3afcc5d6dd8ced75..744b08cb9e2e3aed81a3b996dc613e883f77213b 100644 --- a/institut/urls.py +++ b/institut/urls.py @@ -4,10 +4,12 @@ from django.urls import include, path from wagtail import urls as wagtail_urls from wagtail.admin import urls as wagtailadmin_urls from wagtail.documents import urls as wagtaildocs_urls +from wagtail_footnotes import urls as footnotes_urls urlpatterns = [ path("django-admin/", admin.site.urls), path("admin/", include(wagtailadmin_urls)), + path("footnotes/", include(footnotes_urls)), path("documents/", include(wagtaildocs_urls)), ] diff --git a/requirements/base.txt b/requirements/base.txt index 7a996fcb52225acc3278aa89430fe3e53ee0d506..5d8f90c3ab7358d16593b863591846a02d43e550 100644 --- a/requirements/base.txt +++ b/requirements/base.txt @@ -1,6 +1,7 @@ dj-database-url==2.0.0 django-environ==0.9.0 +django-taggit==3.1.0 +django-modelcluster==6.0 psycopg2-binary==2.9.6 wagtail==5.0.2 -django-taggit==4.0.0 -django-modelcluster==6.0 +wagtail-footnotes==0.10.0