diff --git a/network-api/networkapi/utility/faker/streamfield_provider.py b/network-api/networkapi/utility/faker/streamfield_provider.py index 65b8c7ce108..bbc5f315853 100644 --- a/network-api/networkapi/utility/faker/streamfield_provider.py +++ b/network-api/networkapi/utility/faker/streamfield_provider.py @@ -742,6 +742,17 @@ def generate_bg_cta_link_field(): return generate_field("link", link_value) +def generate_homepage_hero_intro_link(): + link_value = { + "link_to": "external_url", + "external_url": fake.url(schemes=["https"]), + "label": " ".join(fake.words(nb=3)), + "new_window": True, + } + + return generate_field("link", link_value) + + class StreamfieldProvider(BaseProvider): """ A custom Faker Provider for relative image urls, for use with factory_boy @@ -804,6 +815,7 @@ def streamfield(self, fields=None): "mixed_content": generate_mixed_content_field, "app_install_download_button": generate_app_install_download_button_field, "buyersguide_call_to_action_link": generate_bg_cta_link_field, + "homepage_hero_intro_link": generate_homepage_hero_intro_link, } streamfield_data = [] diff --git a/network-api/networkapi/wagtailpages/factory/homepage.py b/network-api/networkapi/wagtailpages/factory/homepage.py index 9db1deece76..9055c31679a 100644 --- a/network-api/networkapi/wagtailpages/factory/homepage.py +++ b/network-api/networkapi/wagtailpages/factory/homepage.py @@ -28,7 +28,7 @@ class Meta: # cause_statement_link_text and cause_statement_link_page are created at a later state hero_intro_heading = Faker("text", max_nb_chars=60) hero_intro_body = Faker("text", max_nb_chars=250) - hero_intro_link_text = Faker("text", max_nb_chars=30) + hero_intro_link = Faker("streamfield", fields=["homepage_hero_intro_link"]) quote_image = SubFactory(ImageFactory) quote_text = Faker("text", max_nb_chars=300) quote_source_name = Faker("text", max_nb_chars=30) @@ -105,8 +105,6 @@ def generate(seed): print('Generating "who we are" Page (PrimaryPage)') wwa_page = PrimaryPageFactory.create(parent=home_page, title="Who we are", show_in_menus=True) - # Set the hero_intro_link_page - home_page.hero_intro_link_page = wwa_page home_page.save() reseed(seed) diff --git a/network-api/networkapi/wagtailpages/migrations/0163_remove_focusarea_page_homepage_hero_intro_body_and_more.py b/network-api/networkapi/wagtailpages/migrations/0163_remove_focusarea_page_homepage_hero_intro_body_and_more.py index 102014dd73d..e17c329fbf3 100644 --- a/network-api/networkapi/wagtailpages/migrations/0163_remove_focusarea_page_homepage_hero_intro_body_and_more.py +++ b/network-api/networkapi/wagtailpages/migrations/0163_remove_focusarea_page_homepage_hero_intro_body_and_more.py @@ -1,13 +1,16 @@ -# Generated by Django 4.2.15 on 2024-09-19 20:09 +# Generated by Django 4.2.15 on 2024-09-20 08:22 -import django.db.models.deletion +import wagtail.blocks +import wagtail.documents.blocks +import wagtail.fields from django.db import migrations, models +import networkapi.wagtailpages.validators + class Migration(migrations.Migration): dependencies = [ - ("wagtailcore", "0089_log_entry_data_json_null_to_object"), ("wagtailpages", "0162_alter_articlepage_body"), ] @@ -19,27 +22,89 @@ class Migration(migrations.Migration): migrations.AddField( model_name="homepage", name="hero_intro_body", - field=models.TextField(blank=True, max_length=300), + field=models.TextField( + blank=True, + default="Mozilla empowers consumers to demand better online privacy, trustworthy AI, and safe online experiences from Big Tech and governments. We work across borders, disciplines, and technologies to uphold principles like privacy, inclusion and decentralization online.", + max_length=300, + ), ), migrations.AddField( model_name="homepage", name="hero_intro_heading", - field=models.CharField(blank=True, max_length=100), - ), - migrations.AddField( - model_name="homepage", - name="hero_intro_link_page", - field=models.ForeignKey( + field=models.CharField( blank=True, - null=True, - on_delete=django.db.models.deletion.SET_NULL, - related_name="hero_intro_link", - to="wagtailcore.page", + default="A healthy internet is one in which privacy, openness, and inclusion are the norms. ", + max_length=100, ), ), migrations.AddField( model_name="homepage", - name="hero_intro_link_text", - field=models.CharField(blank=True, max_length=50), + name="hero_intro_link", + field=wagtail.fields.StreamField( + [ + ( + "link", + wagtail.blocks.StructBlock( + [ + ("label", wagtail.blocks.CharBlock()), + ( + "link_to", + wagtail.blocks.ChoiceBlock( + choices=[ + ("page", "Page"), + ("external_url", "External URL"), + ("relative_url", "Relative URL"), + ("email", "Email"), + ("anchor", "Anchor"), + ("file", "File"), + ("phone", "Phone"), + ], + label="Link to", + ), + ), + ("page", wagtail.blocks.PageChooserBlock(label="Page", required=False)), + ( + "external_url", + wagtail.blocks.URLBlock( + help_text="Enter a full URL including http:// or https://", + label="External URL", + max_length=300, + required=False, + ), + ), + ( + "relative_url", + wagtail.blocks.CharBlock( + help_text='A path relative to this domain. For example, "/foo/bar" or "?foo=bar".', + label="Relative URL", + max_length=300, + required=False, + validators=[networkapi.wagtailpages.validators.RelativeURLValidator()], + ), + ), + ( + "anchor", + wagtail.blocks.CharBlock( + help_text='An id attribute of an element on the current page. For example, "#section-1"', + label="#", + max_length=300, + required=False, + validators=[networkapi.wagtailpages.validators.AnchorLinkValidator()], + ), + ), + ("email", wagtail.blocks.EmailBlock(required=False)), + ("file", wagtail.documents.blocks.DocumentChooserBlock(label="File", required=False)), + ("phone", wagtail.blocks.CharBlock(label="Phone", max_length=30, required=False)), + ( + "new_window", + wagtail.blocks.BooleanBlock(label="Open in new window", required=False), + ), + ] + ), + ) + ], + blank=True, + use_json_field=True, + ), ), ] diff --git a/network-api/networkapi/wagtailpages/pagemodels/base.py b/network-api/networkapi/wagtailpages/pagemodels/base.py index 398bf13f08c..8c6e4ee25d6 100644 --- a/network-api/networkapi/wagtailpages/pagemodels/base.py +++ b/network-api/networkapi/wagtailpages/pagemodels/base.py @@ -9,6 +9,8 @@ from wagtail.search import index from wagtail_localize.fields import SynchronizedField, TranslatableField +from networkapi.wagtailpages.pagemodels.customblocks.link_block import LinkBlock + # TODO: https://github.com/mozilla/foundation.mozilla.org/issues/2362 from ..donation_modal import DonationModals # noqa: F401 from ..utils import CharCountWidget, get_page_tree_information @@ -18,6 +20,9 @@ from .mixin.foundation_metadata import FoundationMetadataPageMixin from .mixin.foundation_navigation import FoundationNavigationPageMixin +hero_intro_heading_default_text = "A healthy internet is one in which privacy, openness, and inclusion are the norms. " +hero_intro_body_default_text = "Mozilla empowers consumers to demand better online privacy, trustworthy AI, and safe online experiences from Big Tech and governments. We work across borders, disciplines, and technologies to uphold principles like privacy, inclusion and decentralization online." + class BasePage(FoundationMetadataPageMixin, FoundationNavigationPageMixin, Page): class Meta: @@ -755,15 +760,13 @@ def get_banner(self): hero_button_url = models.URLField(blank=True) - hero_intro_heading = models.CharField(max_length=100, blank=True) - hero_intro_body = models.TextField(max_length=300, blank=True) - hero_intro_link_text = models.CharField(max_length=50, blank=True) - hero_intro_link_page = models.ForeignKey( - Page, - null=True, + hero_intro_heading = models.CharField(max_length=100, blank=True, default=hero_intro_heading_default_text) + hero_intro_body = models.TextField(max_length=300, blank=True, default=hero_intro_body_default_text) + hero_intro_link = StreamField( + [("link", LinkBlock())], + use_json_field=True, blank=True, - on_delete=models.SET_NULL, - related_name="hero_intro_link", + max_num=1, ) ideas_image = models.ForeignKey( @@ -871,8 +874,7 @@ def get_banner(self): [ FieldPanel("hero_intro_heading"), FieldPanel("hero_intro_body"), - FieldPanel("hero_intro_link_text"), - FieldPanel("hero_intro_link_page"), + FieldPanel("hero_intro_link"), ], heading="Hero Intro Box", classname="collapsible", @@ -947,8 +949,7 @@ def get_banner(self): SynchronizedField("hero_button_url"), TranslatableField("hero_intro_heading"), TranslatableField("hero_intro_body"), - TranslatableField("hero_intro_link_text"), - SynchronizedField("hero_intro_link_page"), + SynchronizedField("hero_intro_link"), SynchronizedField("ideas_image"), TranslatableField("ideas_headline"), TranslatableField("cause_statement"), diff --git a/network-api/networkapi/wagtailpages/templates/wagtailpages/fragments/hero_intro_box.html b/network-api/networkapi/wagtailpages/templates/wagtailpages/fragments/hero_intro_box.html index f6ccc05ba88..ef7d4fab879 100644 --- a/network-api/networkapi/wagtailpages/templates/wagtailpages/fragments/hero_intro_box.html +++ b/network-api/networkapi/wagtailpages/templates/wagtailpages/fragments/hero_intro_box.html @@ -3,7 +3,9 @@

{{ page.hero_intro_heading }}

{{ page.hero_intro_body }}

- {% if page.hero_intro_link_page %} - {{ page.hero_intro_link_text }} + {% if page.hero_intro_link %} + {% with link=page.hero_intro_link.0.value %} + {{ link.label }} + {% endwith %} {% endif %}