diff --git a/lemarche/cms/blocks.py b/lemarche/cms/blocks.py index 0e67ce18e..11a8b28c0 100644 --- a/lemarche/cms/blocks.py +++ b/lemarche/cms/blocks.py @@ -1,4 +1,6 @@ # common blocks +from uuid import uuid4 + from wagtail import blocks from wagtail.images.blocks import ImageChooserBlock @@ -232,3 +234,33 @@ class Meta: template = "cms/streams/section_why_call_siaes.html" icon = "pen" label = "Pourquoi faire appel à un prestataire inclusif ?" + + +class FAQBlock(blocks.StructBlock): + question = blocks.CharBlock(required=True, help_text="La question fréquemment posée.") + answer = blocks.RichTextBlock(required=True, help_text="La réponse à la question.") + + def get_context(self, value, parent_context=None): + context = super().get_context(value, parent_context=parent_context) + context["faq_id"] = f"faq-{str(uuid4())[:6]}" + return context + + class Meta: + icon = "help" + label = "Question/Réponse" + template = "cms/streams/faq_block.html" + + +class FAQGroupBlock(blocks.StructBlock): + group_title = blocks.CharBlock(required=True, help_text="Le titre du groupe de questions-réponses.") + faqs = blocks.ListBlock(FAQBlock()) + + def get_context(self, value, parent_context=None): + context = super().get_context(value, parent_context=parent_context) + context["group_id"] = f"group-{str(uuid4())[:6]}" + return context + + class Meta: + icon = "folder" + label = "Groupe de FAQ" + template = "cms/streams/faq_group_block.html" diff --git a/lemarche/cms/migrations/0012_faqpage.py b/lemarche/cms/migrations/0012_faqpage.py new file mode 100644 index 000000000..d63f9ee8d --- /dev/null +++ b/lemarche/cms/migrations/0012_faqpage.py @@ -0,0 +1,93 @@ +# Generated by Django 4.2.13 on 2024-07-16 17:55 + +import django.db.models.deletion +import modelcluster.fields +import wagtail.blocks +import wagtail.fields +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("cms", "0011_infocard"), + ] + + operations = [ + migrations.CreateModel( + name="FAQPage", + fields=[ + ( + "page_ptr", + models.OneToOneField( + auto_created=True, + on_delete=django.db.models.deletion.CASCADE, + parent_link=True, + primary_key=True, + serialize=False, + to="wagtailcore.page", + ), + ), + ("intro", models.TextField(blank=True, null=True, verbose_name="Introduction")), + ( + "faqs", + wagtail.fields.StreamField( + [ + ( + "faq_group", + wagtail.blocks.StructBlock( + [ + ( + "group_title", + wagtail.blocks.CharBlock( + help_text="Le titre du groupe de questions-réponses.", required=True + ), + ), + ( + "faqs", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "question", + wagtail.blocks.CharBlock( + help_text="La question fréquemment posée.", + required=True, + ), + ), + ( + "answer", + wagtail.blocks.RichTextBlock( + help_text="La réponse à la question.", required=True + ), + ), + ] + ) + ), + ), + ] + ), + ) + ], + blank=True, + use_json_field=True, + ), + ), + ("categories", modelcluster.fields.ParentalManyToManyField(blank=True, to="cms.articlecategory")), + ( + "image", + models.ForeignKey( + blank=True, + null=True, + on_delete=django.db.models.deletion.SET_NULL, + related_name="+", + to="wagtailimages.image", + ), + ), + ], + options={ + "verbose_name": "FAQ Page", + "verbose_name_plural": "FAQ Pages", + }, + bases=("wagtailcore.page",), + ), + ] diff --git a/lemarche/cms/migrations/0013_alter_articlepage_intro_alter_faqpage_intro.py b/lemarche/cms/migrations/0013_alter_articlepage_intro_alter_faqpage_intro.py new file mode 100644 index 000000000..4159792a4 --- /dev/null +++ b/lemarche/cms/migrations/0013_alter_articlepage_intro_alter_faqpage_intro.py @@ -0,0 +1,22 @@ +# Generated by Django 4.2.13 on 2024-07-16 18:22 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("cms", "0012_faqpage"), + ] + + operations = [ + migrations.AlterField( + model_name="articlepage", + name="intro", + field=models.TextField(blank=True, null=True, verbose_name="Introduction de la page"), + ), + migrations.AlterField( + model_name="faqpage", + name="intro", + field=models.TextField(blank=True, null=True, verbose_name="Introduction de la page"), + ), + ] diff --git a/lemarche/cms/models.py b/lemarche/cms/models.py index 2ea6ee3a9..b86b8c504 100644 --- a/lemarche/cms/models.py +++ b/lemarche/cms/models.py @@ -15,13 +15,27 @@ from lemarche.pages.models import PageFragment -class ArticlePage(Page): - intro = models.TextField(verbose_name="Introduction", null=True, blank=True) +class ArticleBase(Page): + intro = models.TextField(verbose_name="Introduction de la page", null=True, blank=True) image = models.ForeignKey( "wagtailimages.Image", null=True, blank=True, on_delete=models.SET_NULL, related_name="+" ) categories = ParentalManyToManyField("cms.ArticleCategory", blank=True) + content_panels = Page.content_panels + [ + FieldPanel("intro", classname="full"), + MultiFieldPanel([FieldPanel("categories", widget=forms.CheckboxSelectMultiple)], heading="Categories"), + FieldPanel( + "image", + classname="collapsible", + ), + ] + + class Meta: + abstract = True + + +class ArticlePage(ArticleBase): is_static_page = models.BooleanField(verbose_name="c'est une page statique ?", default=False) with_cta_tender = models.BooleanField(verbose_name="avec un CTA pour les besoins ?", default=False) @@ -47,7 +61,7 @@ def get_template(self, request, *args, **kwargs): # Editor panels configuration - content_panels = Page.content_panels + [ + content_panels = ArticleBase.content_panels + [ FieldPanel("intro", classname="full"), FieldPanel("with_cta_tender", classname="full"), MultiFieldPanel([FieldPanel("categories", widget=forms.CheckboxSelectMultiple)], heading="Categories"), @@ -225,3 +239,22 @@ def get_context(self, request, *args, **kwargs): except PageFragment.DoesNotExist: pass return context + + +class FAQPage(ArticleBase): + faqs = StreamField( + [ + ("faq_group", blocks.FAQGroupBlock()), + ], + blank=True, + use_json_field=True, + ) + content_panels = ArticleBase.content_panels + [ + FieldPanel("faqs"), + ] + + parent_page_types = ["wagtailcore.Page", "cms.HomePage", "cms.ArticleList", "cms.PaidArticleList"] + + class Meta: + verbose_name = "FAQ Page" + verbose_name_plural = "FAQ Pages" diff --git a/lemarche/templates/cms/faq_page.html b/lemarche/templates/cms/faq_page.html new file mode 100644 index 000000000..3e7c33194 --- /dev/null +++ b/lemarche/templates/cms/faq_page.html @@ -0,0 +1,8 @@ +{% extends "layouts/base.html" %} +{% block content %} +
{{ page.intro|default:"" }}
+ {% for block in page.faqs %}{{ block }}{% endfor %} +{{ faq.title }}
{% endcomment %} + {% include_block faq with parent_id=group_id %} + {% endfor %} +