diff --git a/Dockerfile b/Dockerfile index f9c29c01..0c75e9a3 100644 --- a/Dockerfile +++ b/Dockerfile @@ -33,7 +33,7 @@ RUN poetry install COPY --chown=app:app . . -RUN poetry run python manage.py collectstatic --no-input +RUN poetry run python manage.py collectstatic --no-input --ignore=*.sass USER app diff --git a/Makefile b/Makefile index 1c87c0af..03cbd2b7 100644 --- a/Makefile +++ b/Makefile @@ -18,6 +18,15 @@ web-prompt: test-unit: $(EXEC_CMD) poetry run python manage.py test --settings config.settings_test +.PHONY: collectstatic +collectstatic: + $(EXEC_CMD) poetry run python manage.py collectstatic --noinput --ignore=*.sass + +.PHONY: sass +sass: + $(EXEC_CMD) poetry run python manage.py compilescss + make collectstatic + .PHONY: quality quality: $(EXEC_CMD) poetry run black --check --exclude=venv . @@ -35,7 +44,7 @@ init: $(EXEC_CMD) poetry install $(EXEC_CMD) poetry run pre-commit install $(EXEC_CMD) poetry run python manage.py migrate - $(EXEC_CMD) poetry run python manage.py collectstatic --noinput + make collectstatic $(EXEC_CMD) poetry run python manage.py create_sample_pages .PHONY: runserver diff --git a/config/settings.py b/config/settings.py index b6f7bbde..1a6f98b5 100644 --- a/config/settings.py +++ b/config/settings.py @@ -158,9 +158,9 @@ # https://whitenoise.evans.io/en/latest/ STATICFILES_FINDERS = [ + "django.contrib.staticfiles.finders.FileSystemFinder", "django.contrib.staticfiles.finders.AppDirectoriesFinder", "sass_processor.finders.CssFinder", - "django.contrib.staticfiles.finders.FileSystemFinder", ] # S3 uploads & MEDIA CONFIGURATION @@ -179,7 +179,8 @@ MEDIA_URL = "medias/" # Django Sass -SASS_PROCESSOR_ROOT = os.path.join(BASE_DIR, "static") +SASS_PROCESSOR_ROOT = os.path.join(BASE_DIR, "static/css") +SASS_PROCESSOR_AUTO_INCLUDE = False STATIC_URL = "static/" STATIC_ROOT = "staticfiles" diff --git a/content_manager/blocks.py b/content_manager/blocks.py index 2b49ac42..5bc463d3 100644 --- a/content_manager/blocks.py +++ b/content_manager/blocks.py @@ -60,7 +60,7 @@ class AlertBlock(blocks.StructBlock): class BadgeBlock(blocks.StructBlock): text = blocks.CharBlock(label="Texte du badge", required=False) color = blocks.ChoiceBlock(label="Couleur de badge", choices=badge_level_choices, required=False) - hide_icon = blocks.BooleanBlock(label="Masquer l'icon du badge", required=False) + hide_icon = blocks.BooleanBlock(label="Masquer l’icône du badge", required=False) class BadgesListBlock(blocks.StreamBlock): @@ -87,24 +87,26 @@ class CardBlock(blocks.StructBlock): label="ou Document", help_text=( "Sélectionnez un document pour rendre la carte cliquable vers " - "celui ci (si le champ `Lien` n'est pas renseigné)." + "celui ci (si le champ « Lien » n’est pas renseigné)." ), required=False, ) class HeroBlock(blocks.StructBlock): - bg_image = ImageChooserBlock(label="Image d'arrière plan") + bg_image = ImageChooserBlock(label="Image d’arrière plan") bg_color = blocks.RegexBlock( - label="Couleur d'arrière plan au format hexa (Ex: #f5f5fe)", + label="Couleur d’arrière plan au format hexa (Ex: #f5f5fe)", regex=r"^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$", - error_messages={"invalid": "La couleur n'est pas correcte, le format doit être #fff ou #f5f5fe"}, + error_messages={"invalid": "La couleur n’est pas correcte, le format doit être #fff ou #f5f5fe"}, required=False, ) title = blocks.CharBlock(label="Titre") text = blocks.CharBlock(label="Texte", required=False) cta_label = blocks.CharBlock(label="Texte du bouton", required=False) cta_link = blocks.URLBlock(label="Lien du bouton", required=False) + large = blocks.BooleanBlock(label="Large", required=False) + darken = blocks.BooleanBlock(label="Assombrir", required=False) class IframeBlock(blocks.StructBlock): @@ -122,7 +124,7 @@ class IframeBlock(blocks.StructBlock): class ImageAndTextBlock(blocks.StructBlock): image = ImageChooserBlock(label="Illustration (à gauche)") image_ratio = blocks.ChoiceBlock( - label="Largeur de l'image", + label="Largeur de l’image", choices=[ ("3", "3/12"), ("5", "5/12"), @@ -141,7 +143,7 @@ class ImageAndTextBlock(blocks.StructBlock): class ImageBlock(blocks.StructBlock): title = blocks.CharBlock(label="Titre", required=False) image = ImageChooserBlock(label="Illustration") - alt = blocks.CharBlock(label="Texte alternatif (description textuelle de l'image)", required=False) + alt = blocks.CharBlock(label="Texte alternatif (description textuelle de l’image)", required=False) caption = blocks.CharBlock(label="Légende", required=False) url = blocks.URLBlock(label="Lien", required=False) @@ -149,8 +151,8 @@ class ImageBlock(blocks.StructBlock): class QuoteBlock(blocks.StructBlock): image = ImageChooserBlock(label="Illustration (à gauche)", required=False) quote = blocks.CharBlock(label="Citation") - author_name = blocks.CharBlock(label="Nom de l'auteur") - author_title = blocks.CharBlock(label="Titre de l'auteur") + author_name = blocks.CharBlock(label="Nom de l’auteur") + author_title = blocks.CharBlock(label="Titre de l’auteur") class SeparatorBlock(blocks.StructBlock): @@ -159,7 +161,7 @@ class SeparatorBlock(blocks.StructBlock): class StepBlock(blocks.StructBlock): - title = blocks.CharBlock(label="Titre de l'étape") + title = blocks.CharBlock(label="Titre de l’étape") detail = blocks.TextBlock(label="Détail") @@ -169,7 +171,7 @@ class StepsListBlock(blocks.StreamBlock): class StepperBlock(blocks.StructBlock): title = blocks.CharBlock(label="Titre") - total = blocks.IntegerBlock(label="Nombre d'étape") + total = blocks.IntegerBlock(label="Nombre d’étapes") current = blocks.IntegerBlock(label="Étape en cours") steps = StepsListBlock(label="Les étapes") @@ -177,7 +179,7 @@ class StepperBlock(blocks.StructBlock): class TextAndCTA(blocks.StructBlock): text = blocks.RichTextBlock(label="Texte avec mise en forme", required=False) cta_label = blocks.CharBlock( - label="Titre de l'appel à l'action", + label="Titre de l’appel à l’action", help_text="Le lien apparait comme un bouton sous le bloc de texte", required=False, ) @@ -194,7 +196,7 @@ class VideoBlock(blocks.StructBlock): caption = blocks.CharBlock(label="Légende") url = blocks.URLBlock( label="Lien de la vidéo", - help_text="URL au format 'embed' (Ex. : https://www.youtube.com/embed/gLzXOViPX-0)", + help_text="URL au format « embed » (Ex. : https://www.youtube.com/embed/gLzXOViPX-0)", ) @@ -205,16 +207,16 @@ class MultiColumnsBlock(blocks.StreamBlock): video = VideoBlock(label="Vidéo") card = CardBlock(label="Carte") quote = QuoteBlock(label="Citation") - text_cta = TextAndCTA(label="Texte et appel à l'action") + text_cta = TextAndCTA(label="Texte et appel à l’action") iframe = IframeBlock(label="Cadre intégré") class MultiColumnsWithTitleBlock(blocks.StructBlock): - bg_image = ImageChooserBlock(label="Image d'arrière plan", required=False) + bg_image = ImageChooserBlock(label="Image d’arrière plan", required=False) bg_color = blocks.RegexBlock( - label="Couleur d'arrière plan au format hexa (Ex: #f5f5fe)", + label="Couleur d’arrière plan au format hexa (Ex: #f5f5fe)", regex=r"^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$", - error_messages={"invalid": "La couleur n'est pas correcte, le format doit être #fff ou #f5f5fe"}, + error_messages={"invalid": "La couleur n’est pas correcte, le format doit être #fff ou #f5f5fe"}, required=False, ) title = blocks.CharBlock(label="Titre", required=False) diff --git a/content_manager/migrations/0010_alter_contentpage_body.py b/content_manager/migrations/0010_alter_contentpage_body.py new file mode 100644 index 00000000..bb11ed9a --- /dev/null +++ b/content_manager/migrations/0010_alter_contentpage_body.py @@ -0,0 +1,456 @@ +# Generated by Django 4.2.7 on 2023-12-06 16:48 + +import wagtail.blocks +import wagtail.documents.blocks +import wagtail.fields +import wagtail.images.blocks +from django.db import migrations + + +class Migration(migrations.Migration): + dependencies = [ + ("content_manager", "0009_alter_contentpage_body"), + ] + + operations = [ + migrations.AlterField( + model_name="contentpage", + name="body", + field=wagtail.fields.StreamField( + [ + ( + "hero", + wagtail.blocks.StructBlock( + [ + ("bg_image", wagtail.images.blocks.ImageChooserBlock(label="Image d’arrière plan")), + ( + "bg_color", + wagtail.blocks.RegexBlock( + error_messages={ + "invalid": "La couleur n’est pas correcte, le format doit être #fff ou #f5f5fe" + }, + label="Couleur d’arrière plan au format hexa (Ex: #f5f5fe)", + regex="^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$", + required=False, + ), + ), + ("title", wagtail.blocks.CharBlock(label="Titre")), + ("text", wagtail.blocks.CharBlock(label="Texte", required=False)), + ("cta_label", wagtail.blocks.CharBlock(label="Texte du bouton", required=False)), + ("cta_link", wagtail.blocks.URLBlock(label="Lien du bouton", required=False)), + ("large", wagtail.blocks.BooleanBlock(label="Large", required=False)), + ("darken", wagtail.blocks.BooleanBlock(label="Assombrir", required=False)), + ], + label="Section promotionnelle", + ), + ), + ( + "title", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock(label="Titre")), + ("large", wagtail.blocks.BooleanBlock(label="Large", required=False)), + ], + label="Titre de page", + ), + ), + ("paragraph", wagtail.blocks.RichTextBlock(label="Texte avec mise en forme")), + ("paragraphlarge", wagtail.blocks.RichTextBlock(label="Texte avec mise en forme (large)")), + ( + "image", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock(label="Titre", required=False)), + ("image", wagtail.images.blocks.ImageChooserBlock(label="Illustration")), + ( + "alt", + wagtail.blocks.CharBlock( + label="Texte alternatif (description textuelle de l’image)", required=False + ), + ), + ("caption", wagtail.blocks.CharBlock(label="Légende", required=False)), + ("url", wagtail.blocks.URLBlock(label="Lien", required=False)), + ] + ), + ), + ( + "imageandtext", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock(label="Illustration (à gauche)")), + ( + "image_ratio", + wagtail.blocks.ChoiceBlock( + choices=[("3", "3/12"), ("5", "5/12"), ("6", "6/12")], + label="Largeur de l’image", + ), + ), + ("text", wagtail.blocks.RichTextBlock(label="Texte avec mise en forme (à droite)")), + ( + "link_label", + wagtail.blocks.CharBlock( + help_text="Le lien apparait en bas du bloc de droite, avec une flèche", + label="Titre du lien", + required=False, + ), + ), + ("link_url", wagtail.blocks.URLBlock(label="Lien", required=False)), + ], + label="Bloc image à gauche et texte à droite", + ), + ), + ( + "alert", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock(label="Titre du message", required=False)), + ("description", wagtail.blocks.TextBlock(label="Texte du message", required=False)), + ( + "level", + wagtail.blocks.ChoiceBlock( + choices=[ + ("error", "Erreur"), + ("success", "Succès"), + ("info", "Information"), + ("warning", "Attention"), + ], + label="Type de message", + ), + ), + ( + "heading_tag", + wagtail.blocks.ChoiceBlock( + choices=[ + ("h2", "En-tête 2"), + ("h3", "En-tête 3"), + ("h4", "En-tête 4"), + ("h5", "En-tête 5"), + ("h6", "En-tête 6"), + ("p", "Paragraphe"), + ], + help_text="À adapter à la structure de la page. Par défaut en-tête 3.", + label="Niveau de titre", + ), + ), + ], + label="Message d'alerte", + ), + ), + ( + "callout", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock(label="Titre de la mise en vant", required=False)), + ("text", wagtail.blocks.TextBlock(label="Texte mis en avant", required=False)), + ( + "heading_tag", + wagtail.blocks.ChoiceBlock( + choices=[ + ("h2", "En-tête 2"), + ("h3", "En-tête 3"), + ("h4", "En-tête 4"), + ("h5", "En-tête 5"), + ("h6", "En-tête 6"), + ("p", "Paragraphe"), + ], + help_text="À adapter à la structure de la page. Par défaut en-tête 3.", + label="Niveau de titre", + ), + ), + ], + label="Texte mise en avant", + ), + ), + ( + "quote", + wagtail.blocks.StructBlock( + [ + ( + "image", + wagtail.images.blocks.ImageChooserBlock( + label="Illustration (à gauche)", required=False + ), + ), + ("quote", wagtail.blocks.CharBlock(label="Citation")), + ("author_name", wagtail.blocks.CharBlock(label="Nom de l’auteur")), + ("author_title", wagtail.blocks.CharBlock(label="Titre de l’auteur")), + ], + label="Citation", + ), + ), + ( + "video", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock(label="Titre", required=False)), + ("caption", wagtail.blocks.CharBlock(label="Légende")), + ( + "url", + wagtail.blocks.URLBlock( + help_text="URL au format «\xa0embed\xa0» (Ex. : https://www.youtube.com/embed/gLzXOViPX-0)", + label="Lien de la vidéo", + ), + ), + ], + label="Vidéo", + ), + ), + ( + "multicolumns", + wagtail.blocks.StructBlock( + [ + ( + "bg_image", + wagtail.images.blocks.ImageChooserBlock( + label="Image d’arrière plan", required=False + ), + ), + ( + "bg_color", + wagtail.blocks.RegexBlock( + error_messages={ + "invalid": "La couleur n’est pas correcte, le format doit être #fff ou #f5f5fe" + }, + label="Couleur d’arrière plan au format hexa (Ex: #f5f5fe)", + regex="^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$", + required=False, + ), + ), + ("title", wagtail.blocks.CharBlock(label="Titre", required=False)), + ( + "columns", + wagtail.blocks.StreamBlock( + [ + ("text", wagtail.blocks.RichTextBlock(label="Texte avec mise en forme")), + ( + "image", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock(label="Titre", required=False), + ), + ( + "image", + wagtail.images.blocks.ImageChooserBlock( + label="Illustration" + ), + ), + ( + "alt", + wagtail.blocks.CharBlock( + label="Texte alternatif (description textuelle de l’image)", + required=False, + ), + ), + ( + "caption", + wagtail.blocks.CharBlock(label="Légende", required=False), + ), + ("url", wagtail.blocks.URLBlock(label="Lien", required=False)), + ], + label="Image", + ), + ), + ( + "video", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock(label="Titre", required=False), + ), + ("caption", wagtail.blocks.CharBlock(label="Légende")), + ( + "url", + wagtail.blocks.URLBlock( + help_text="URL au format «\xa0embed\xa0» (Ex. : https://www.youtube.com/embed/gLzXOViPX-0)", + label="Lien de la vidéo", + ), + ), + ], + label="Vidéo", + ), + ), + ( + "card", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock(label="Titre")), + ("description", wagtail.blocks.TextBlock(label="Texte")), + ( + "image", + wagtail.images.blocks.ImageChooserBlock(label="Image"), + ), + ("url", wagtail.blocks.URLBlock(label="Lien", required=False)), + ( + "document", + wagtail.documents.blocks.DocumentChooserBlock( + help_text="Sélectionnez un document pour rendre la carte cliquable vers celui ci (si le champ «\xa0Lien\xa0» n’est pas renseigné).", + label="ou Document", + required=False, + ), + ), + ], + label="Carte", + ), + ), + ( + "quote", + wagtail.blocks.StructBlock( + [ + ( + "image", + wagtail.images.blocks.ImageChooserBlock( + label="Illustration (à gauche)", required=False + ), + ), + ("quote", wagtail.blocks.CharBlock(label="Citation")), + ( + "author_name", + wagtail.blocks.CharBlock(label="Nom de l’auteur"), + ), + ( + "author_title", + wagtail.blocks.CharBlock(label="Titre de l’auteur"), + ), + ], + label="Citation", + ), + ), + ( + "text_cta", + wagtail.blocks.StructBlock( + [ + ( + "text", + wagtail.blocks.RichTextBlock( + label="Texte avec mise en forme", required=False + ), + ), + ( + "cta_label", + wagtail.blocks.CharBlock( + help_text="Le lien apparait comme un bouton sous le bloc de texte", + label="Titre de l’appel à l’action", + required=False, + ), + ), + ( + "cta_url", + wagtail.blocks.CharBlock(label="Lien", required=False), + ), + ], + label="Texte et appel à l’action", + ), + ), + ( + "iframe", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Accessibilité : Le titre doit décrire, de façon claire et concise, le contenu embarqué.", + label="Titre", + ), + ), + ( + "url", + wagtail.blocks.URLBlock( + help_text="Exemple pour Tally : https://tally.so/embed/w2jMRa", + label="Lien du cadre intégré", + ), + ), + ( + "height", + wagtail.blocks.IntegerBlock(label="Hauteur en pixels"), + ), + ], + label="Cadre intégré", + ), + ), + ], + label="Multi-colonnes", + ), + ), + ], + label="Multi-colonnes", + ), + ), + ( + "accordions", + wagtail.blocks.StreamBlock( + [ + ("title", wagtail.blocks.CharBlock(label="Titre")), + ( + "accordion", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock(label="Titre")), + ("content", wagtail.blocks.RichTextBlock(label="Contenu")), + ], + label="Accordéon", + max_num=15, + min_num=1, + ), + ), + ], + label="Accordéons", + ), + ), + ( + "stepper", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock(label="Titre")), + ("total", wagtail.blocks.IntegerBlock(label="Nombre d’étapes")), + ("current", wagtail.blocks.IntegerBlock(label="Étape en cours")), + ( + "steps", + wagtail.blocks.StreamBlock( + [ + ( + "step", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock(label="Titre de l’étape")), + ("detail", wagtail.blocks.TextBlock(label="Détail")), + ], + label="Étape", + ), + ) + ], + label="Les étapes", + ), + ), + ], + label="Étapes", + ), + ), + ( + "separator", + wagtail.blocks.StructBlock( + [ + ( + "top_margin", + wagtail.blocks.IntegerBlock( + default=3, label="Espacement au dessus", max_value=15, min_value=0 + ), + ), + ( + "bottom_margin", + wagtail.blocks.IntegerBlock( + default=3, label="Espacement en dessous", max_value=15, min_value=0 + ), + ), + ], + label="Séparateur", + ), + ), + ], + blank=True, + use_json_field=True, + ), + ), + ] diff --git a/content_manager/templates/content_manager/blocks/hero.html b/content_manager/templates/content_manager/blocks/hero.html index fe26200b..8d79cbca 100644 --- a/content_manager/templates/content_manager/blocks/hero.html +++ b/content_manager/templates/content_manager/blocks/hero.html @@ -1,14 +1,16 @@ {% load static wagtailimages_tags %} {% image block.value.bg_image original as bg_img %} -
{{ block.value.text }}
{% endif %} {% if block.value.cta_link and block.value.cta_label %} - {{ block.value.cta_label }} {% endif %}