From 83644eb207d4d39312999e487ac5989d11307383 Mon Sep 17 00:00:00 2001 From: "madjid.asa" Date: Mon, 15 Jul 2024 18:11:05 +0200 Subject: [PATCH 1/6] feat(cms): ajout de page de FAQ --- lemarche/cms/blocks.py | 34 ++++++++ lemarche/cms/migrations/0012_faqpage.py | 80 +++++++++++++++++++ lemarche/cms/models.py | 17 ++++ lemarche/templates/cms/faq_page.html | 7 ++ lemarche/templates/cms/streams/faq_block.html | 17 ++++ .../cms/streams/faq_group_block.html | 10 +++ 6 files changed, 165 insertions(+) create mode 100644 lemarche/cms/migrations/0012_faqpage.py create mode 100644 lemarche/templates/cms/faq_page.html create mode 100644 lemarche/templates/cms/streams/faq_block.html create mode 100644 lemarche/templates/cms/streams/faq_group_block.html diff --git a/lemarche/cms/blocks.py b/lemarche/cms/blocks.py index 0e67ce18e..5b823a944 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,35 @@ class Meta: template = "cms/streams/section_why_call_siaes.html" icon = "pen" label = "Pourquoi faire appel à un prestataire inclusif ?" + + +class FAQBlock(blocks.StructBlock): + # id = blocks.CharBlock(required=True, default=uuid4(), help_text="L'identifiant unique pour cette question.") + 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): + # id = blocks.CharBlock(required=True, default=uuid4(), help_text="L'identifiant unique pour cette question.") + 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..5aa32514a --- /dev/null +++ b/lemarche/cms/migrations/0012_faqpage.py @@ -0,0 +1,80 @@ +# Generated by Django 4.2.13 on 2024-07-15 16:10 + +import django.db.models.deletion +import wagtail.blocks +import wagtail.fields +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("wagtailcore", "0093_uploadedfile"), + ("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", + ), + ), + ( + "body", + 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, + ), + ), + ], + options={ + "verbose_name": "FAQ Page", + "verbose_name_plural": "FAQ Pages", + }, + bases=("wagtailcore.page",), + ), + ] diff --git a/lemarche/cms/models.py b/lemarche/cms/models.py index 2ea6ee3a9..846e7ebf4 100644 --- a/lemarche/cms/models.py +++ b/lemarche/cms/models.py @@ -225,3 +225,20 @@ def get_context(self, request, *args, **kwargs): except PageFragment.DoesNotExist: pass return context + + +class FAQPage(Page): + body = StreamField( + [ + ("faq_group", blocks.FAQGroupBlock()), + ], + blank=True, + ) + + content_panels = Page.content_panels + [ + FieldPanel("body"), + ] + + 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..74efe341b --- /dev/null +++ b/lemarche/templates/cms/faq_page.html @@ -0,0 +1,7 @@ +{% extends "layouts/base.html" %} +{% block content %} +
+

{{ page.title }}

+ {% for block in page.body %}{{ block }}{% endfor %} +
+{% endblock %} diff --git a/lemarche/templates/cms/streams/faq_block.html b/lemarche/templates/cms/streams/faq_block.html new file mode 100644 index 000000000..a346bd951 --- /dev/null +++ b/lemarche/templates/cms/streams/faq_block.html @@ -0,0 +1,17 @@ +
+
+

+ +

+
+
+
{{ self.answer }}
+
+
diff --git a/lemarche/templates/cms/streams/faq_group_block.html b/lemarche/templates/cms/streams/faq_group_block.html new file mode 100644 index 000000000..df3c85df9 --- /dev/null +++ b/lemarche/templates/cms/streams/faq_group_block.html @@ -0,0 +1,10 @@ +{% load wagtailcore_tags %} +
+

{{ self.group_title }}

+
+ {% for faq in self.faqs %} + {% comment %}

{{ faq.title }}

{% endcomment %} + {% include_block faq with parent_id=group_id %} + {% endfor %} +
+
From a5f661214224cd8a34796b152db79038241d8132 Mon Sep 17 00:00:00 2001 From: "madjid.asa" Date: Tue, 16 Jul 2024 12:27:02 +0200 Subject: [PATCH 2/6] fix streamfield json --- lemarche/cms/migrations/0012_faqpage.py | 1 + lemarche/cms/models.py | 1 + 2 files changed, 2 insertions(+) diff --git a/lemarche/cms/migrations/0012_faqpage.py b/lemarche/cms/migrations/0012_faqpage.py index 5aa32514a..572cfc276 100644 --- a/lemarche/cms/migrations/0012_faqpage.py +++ b/lemarche/cms/migrations/0012_faqpage.py @@ -68,6 +68,7 @@ class Migration(migrations.Migration): ) ], blank=True, + use_json_field=True, ), ), ], diff --git a/lemarche/cms/models.py b/lemarche/cms/models.py index 846e7ebf4..fac5e69eb 100644 --- a/lemarche/cms/models.py +++ b/lemarche/cms/models.py @@ -233,6 +233,7 @@ class FAQPage(Page): ("faq_group", blocks.FAQGroupBlock()), ], blank=True, + use_json_field=True, ) content_panels = Page.content_panels + [ From 204633c64cd16d5e033e3e5254cfb8ed49c7fa66 Mon Sep 17 00:00:00 2001 From: "madjid.asa" Date: Tue, 16 Jul 2024 13:32:15 +0200 Subject: [PATCH 3/6] update dahsboard siaes and update FAQ models --- lemarche/cms/models.py | 30 ++++++++++++++----- lemarche/templates/cms/faq_page.html | 5 ++-- .../cms/streams/faq_group_block.html | 2 +- lemarche/www/dashboard/views.py | 12 ++++++-- 4 files changed, 36 insertions(+), 13 deletions(-) diff --git a/lemarche/cms/models.py b/lemarche/cms/models.py index fac5e69eb..4e1aca314 100644 --- a/lemarche/cms/models.py +++ b/lemarche/cms/models.py @@ -15,13 +15,27 @@ from lemarche.pages.models import PageFragment -class ArticlePage(Page): +class ArticleBase(Page): intro = models.TextField(verbose_name="Introduction", 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"), @@ -227,19 +241,21 @@ def get_context(self, request, *args, **kwargs): return context -class FAQPage(Page): - body = StreamField( +class FAQPage(ArticleBase): + faqs = StreamField( [ ("faq_group", blocks.FAQGroupBlock()), ], blank=True, use_json_field=True, ) - - content_panels = Page.content_panels + [ - FieldPanel("body"), + content_panels = ArticleBase.content_panels + [ + MultiFieldPanel([FieldPanel("categories", widget=forms.CheckboxSelectMultiple)], heading="Categories"), + 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 index 74efe341b..3e7c33194 100644 --- a/lemarche/templates/cms/faq_page.html +++ b/lemarche/templates/cms/faq_page.html @@ -1,7 +1,8 @@ {% extends "layouts/base.html" %} {% block content %} -
+

{{ page.title }}

- {% for block in page.body %}{{ block }}{% endfor %} +

{{ page.intro|default:"" }}

+ {% for block in page.faqs %}{{ block }}{% endfor %}
{% endblock %} diff --git a/lemarche/templates/cms/streams/faq_group_block.html b/lemarche/templates/cms/streams/faq_group_block.html index df3c85df9..3bdc29593 100644 --- a/lemarche/templates/cms/streams/faq_group_block.html +++ b/lemarche/templates/cms/streams/faq_group_block.html @@ -1,5 +1,5 @@ {% load wagtailcore_tags %} -
+

{{ self.group_title }}

{% for faq in self.faqs %} diff --git a/lemarche/www/dashboard/views.py b/lemarche/www/dashboard/views.py index c5b816a56..dce114929 100644 --- a/lemarche/www/dashboard/views.py +++ b/lemarche/www/dashboard/views.py @@ -53,13 +53,19 @@ def get_context_data(self, **kwargs): try: # Look for the blog category by its slug. category = ArticleCategory.objects.get(slug=category_slug) - article_list = article_list.filter(categories__in=[category]) - except Exception: + last_faq_page = category.faqpage_set.last() + article_list = article_list.filter(categories__in=[category])[:3] + if last_faq_page: + article_list = list(article_list[:2]) + article_list.insert(0, last_faq_page) + + except ArticleCategory.DoesNotExist: category_slug = None + article_list = article_list[:3] # set context ressources context["current_slug_cat"] = category_slug - context["last_3_ressources"] = article_list[:3] + context["last_3_ressources"] = article_list # for specific users if user.kind == User.KIND_SIAE: From 0ad29c588548fc3d21be7199703ec47829dfd5da Mon Sep 17 00:00:00 2001 From: "madjid.asa" Date: Tue, 16 Jul 2024 17:16:12 +0200 Subject: [PATCH 4/6] clean migration --- lemarche/cms/migrations/0012_faqpage.py | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/lemarche/cms/migrations/0012_faqpage.py b/lemarche/cms/migrations/0012_faqpage.py index 572cfc276..60be48d48 100644 --- a/lemarche/cms/migrations/0012_faqpage.py +++ b/lemarche/cms/migrations/0012_faqpage.py @@ -1,6 +1,7 @@ -# Generated by Django 4.2.13 on 2024-07-15 16:10 +# Generated by Django 4.2.13 on 2024-07-16 11:35 import django.db.models.deletion +import modelcluster.fields import wagtail.blocks import wagtail.fields from django.db import migrations, models @@ -8,7 +9,6 @@ class Migration(migrations.Migration): dependencies = [ - ("wagtailcore", "0093_uploadedfile"), ("cms", "0011_infocard"), ] @@ -27,8 +27,9 @@ class Migration(migrations.Migration): to="wagtailcore.page", ), ), + ("intro", models.TextField(blank=True, null=True, verbose_name="Introduction")), ( - "body", + "faqs", wagtail.fields.StreamField( [ ( @@ -68,7 +69,17 @@ class Migration(migrations.Migration): ) ], 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", ), ), ], From c9f34c628ac3d0bbc4b36822fa4632094527431d Mon Sep 17 00:00:00 2001 From: "madjid.asa" Date: Tue, 16 Jul 2024 19:50:41 +0200 Subject: [PATCH 5/6] clean comments --- lemarche/cms/blocks.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/lemarche/cms/blocks.py b/lemarche/cms/blocks.py index 5b823a944..11a8b28c0 100644 --- a/lemarche/cms/blocks.py +++ b/lemarche/cms/blocks.py @@ -237,7 +237,6 @@ class Meta: class FAQBlock(blocks.StructBlock): - # id = blocks.CharBlock(required=True, default=uuid4(), help_text="L'identifiant unique pour cette question.") 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.") @@ -253,7 +252,6 @@ class Meta: class FAQGroupBlock(blocks.StructBlock): - # id = blocks.CharBlock(required=True, default=uuid4(), help_text="L'identifiant unique pour cette question.") group_title = blocks.CharBlock(required=True, help_text="Le titre du groupe de questions-réponses.") faqs = blocks.ListBlock(FAQBlock()) From b0593c5c6c46733c6f99a0ef8c54621139cfdf6e Mon Sep 17 00:00:00 2001 From: "madjid.asa" Date: Tue, 16 Jul 2024 20:22:17 +0200 Subject: [PATCH 6/6] fix migration --- lemarche/cms/migrations/0012_faqpage.py | 3 ++- ...r_articlepage_intro_alter_faqpage_intro.py | 22 +++++++++++++++++++ lemarche/cms/models.py | 3 +-- 3 files changed, 25 insertions(+), 3 deletions(-) create mode 100644 lemarche/cms/migrations/0013_alter_articlepage_intro_alter_faqpage_intro.py diff --git a/lemarche/cms/migrations/0012_faqpage.py b/lemarche/cms/migrations/0012_faqpage.py index 60be48d48..d63f9ee8d 100644 --- a/lemarche/cms/migrations/0012_faqpage.py +++ b/lemarche/cms/migrations/0012_faqpage.py @@ -1,4 +1,4 @@ -# Generated by Django 4.2.13 on 2024-07-16 11:35 +# Generated by Django 4.2.13 on 2024-07-16 17:55 import django.db.models.deletion import modelcluster.fields @@ -69,6 +69,7 @@ class Migration(migrations.Migration): ) ], blank=True, + use_json_field=True, ), ), ("categories", modelcluster.fields.ParentalManyToManyField(blank=True, to="cms.articlecategory")), 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 4e1aca314..b86b8c504 100644 --- a/lemarche/cms/models.py +++ b/lemarche/cms/models.py @@ -16,7 +16,7 @@ class ArticleBase(Page): - intro = models.TextField(verbose_name="Introduction", null=True, blank=True) + 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="+" ) @@ -250,7 +250,6 @@ class FAQPage(ArticleBase): use_json_field=True, ) content_panels = ArticleBase.content_panels + [ - MultiFieldPanel([FieldPanel("categories", widget=forms.CheckboxSelectMultiple)], heading="Categories"), FieldPanel("faqs"), ]