diff --git a/dev-requirements.txt b/dev-requirements.txt index 7eff575ebe4..6d4d671fd96 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -20,7 +20,7 @@ coverage[toml]==7.4.1 # via pytest-cov cssbeautifier==1.14.7 # via djlint -django==4.2.11 +django==4.2.14 # via # -c requirements.txt # django-debug-toolbar diff --git a/network-api/networkapi/donate/migrations/0015_update_videoblock_with_linkblock.py b/network-api/networkapi/donate/migrations/0015_update_videoblock_with_linkblock.py new file mode 100644 index 00000000000..7b4aaabfed0 --- /dev/null +++ b/network-api/networkapi/donate/migrations/0015_update_videoblock_with_linkblock.py @@ -0,0 +1,3526 @@ +# Generated by Django 4.2.11 on 2024-07-03 00:30 + +import wagtail.blocks +import wagtail.blocks.static_block +import wagtail.documents.blocks +import wagtail.embeds.blocks +import wagtail.fields +import wagtail.images.blocks +import wagtail.snippets.blocks +from django.db import migrations +from wagtail.blocks.migrations.migrate_operation import MigrateStreamData + +import networkapi.wagtailpages.pagemodels.blog.blog_topic +import networkapi.wagtailpages.pagemodels.profiles +import networkapi.wagtailpages.validators +from networkapi.utility.migration.operations import AlterStreamChildBlockDataOperation + + +def migrate_video_block(source_block): + new_value = { + "url": source_block["value"].get("url"), + "caption": source_block["value"].get("caption"), + "caption_url": [], + "video_width": source_block["value"].get("video_width"), + } + if "captionURL" in source_block["value"] and source_block["value"]["captionURL"]: + new_value["caption_url"] = [ + { + "link_to": "external_url", + "external_url": source_block["value"].get("captionURL"), + "new_window": True, + } + ] + return { + **source_block, + "value": new_value, + } + + +class Migration(migrations.Migration): + + dependencies = [ + ("donate", "0014_update_imagetextblock_with_linkblock"), + ] + + operations = [ + migrations.AlterField( + model_name="donatehelppage", + name="body", + field=wagtail.fields.StreamField( + [ + ( + "paragraph", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + "large", + ], + template="wagtailpages/blocks/rich_text_block.html", + ), + ), + ( + "card_grid", + wagtail.blocks.StructBlock( + [ + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ("body", wagtail.blocks.TextBlock(help_text="Body text of the card.")), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that this card should link out to. (Note: If left blank, link will not render.) ", + required=False, + ), + ), + ( + "link_label", + wagtail.blocks.CharBlock( + help_text="Optional Label for the URL link above. (Note: If left blank, link will not render.) ", + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + ), + ) + ] + ), + ), + ( + "image", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "image_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide images are col-12, Full-Width Images reach both ends of the screen (16:6 images recommended for full width)", + ), + ), + ] + ), + ), + ( + "image_text", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ( + "text", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + ] + ), + ), + ( + "url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this image should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ] + ), + ), + ( + "image_text_mini", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ("text", wagtail.blocks.RichTextBlock(features=["bold", "italic", "link"])), + ] + ), + ), + ( + "image_grid", + wagtail.blocks.StructBlock( + [ + ( + "grid_items", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for this image.", required=False + ), + ), + ( + "caption", + wagtail.blocks.CharBlock( + help_text="Please remember to properly attribute any images we use.", + required=False, + ), + ), + ( + "url", + wagtail.blocks.CharBlock( + help_text="Optional URL that this figure should link out to.", + required=False, + ), + ), + ( + "square_image", + wagtail.blocks.BooleanBlock( + default=True, + help_text="If left checked, the image will be cropped to be square.", + required=False, + ), + ), + ] + ) + ), + ) + ] + ), + ), + ( + "video", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="For YouTube: go to your YouTube video and click “Share,” then “Embed,” and then copy and paste the provided URL only. For example: https://www.youtube.com/embed/3FIVXBawyQw For Vimeo: follow similar steps to grab the embed URL. For example: https://player.vimeo.com/video/9004979", + label="Embed URL", + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "captionURL", + wagtail.blocks.CharBlock( + help_text="Optional URL for caption to link to.", required=False + ), + ), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "video_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide videos are col-12, Full-Width videos reach both ends of the screen.", + ), + ), + ] + ), + ), + ( + "iframe", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.CharBlock( + help_text="Please note that only URLs from allow-listed domains will work." + ), + ), + ( + "height", + wagtail.blocks.IntegerBlock( + help_text="Optional integer pixel value for custom iFrame height", + required=False, + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "iframe_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide iframes are col-12, Full-Width iframes reach both ends of the screen", + ), + ), + ( + "disable_scroll", + wagtail.blocks.BooleanBlock( + default=False, + help_text='Checking this will add "scrolling=no" to the iframe. Use this if your iframe is rendering an unnecessary scroll bar or whitespace below it.', + required=False, + ), + ), + ] + ), + ), + ( + "linkbutton", + 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"', + 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), + ), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ] + ), + ), + ( + "spacer", + wagtail.blocks.StructBlock( + [ + ( + "size", + wagtail.blocks.ChoiceBlock( + choices=[ + ("1", "quarter spacing"), + ("2", "half spacing"), + ("3", "single spacing"), + ("4", "one and a half spacing"), + ("5", "triple spacing"), + ] + ), + ) + ] + ), + ), + ( + "single_quote", + wagtail.blocks.StructBlock( + [ + ("quote", wagtail.blocks.RichTextBlock(features=["bold"])), + ("attribution", wagtail.blocks.CharBlock(required=False)), + ( + "attribution_info", + wagtail.blocks.RichTextBlock(features=["bold", "link", "large"], required=False), + ), + ] + ), + ), + ( + "pulse_listing", + wagtail.blocks.StructBlock( + [ + ( + "search_terms", + wagtail.blocks.CharBlock( + help_text="Test your search at mozillapulse.org/search", + label="Search", + required=False, + ), + ), + ( + "max_number_of_results", + wagtail.blocks.IntegerBlock( + default=6, + help_text="Choose 1-12. If you want visitors to see more, link to a search or tag on Pulse.", + max_value=12, + min_value=0, + required=True, + ), + ), + ( + "only_featured_entries", + wagtail.blocks.BooleanBlock( + default=False, + help_text="Featured items are selected by Pulse moderators.", + label="Display only featured entries", + required=False, + ), + ), + ( + "newest_first", + wagtail.blocks.ChoiceBlock( + choices=[ + ("True", "Show newer entries first"), + ("False", "Show older entries first"), + ], + label="Sort", + ), + ), + ( + "advanced_filter_header", + wagtail.blocks.static_block.StaticBlock( + admin_text="-------- ADVANCED FILTERS: OPTIONS TO DISPLAY FEWER, MORE TARGETED RESULTS. --------", + label=" ", + ), + ), + ( + "issues", + wagtail.blocks.ChoiceBlock( + choices=[ + ("all", "All"), + ("Decentralization", "Decentralization"), + ("Digital Inclusion", "Digital Inclusion"), + ("Online Privacy & Security", "Online Privacy & Security"), + ("Open Innovation", "Open Innovation"), + ("Web Literacy", "Web Literacy"), + ] + ), + ), + ( + "help", + wagtail.blocks.ChoiceBlock( + choices=[ + ("all", "All"), + ("Attend", "Attend"), + ("Create content", "Create content"), + ("Code", "Code"), + ("Design", "Design"), + ("Fundraise", "Fundraise"), + ("Join community", "Join community"), + ("Localize & translate", "Localize & translate"), + ("Mentor", "Mentor"), + ("Plan & organize", "Plan & organize"), + ("Promote", "Promote"), + ("Take action", "Take action"), + ("Test & feedback", "Test & feedback"), + ("Write documentation", "Write documentation"), + ], + label="Type of help needed", + ), + ), + ( + "direct_link", + wagtail.blocks.BooleanBlock( + default=False, + help_text="Checked: user goes to project link. Unchecked: user goes to pulse entry", + label="Direct link", + required=False, + ), + ), + ] + ), + ), + ( + "profile_listing", + wagtail.blocks.StructBlock( + [ + ( + "max_number_of_results", + wagtail.blocks.IntegerBlock( + default=12, + help_text="Pick up to 48 profiles.", + max_value=48, + min_value=1, + required=True, + ), + ), + ( + "advanced_filter_header", + wagtail.blocks.static_block.StaticBlock( + admin_text="-------- ADVANCED FILTERS: OPTIONS TO DISPLAY FEWER, MORE TARGETED RESULTS. --------", + label=" ", + ), + ), + ( + "profile_type", + wagtail.blocks.CharBlock(default="", help_text="Example: Fellow.", required=False), + ), + ( + "program_type", + wagtail.blocks.CharBlock( + default="", help_text="Example: Tech Policy.", required=False + ), + ), + ("year", wagtail.blocks.CharBlock(default="", required=False)), + ] + ), + ), + ( + "profile_by_id", + wagtail.blocks.StructBlock( + [ + ( + "ids", + wagtail.blocks.CharBlock( + help_text="Show profiles for pulse users with specific profile ids (mozillapulse.org/profile/[##]). For multiple profiles, specify a comma separated list (e.g. 85,105,332).", + label="Profile by ID", + ), + ) + ] + ), + ), + ( + "profile_directory", + wagtail.blocks.StructBlock( + [ + ( + "max_number_of_results", + wagtail.blocks.IntegerBlock( + default=12, + help_text="Pick up to 48 profiles.", + max_value=48, + min_value=1, + required=True, + ), + ), + ( + "advanced_filter_header", + wagtail.blocks.static_block.StaticBlock( + admin_text="-------- ADVANCED FILTERS: OPTIONS TO DISPLAY FEWER, MORE TARGETED RESULTS. --------", + label=" ", + ), + ), + ( + "profile_type", + wagtail.blocks.CharBlock(default="", help_text="Example: Fellow.", required=False), + ), + ( + "program_type", + wagtail.blocks.CharBlock( + default="", help_text="Example: Tech Policy.", required=False + ), + ), + ("year", wagtail.blocks.CharBlock(default="", required=False)), + ( + "filter_values", + wagtail.blocks.CharBlock( + default="2019,2018,2017,2016,2015,2014,2013", + help_text="Example: 2019,2018,2017,2016,2015,2014,2013", + required=True, + ), + ), + ] + ), + ), + ( + "recent_blog_entries", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock(required=False)), + ( + "tag_filter", + wagtail.blocks.CharBlock( + help_text="Test this filter at foundation.mozilla.org/blog/tags/", + label="Filter by Tag", + required=False, + ), + ), + ( + "topic_filter", + wagtail.blocks.ChoiceBlock( + choices=networkapi.wagtailpages.pagemodels.blog.blog_topic.BlogPageTopic.get_topics, + help_text="Test this filter at foundation.mozilla.org/blog/topic/", + label="Filter by Topic", + required=False, + ), + ), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ] + ), + ), + ( + "blog_set", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock()), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ( + "blog_pages", + wagtail.blocks.ListBlock( + wagtail.blocks.PageChooserBlock(page_type=["wagtailpages.BlogPage"]) + ), + ), + ] + ), + ), + ( + "airtable", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="Copied from the Airtable embed code. The word 'embed' will be in the url" + ), + ), + ( + "height", + wagtail.blocks.IntegerBlock( + default=533, + help_text="The pixel height on desktop view, usually copied from the Airtable embed code", + ), + ), + ] + ), + ), + ( + "typeform", + wagtail.blocks.StructBlock( + [ + ( + "embed_id", + wagtail.blocks.CharBlock( + help_text="The embed id of your Typeform page (e.g. if the form is on admin.typeform.com/form/e8zScc6t, the id will be: e8zScc6t)", + required=True, + ), + ), + ( + "button_type", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ( + "button_text", + wagtail.blocks.CharBlock( + help_text="This is a text prompt for users to open the typeform content", + required=True, + ), + ), + ] + ), + ), + ( + "datawrapper", + wagtail.embeds.blocks.EmbedBlock( + help_text='Enter the "visualization only" link of the Datawrapper chart. It looks something like this: https://datawrapper.dwcdn.net/KwSKp/1/', + icon="image", + template="wagtailpages/blocks/datawrapper_block.html", + ), + ), + ( + "listing", + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock(help_text="Heading for the block.", required=False), + ), + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ( + "highlighted_metadata", + wagtail.blocks.CharBlock( + help_text="Metadata to highlight on the card.", required=False + ), + ), + ( + "metadata", + wagtail.blocks.CharBlock( + help_text="Generic metadata.", required=False + ), + ), + ( + "body", + wagtail.blocks.RichTextBlock( + features=["bold"], + help_text="Body text of the card.", + required=False, + ), + ), + ( + "link_page", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to.", required=False + ), + ), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that the header should link out to.", + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + min_num=2, + ), + ), + ( + "cards_per_row", + wagtail.blocks.ChoiceBlock( + choices=[(2, "2"), (3, "3")], + help_text="Number of cards per row. Note: this is a max and fewer might be used if is less space is available.", + required=False, + ), + ), + ] + ), + ), + ( + "profiles", + wagtail.blocks.StructBlock( + [ + ( + "profiles", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "profile", + wagtail.snippets.blocks.SnippetChooserBlock( + networkapi.wagtailpages.pagemodels.profiles.Profile + ), + ) + ] + ), + min_num=1, + ), + ) + ] + ), + ), + ( + "article_teaser_block", + wagtail.blocks.StructBlock( + [ + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "article", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to.", + page_type=["wagtailpages.ArticlePage"], + required=False, + ), + ) + ] + ), + help_text="Please use a minimum of 3 cards.", + min_num=3, + ), + ) + ] + ), + ), + ( + "group_listing_block", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the group of cards.", required=False + ), + ), + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ( + "meta_data", + wagtail.blocks.CharBlock( + help_text="Optional meta data information for the card.", + required=False, + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ( + "body", + wagtail.blocks.RichTextBlock( + features=["bold", "link"], help_text="Body text of the card." + ), + ), + ( + "url", + wagtail.blocks.CharBlock( + help_text="The URL this card should link to.", required=False + ), + ), + ] + ) + ), + ), + ] + ), + ), + ( + "image_feature", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock(help_text="Image description (for screen readers)."), + ), + ("metadata", wagtail.blocks.CharBlock(required=False)), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ( + "title_link", + wagtail.blocks.PageChooserBlock( + help_text="Page that the title should link out to.", required=False + ), + ), + ("body", wagtail.blocks.CharBlock(required=False)), + ] + ), + ), + ( + "image_teaser_block", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ("text", wagtail.blocks.RichTextBlock(features=["bold"])), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ("url_label", wagtail.blocks.CharBlock(required=False)), + ("url", wagtail.blocks.CharBlock(required=False)), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ] + ), + ), + ( + "text_only_teaser", + wagtail.blocks.StructBlock( + [ + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock(help_text="Heading for the card."), + ), + ( + "link_page", + wagtail.blocks.PageChooserBlock( + help_text="Page that the header should link out to.", + required=False, + ), + ), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that the header should link out to.", + required=False, + ), + ), + ("meta_data", wagtail.blocks.CharBlock(max_length=500)), + ( + "body", + wagtail.blocks.TextBlock( + help_text="Body text of the card.", + max_length=200, + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 3 cards.", + min_num=3, + ), + ) + ] + ), + ), + ( + "block_with_aside", + wagtail.blocks.StructBlock( + [ + ( + "content", + wagtail.blocks.StreamBlock( + [ + ( + "listing", + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock( + help_text="Heading for the block.", required=False + ), + ), + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "image", + wagtail.images.blocks.ImageChooserBlock(), + ), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", + required=False, + ), + ), + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the card." + ), + ), + ( + "highlighted_metadata", + wagtail.blocks.CharBlock( + help_text="Metadata to highlight on the card.", + required=False, + ), + ), + ( + "metadata", + wagtail.blocks.CharBlock( + help_text="Generic metadata.", + required=False, + ), + ), + ( + "body", + wagtail.blocks.RichTextBlock( + features=["bold"], + help_text="Body text of the card.", + required=False, + ), + ), + ( + "link_page", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to.", + required=False, + ), + ), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that the header should link out to.", + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + min_num=2, + ), + ), + ( + "cards_per_row", + wagtail.blocks.ChoiceBlock( + choices=[(2, "2"), (3, "3")], + help_text="Number of cards per row. Note: this is a max and fewer might be used if is less space is available.", + required=False, + ), + ), + ] + ), + ), + ( + "paragraph", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + ] + ), + ), + ], + help_text="The wider block that appears on the left on desktop", + icon="doc-full", + max_num=1, + ), + ), + ( + "aside", + wagtail.blocks.StreamBlock( + [ + ( + "aside_content", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the card.", required=False + ), + ), + ( + "body", + wagtail.blocks.TextBlock( + help_text="Body text of the card.", required=False + ), + ), + ] + ), + ), + ( + "linkbutton", + 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"', + 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 + ), + ), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ] + ), + ), + ( + "spacer", + wagtail.blocks.StructBlock( + [ + ( + "size", + wagtail.blocks.ChoiceBlock( + choices=[ + ("1", "quarter spacing"), + ("2", "half spacing"), + ("3", "single spacing"), + ("4", "one and a half spacing"), + ("5", "triple spacing"), + ] + ), + ) + ] + ), + ), + ], + help_text="Elements here will appear in the column on the right side of the page on desktop. This can be left blank if you would just like a 2/3 column on the left", + icon="doc-full", + required=False, + ), + ), + ] + ), + ), + ( + "accordion", + wagtail.blocks.StructBlock( + [ + ( + "accordion_items", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the Accordion Item" + ), + ), + ( + "content", + wagtail.blocks.StreamBlock( + [ + ( + "rich_text", + wagtail.blocks.RichTextBlock( + blank=True, + features=[ + "bold", + "italic", + "link", + "ul", + "ol", + "document-link", + ], + ), + ), + ( + "datawrapper", + wagtail.embeds.blocks.EmbedBlock( + help_text='Enter the "visualization only" link of the Datawrapper chart. It looks something like this: https://datawrapper.dwcdn.net/KwSKp/1/', + icon="image", + template="wagtailpages/blocks/datawrapper_block.html", + ), + ), + ( + "image", + wagtail.blocks.StructBlock( + [ + ( + "image", + wagtail.images.blocks.ImageChooserBlock(), + ), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", + required=True, + ), + ), + ] + ), + ), + ( + "video", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="For YouTube: go to your YouTube video and click “Share,” then “Embed,” and then copy and paste the provided URL only. For example: https://www.youtube.com/embed/3FIVXBawyQw For Vimeo: follow similar steps to grab the embed URL. For example: https://player.vimeo.com/video/9004979", + label="Embed URL", + ), + ), + ( + "caption", + wagtail.blocks.CharBlock(required=False), + ), + ( + "captionURL", + wagtail.blocks.CharBlock( + help_text="Optional URL for caption to link to.", + required=False, + ), + ), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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, + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "video_width", + wagtail.blocks.ChoiceBlock( + choices=[ + ("normal", "Normal"), + ("wide", "Wide"), + ("full_width", "Full Width"), + ], + help_text="Wide videos are col-12, Full-Width videos reach both ends of the screen.", + ), + ), + ] + ), + ), + ] + ), + ), + ] + ) + ), + ) + ] + ), + ), + ], + blank=True, + use_json_field=True, + ), + ), + MigrateStreamData( + app_name="donate", + model_name="donatehelppage", + field_name="body", + operations_and_block_paths=[ + (AlterStreamChildBlockDataOperation(block="video", operation=migrate_video_block), ""), + ], + ), + migrations.AlterField( + model_name="donatehelppage", + name="body", + field=wagtail.fields.StreamField( + [ + ( + "paragraph", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + "large", + ], + template="wagtailpages/blocks/rich_text_block.html", + ), + ), + ( + "card_grid", + wagtail.blocks.StructBlock( + [ + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ("body", wagtail.blocks.TextBlock(help_text="Body text of the card.")), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that this card should link out to. (Note: If left blank, link will not render.) ", + required=False, + ), + ), + ( + "link_label", + wagtail.blocks.CharBlock( + help_text="Optional Label for the URL link above. (Note: If left blank, link will not render.) ", + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + ), + ) + ] + ), + ), + ( + "image", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "image_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide images are col-12, Full-Width Images reach both ends of the screen (16:6 images recommended for full width)", + ), + ), + ] + ), + ), + ( + "image_text", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ( + "text", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + ] + ), + ), + ( + "url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this image should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ] + ), + ), + ( + "image_text_mini", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ("text", wagtail.blocks.RichTextBlock(features=["bold", "italic", "link"])), + ] + ), + ), + ( + "image_grid", + wagtail.blocks.StructBlock( + [ + ( + "grid_items", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for this image.", required=False + ), + ), + ( + "caption", + wagtail.blocks.CharBlock( + help_text="Please remember to properly attribute any images we use.", + required=False, + ), + ), + ( + "url", + wagtail.blocks.CharBlock( + help_text="Optional URL that this figure should link out to.", + required=False, + ), + ), + ( + "square_image", + wagtail.blocks.BooleanBlock( + default=True, + help_text="If left checked, the image will be cropped to be square.", + required=False, + ), + ), + ] + ) + ), + ) + ] + ), + ), + ( + "video", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="For YouTube: go to your YouTube video and click “Share,” then “Embed,” and then copy and paste the provided URL only. For example: https://www.youtube.com/embed/3FIVXBawyQw For Vimeo: follow similar steps to grab the embed URL. For example: https://player.vimeo.com/video/9004979", + label="Embed URL", + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "video_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide videos are col-12, Full-Width videos reach both ends of the screen.", + ), + ), + ] + ), + ), + ( + "iframe", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.CharBlock( + help_text="Please note that only URLs from allow-listed domains will work." + ), + ), + ( + "height", + wagtail.blocks.IntegerBlock( + help_text="Optional integer pixel value for custom iFrame height", + required=False, + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "iframe_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide iframes are col-12, Full-Width iframes reach both ends of the screen", + ), + ), + ( + "disable_scroll", + wagtail.blocks.BooleanBlock( + default=False, + help_text='Checking this will add "scrolling=no" to the iframe. Use this if your iframe is rendering an unnecessary scroll bar or whitespace below it.', + required=False, + ), + ), + ] + ), + ), + ( + "linkbutton", + 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"', + 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), + ), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ] + ), + ), + ( + "spacer", + wagtail.blocks.StructBlock( + [ + ( + "size", + wagtail.blocks.ChoiceBlock( + choices=[ + ("1", "quarter spacing"), + ("2", "half spacing"), + ("3", "single spacing"), + ("4", "one and a half spacing"), + ("5", "triple spacing"), + ] + ), + ) + ] + ), + ), + ( + "single_quote", + wagtail.blocks.StructBlock( + [ + ("quote", wagtail.blocks.RichTextBlock(features=["bold"])), + ("attribution", wagtail.blocks.CharBlock(required=False)), + ( + "attribution_info", + wagtail.blocks.RichTextBlock(features=["bold", "link", "large"], required=False), + ), + ] + ), + ), + ( + "pulse_listing", + wagtail.blocks.StructBlock( + [ + ( + "search_terms", + wagtail.blocks.CharBlock( + help_text="Test your search at mozillapulse.org/search", + label="Search", + required=False, + ), + ), + ( + "max_number_of_results", + wagtail.blocks.IntegerBlock( + default=6, + help_text="Choose 1-12. If you want visitors to see more, link to a search or tag on Pulse.", + max_value=12, + min_value=0, + required=True, + ), + ), + ( + "only_featured_entries", + wagtail.blocks.BooleanBlock( + default=False, + help_text="Featured items are selected by Pulse moderators.", + label="Display only featured entries", + required=False, + ), + ), + ( + "newest_first", + wagtail.blocks.ChoiceBlock( + choices=[ + ("True", "Show newer entries first"), + ("False", "Show older entries first"), + ], + label="Sort", + ), + ), + ( + "advanced_filter_header", + wagtail.blocks.static_block.StaticBlock( + admin_text="-------- ADVANCED FILTERS: OPTIONS TO DISPLAY FEWER, MORE TARGETED RESULTS. --------", + label=" ", + ), + ), + ( + "issues", + wagtail.blocks.ChoiceBlock( + choices=[ + ("all", "All"), + ("Decentralization", "Decentralization"), + ("Digital Inclusion", "Digital Inclusion"), + ("Online Privacy & Security", "Online Privacy & Security"), + ("Open Innovation", "Open Innovation"), + ("Web Literacy", "Web Literacy"), + ] + ), + ), + ( + "help", + wagtail.blocks.ChoiceBlock( + choices=[ + ("all", "All"), + ("Attend", "Attend"), + ("Create content", "Create content"), + ("Code", "Code"), + ("Design", "Design"), + ("Fundraise", "Fundraise"), + ("Join community", "Join community"), + ("Localize & translate", "Localize & translate"), + ("Mentor", "Mentor"), + ("Plan & organize", "Plan & organize"), + ("Promote", "Promote"), + ("Take action", "Take action"), + ("Test & feedback", "Test & feedback"), + ("Write documentation", "Write documentation"), + ], + label="Type of help needed", + ), + ), + ( + "direct_link", + wagtail.blocks.BooleanBlock( + default=False, + help_text="Checked: user goes to project link. Unchecked: user goes to pulse entry", + label="Direct link", + required=False, + ), + ), + ] + ), + ), + ( + "profile_listing", + wagtail.blocks.StructBlock( + [ + ( + "max_number_of_results", + wagtail.blocks.IntegerBlock( + default=12, + help_text="Pick up to 48 profiles.", + max_value=48, + min_value=1, + required=True, + ), + ), + ( + "advanced_filter_header", + wagtail.blocks.static_block.StaticBlock( + admin_text="-------- ADVANCED FILTERS: OPTIONS TO DISPLAY FEWER, MORE TARGETED RESULTS. --------", + label=" ", + ), + ), + ( + "profile_type", + wagtail.blocks.CharBlock(default="", help_text="Example: Fellow.", required=False), + ), + ( + "program_type", + wagtail.blocks.CharBlock( + default="", help_text="Example: Tech Policy.", required=False + ), + ), + ("year", wagtail.blocks.CharBlock(default="", required=False)), + ] + ), + ), + ( + "profile_by_id", + wagtail.blocks.StructBlock( + [ + ( + "ids", + wagtail.blocks.CharBlock( + help_text="Show profiles for pulse users with specific profile ids (mozillapulse.org/profile/[##]). For multiple profiles, specify a comma separated list (e.g. 85,105,332).", + label="Profile by ID", + ), + ) + ] + ), + ), + ( + "profile_directory", + wagtail.blocks.StructBlock( + [ + ( + "max_number_of_results", + wagtail.blocks.IntegerBlock( + default=12, + help_text="Pick up to 48 profiles.", + max_value=48, + min_value=1, + required=True, + ), + ), + ( + "advanced_filter_header", + wagtail.blocks.static_block.StaticBlock( + admin_text="-------- ADVANCED FILTERS: OPTIONS TO DISPLAY FEWER, MORE TARGETED RESULTS. --------", + label=" ", + ), + ), + ( + "profile_type", + wagtail.blocks.CharBlock(default="", help_text="Example: Fellow.", required=False), + ), + ( + "program_type", + wagtail.blocks.CharBlock( + default="", help_text="Example: Tech Policy.", required=False + ), + ), + ("year", wagtail.blocks.CharBlock(default="", required=False)), + ( + "filter_values", + wagtail.blocks.CharBlock( + default="2019,2018,2017,2016,2015,2014,2013", + help_text="Example: 2019,2018,2017,2016,2015,2014,2013", + required=True, + ), + ), + ] + ), + ), + ( + "recent_blog_entries", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock(required=False)), + ( + "tag_filter", + wagtail.blocks.CharBlock( + help_text="Test this filter at foundation.mozilla.org/blog/tags/", + label="Filter by Tag", + required=False, + ), + ), + ( + "topic_filter", + wagtail.blocks.ChoiceBlock( + choices=networkapi.wagtailpages.pagemodels.blog.blog_topic.BlogPageTopic.get_topics, + help_text="Test this filter at foundation.mozilla.org/blog/topic/", + label="Filter by Topic", + required=False, + ), + ), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ] + ), + ), + ( + "blog_set", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock()), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ( + "blog_pages", + wagtail.blocks.ListBlock( + wagtail.blocks.PageChooserBlock(page_type=["wagtailpages.BlogPage"]) + ), + ), + ] + ), + ), + ( + "airtable", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="Copied from the Airtable embed code. The word 'embed' will be in the url" + ), + ), + ( + "height", + wagtail.blocks.IntegerBlock( + default=533, + help_text="The pixel height on desktop view, usually copied from the Airtable embed code", + ), + ), + ] + ), + ), + ( + "typeform", + wagtail.blocks.StructBlock( + [ + ( + "embed_id", + wagtail.blocks.CharBlock( + help_text="The embed id of your Typeform page (e.g. if the form is on admin.typeform.com/form/e8zScc6t, the id will be: e8zScc6t)", + required=True, + ), + ), + ( + "button_type", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ( + "button_text", + wagtail.blocks.CharBlock( + help_text="This is a text prompt for users to open the typeform content", + required=True, + ), + ), + ] + ), + ), + ( + "datawrapper", + wagtail.embeds.blocks.EmbedBlock( + help_text='Enter the "visualization only" link of the Datawrapper chart. It looks something like this: https://datawrapper.dwcdn.net/KwSKp/1/', + icon="image", + template="wagtailpages/blocks/datawrapper_block.html", + ), + ), + ( + "listing", + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock(help_text="Heading for the block.", required=False), + ), + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ( + "highlighted_metadata", + wagtail.blocks.CharBlock( + help_text="Metadata to highlight on the card.", required=False + ), + ), + ( + "metadata", + wagtail.blocks.CharBlock( + help_text="Generic metadata.", required=False + ), + ), + ( + "body", + wagtail.blocks.RichTextBlock( + features=["bold"], + help_text="Body text of the card.", + required=False, + ), + ), + ( + "link_page", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to.", required=False + ), + ), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that the header should link out to.", + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + min_num=2, + ), + ), + ( + "cards_per_row", + wagtail.blocks.ChoiceBlock( + choices=[(2, "2"), (3, "3")], + help_text="Number of cards per row. Note: this is a max and fewer might be used if is less space is available.", + required=False, + ), + ), + ] + ), + ), + ( + "profiles", + wagtail.blocks.StructBlock( + [ + ( + "profiles", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "profile", + wagtail.snippets.blocks.SnippetChooserBlock( + networkapi.wagtailpages.pagemodels.profiles.Profile + ), + ) + ] + ), + min_num=1, + ), + ) + ] + ), + ), + ( + "article_teaser_block", + wagtail.blocks.StructBlock( + [ + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "article", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to.", + page_type=["wagtailpages.ArticlePage"], + required=False, + ), + ) + ] + ), + help_text="Please use a minimum of 3 cards.", + min_num=3, + ), + ) + ] + ), + ), + ( + "group_listing_block", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the group of cards.", required=False + ), + ), + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ( + "meta_data", + wagtail.blocks.CharBlock( + help_text="Optional meta data information for the card.", + required=False, + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ( + "body", + wagtail.blocks.RichTextBlock( + features=["bold", "link"], help_text="Body text of the card." + ), + ), + ( + "url", + wagtail.blocks.CharBlock( + help_text="The URL this card should link to.", required=False + ), + ), + ] + ) + ), + ), + ] + ), + ), + ( + "image_feature", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock(help_text="Image description (for screen readers)."), + ), + ("metadata", wagtail.blocks.CharBlock(required=False)), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ( + "title_link", + wagtail.blocks.PageChooserBlock( + help_text="Page that the title should link out to.", required=False + ), + ), + ("body", wagtail.blocks.CharBlock(required=False)), + ] + ), + ), + ( + "image_teaser_block", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ("text", wagtail.blocks.RichTextBlock(features=["bold"])), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ("url_label", wagtail.blocks.CharBlock(required=False)), + ("url", wagtail.blocks.CharBlock(required=False)), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ] + ), + ), + ( + "text_only_teaser", + wagtail.blocks.StructBlock( + [ + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock(help_text="Heading for the card."), + ), + ( + "link_page", + wagtail.blocks.PageChooserBlock( + help_text="Page that the header should link out to.", + required=False, + ), + ), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that the header should link out to.", + required=False, + ), + ), + ("meta_data", wagtail.blocks.CharBlock(max_length=500)), + ( + "body", + wagtail.blocks.TextBlock( + help_text="Body text of the card.", + max_length=200, + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 3 cards.", + min_num=3, + ), + ) + ] + ), + ), + ( + "block_with_aside", + wagtail.blocks.StructBlock( + [ + ( + "content", + wagtail.blocks.StreamBlock( + [ + ( + "listing", + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock( + help_text="Heading for the block.", required=False + ), + ), + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "image", + wagtail.images.blocks.ImageChooserBlock(), + ), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", + required=False, + ), + ), + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the card." + ), + ), + ( + "highlighted_metadata", + wagtail.blocks.CharBlock( + help_text="Metadata to highlight on the card.", + required=False, + ), + ), + ( + "metadata", + wagtail.blocks.CharBlock( + help_text="Generic metadata.", + required=False, + ), + ), + ( + "body", + wagtail.blocks.RichTextBlock( + features=["bold"], + help_text="Body text of the card.", + required=False, + ), + ), + ( + "link_page", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to.", + required=False, + ), + ), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that the header should link out to.", + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + min_num=2, + ), + ), + ( + "cards_per_row", + wagtail.blocks.ChoiceBlock( + choices=[(2, "2"), (3, "3")], + help_text="Number of cards per row. Note: this is a max and fewer might be used if is less space is available.", + required=False, + ), + ), + ] + ), + ), + ( + "paragraph", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + ] + ), + ), + ], + help_text="The wider block that appears on the left on desktop", + icon="doc-full", + max_num=1, + ), + ), + ( + "aside", + wagtail.blocks.StreamBlock( + [ + ( + "aside_content", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the card.", required=False + ), + ), + ( + "body", + wagtail.blocks.TextBlock( + help_text="Body text of the card.", required=False + ), + ), + ] + ), + ), + ( + "linkbutton", + 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"', + 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 + ), + ), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ] + ), + ), + ( + "spacer", + wagtail.blocks.StructBlock( + [ + ( + "size", + wagtail.blocks.ChoiceBlock( + choices=[ + ("1", "quarter spacing"), + ("2", "half spacing"), + ("3", "single spacing"), + ("4", "one and a half spacing"), + ("5", "triple spacing"), + ] + ), + ) + ] + ), + ), + ], + help_text="Elements here will appear in the column on the right side of the page on desktop. This can be left blank if you would just like a 2/3 column on the left", + icon="doc-full", + required=False, + ), + ), + ] + ), + ), + ( + "accordion", + wagtail.blocks.StructBlock( + [ + ( + "accordion_items", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the Accordion Item" + ), + ), + ( + "content", + wagtail.blocks.StreamBlock( + [ + ( + "rich_text", + wagtail.blocks.RichTextBlock( + blank=True, + features=[ + "bold", + "italic", + "link", + "ul", + "ol", + "document-link", + ], + ), + ), + ( + "datawrapper", + wagtail.embeds.blocks.EmbedBlock( + help_text='Enter the "visualization only" link of the Datawrapper chart. It looks something like this: https://datawrapper.dwcdn.net/KwSKp/1/', + icon="image", + template="wagtailpages/blocks/datawrapper_block.html", + ), + ), + ( + "image", + wagtail.blocks.StructBlock( + [ + ( + "image", + wagtail.images.blocks.ImageChooserBlock(), + ), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", + required=True, + ), + ), + ] + ), + ), + ( + "video", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="For YouTube: go to your YouTube video and click “Share,” then “Embed,” and then copy and paste the provided URL only. For example: https://www.youtube.com/embed/3FIVXBawyQw For Vimeo: follow similar steps to grab the embed URL. For example: https://player.vimeo.com/video/9004979", + label="Embed URL", + ), + ), + ( + "caption", + wagtail.blocks.CharBlock(required=False), + ), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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, + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "video_width", + wagtail.blocks.ChoiceBlock( + choices=[ + ("normal", "Normal"), + ("wide", "Wide"), + ("full_width", "Full Width"), + ], + help_text="Wide videos are col-12, Full-Width videos reach both ends of the screen.", + ), + ), + ] + ), + ), + ] + ), + ), + ] + ) + ), + ) + ] + ), + ), + ], + blank=True, + use_json_field=True, + ), + ), + ] diff --git a/network-api/networkapi/donate/migrations/0016_update_imageteaserblock_with_linkblock.py b/network-api/networkapi/donate/migrations/0016_update_imageteaserblock_with_linkblock.py new file mode 100644 index 00000000000..9b38e5bf730 --- /dev/null +++ b/network-api/networkapi/donate/migrations/0016_update_imageteaserblock_with_linkblock.py @@ -0,0 +1,3699 @@ +# Generated by Django 4.2.14 on 2024-07-15 23:38 + +import wagtail.blocks +import wagtail.blocks.static_block +import wagtail.documents.blocks +import wagtail.embeds.blocks +import wagtail.fields +import wagtail.images.blocks +import wagtail.snippets.blocks +from django.db import migrations +from wagtail.blocks.migrations.migrate_operation import MigrateStreamData + +import networkapi.wagtailpages.pagemodels.blog.blog_topic +import networkapi.wagtailpages.pagemodels.profiles +import networkapi.wagtailpages.validators +from networkapi.utility.migration.operations import AlterStreamChildBlockDataOperation + + +def migrate_image_teaser_block(source_block): + new_value = { + "title": source_block["value"].get("title", ""), + "text": source_block["value"].get("text", ""), + "image": source_block["value"].get("image"), + "altText": source_block["value"].get("altText", ""), + "link": [], + "styling": source_block["value"].get("styling", "btn-primary"), + "top_divider": source_block["value"].get("top_divider", False), + "bottom_divider": source_block["value"].get("bottom_divider", False), + } + if "url" in source_block["value"] and source_block["value"]["url"]: + new_value["link_button"] = [ + { + "link_to": "external_url", + "external_url": source_block["value"]["url"], + "label": source_block["value"].get("url_label", ""), + "new_window": True, + "styling": source_block["value"].get("styling", "btn-primary"), + } + ] + return { + **source_block, + "value": new_value, + } + + +class Migration(migrations.Migration): + + dependencies = [ + ("donate", "0015_update_videoblock_with_linkblock"), + ] + + operations = [ + migrations.AlterField( + model_name="donatehelppage", + name="body", + field=wagtail.fields.StreamField( + [ + ( + "paragraph", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + "large", + ], + template="wagtailpages/blocks/rich_text_block.html", + ), + ), + ( + "card_grid", + wagtail.blocks.StructBlock( + [ + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ("body", wagtail.blocks.TextBlock(help_text="Body text of the card.")), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that this card should link out to. (Note: If left blank, link will not render.) ", + required=False, + ), + ), + ( + "link_label", + wagtail.blocks.CharBlock( + help_text="Optional Label for the URL link above. (Note: If left blank, link will not render.) ", + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + ), + ) + ] + ), + ), + ( + "image", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "image_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide images are col-12, Full-Width Images reach both ends of the screen (16:6 images recommended for full width)", + ), + ), + ] + ), + ), + ( + "image_text", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ( + "text", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + ] + ), + ), + ( + "url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this image should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ] + ), + ), + ( + "image_text_mini", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ("text", wagtail.blocks.RichTextBlock(features=["bold", "italic", "link"])), + ] + ), + ), + ( + "image_grid", + wagtail.blocks.StructBlock( + [ + ( + "grid_items", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for this image.", required=False + ), + ), + ( + "caption", + wagtail.blocks.CharBlock( + help_text="Please remember to properly attribute any images we use.", + required=False, + ), + ), + ( + "url", + wagtail.blocks.CharBlock( + help_text="Optional URL that this figure should link out to.", + required=False, + ), + ), + ( + "square_image", + wagtail.blocks.BooleanBlock( + default=True, + help_text="If left checked, the image will be cropped to be square.", + required=False, + ), + ), + ] + ) + ), + ) + ] + ), + ), + ( + "video", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="For YouTube: go to your YouTube video and click “Share,” then “Embed,” and then copy and paste the provided URL only. For example: https://www.youtube.com/embed/3FIVXBawyQw For Vimeo: follow similar steps to grab the embed URL. For example: https://player.vimeo.com/video/9004979", + label="Embed URL", + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "video_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide videos are col-12, Full-Width videos reach both ends of the screen.", + ), + ), + ] + ), + ), + ( + "iframe", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.CharBlock( + help_text="Please note that only URLs from allow-listed domains will work." + ), + ), + ( + "height", + wagtail.blocks.IntegerBlock( + help_text="Optional integer pixel value for custom iFrame height", + required=False, + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "iframe_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide iframes are col-12, Full-Width iframes reach both ends of the screen", + ), + ), + ( + "disable_scroll", + wagtail.blocks.BooleanBlock( + default=False, + help_text='Checking this will add "scrolling=no" to the iframe. Use this if your iframe is rendering an unnecessary scroll bar or whitespace below it.', + required=False, + ), + ), + ] + ), + ), + ( + "linkbutton", + 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"', + 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), + ), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ] + ), + ), + ( + "spacer", + wagtail.blocks.StructBlock( + [ + ( + "size", + wagtail.blocks.ChoiceBlock( + choices=[ + ("1", "quarter spacing"), + ("2", "half spacing"), + ("3", "single spacing"), + ("4", "one and a half spacing"), + ("5", "triple spacing"), + ] + ), + ) + ] + ), + ), + ( + "single_quote", + wagtail.blocks.StructBlock( + [ + ("quote", wagtail.blocks.RichTextBlock(features=["bold"])), + ("attribution", wagtail.blocks.CharBlock(required=False)), + ( + "attribution_info", + wagtail.blocks.RichTextBlock(features=["bold", "link", "large"], required=False), + ), + ] + ), + ), + ( + "pulse_listing", + wagtail.blocks.StructBlock( + [ + ( + "search_terms", + wagtail.blocks.CharBlock( + help_text="Test your search at mozillapulse.org/search", + label="Search", + required=False, + ), + ), + ( + "max_number_of_results", + wagtail.blocks.IntegerBlock( + default=6, + help_text="Choose 1-12. If you want visitors to see more, link to a search or tag on Pulse.", + max_value=12, + min_value=0, + required=True, + ), + ), + ( + "only_featured_entries", + wagtail.blocks.BooleanBlock( + default=False, + help_text="Featured items are selected by Pulse moderators.", + label="Display only featured entries", + required=False, + ), + ), + ( + "newest_first", + wagtail.blocks.ChoiceBlock( + choices=[ + ("True", "Show newer entries first"), + ("False", "Show older entries first"), + ], + label="Sort", + ), + ), + ( + "advanced_filter_header", + wagtail.blocks.static_block.StaticBlock( + admin_text="-------- ADVANCED FILTERS: OPTIONS TO DISPLAY FEWER, MORE TARGETED RESULTS. --------", + label=" ", + ), + ), + ( + "issues", + wagtail.blocks.ChoiceBlock( + choices=[ + ("all", "All"), + ("Decentralization", "Decentralization"), + ("Digital Inclusion", "Digital Inclusion"), + ("Online Privacy & Security", "Online Privacy & Security"), + ("Open Innovation", "Open Innovation"), + ("Web Literacy", "Web Literacy"), + ] + ), + ), + ( + "help", + wagtail.blocks.ChoiceBlock( + choices=[ + ("all", "All"), + ("Attend", "Attend"), + ("Create content", "Create content"), + ("Code", "Code"), + ("Design", "Design"), + ("Fundraise", "Fundraise"), + ("Join community", "Join community"), + ("Localize & translate", "Localize & translate"), + ("Mentor", "Mentor"), + ("Plan & organize", "Plan & organize"), + ("Promote", "Promote"), + ("Take action", "Take action"), + ("Test & feedback", "Test & feedback"), + ("Write documentation", "Write documentation"), + ], + label="Type of help needed", + ), + ), + ( + "direct_link", + wagtail.blocks.BooleanBlock( + default=False, + help_text="Checked: user goes to project link. Unchecked: user goes to pulse entry", + label="Direct link", + required=False, + ), + ), + ] + ), + ), + ( + "profile_listing", + wagtail.blocks.StructBlock( + [ + ( + "max_number_of_results", + wagtail.blocks.IntegerBlock( + default=12, + help_text="Pick up to 48 profiles.", + max_value=48, + min_value=1, + required=True, + ), + ), + ( + "advanced_filter_header", + wagtail.blocks.static_block.StaticBlock( + admin_text="-------- ADVANCED FILTERS: OPTIONS TO DISPLAY FEWER, MORE TARGETED RESULTS. --------", + label=" ", + ), + ), + ( + "profile_type", + wagtail.blocks.CharBlock(default="", help_text="Example: Fellow.", required=False), + ), + ( + "program_type", + wagtail.blocks.CharBlock( + default="", help_text="Example: Tech Policy.", required=False + ), + ), + ("year", wagtail.blocks.CharBlock(default="", required=False)), + ] + ), + ), + ( + "profile_by_id", + wagtail.blocks.StructBlock( + [ + ( + "ids", + wagtail.blocks.CharBlock( + help_text="Show profiles for pulse users with specific profile ids (mozillapulse.org/profile/[##]). For multiple profiles, specify a comma separated list (e.g. 85,105,332).", + label="Profile by ID", + ), + ) + ] + ), + ), + ( + "profile_directory", + wagtail.blocks.StructBlock( + [ + ( + "max_number_of_results", + wagtail.blocks.IntegerBlock( + default=12, + help_text="Pick up to 48 profiles.", + max_value=48, + min_value=1, + required=True, + ), + ), + ( + "advanced_filter_header", + wagtail.blocks.static_block.StaticBlock( + admin_text="-------- ADVANCED FILTERS: OPTIONS TO DISPLAY FEWER, MORE TARGETED RESULTS. --------", + label=" ", + ), + ), + ( + "profile_type", + wagtail.blocks.CharBlock(default="", help_text="Example: Fellow.", required=False), + ), + ( + "program_type", + wagtail.blocks.CharBlock( + default="", help_text="Example: Tech Policy.", required=False + ), + ), + ("year", wagtail.blocks.CharBlock(default="", required=False)), + ( + "filter_values", + wagtail.blocks.CharBlock( + default="2019,2018,2017,2016,2015,2014,2013", + help_text="Example: 2019,2018,2017,2016,2015,2014,2013", + required=True, + ), + ), + ] + ), + ), + ( + "recent_blog_entries", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock(required=False)), + ( + "tag_filter", + wagtail.blocks.CharBlock( + help_text="Test this filter at foundation.mozilla.org/blog/tags/", + label="Filter by Tag", + required=False, + ), + ), + ( + "topic_filter", + wagtail.blocks.ChoiceBlock( + choices=networkapi.wagtailpages.pagemodels.blog.blog_topic.BlogPageTopic.get_topics, + help_text="Test this filter at foundation.mozilla.org/blog/topic/", + label="Filter by Topic", + required=False, + ), + ), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ] + ), + ), + ( + "blog_set", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock()), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ( + "blog_pages", + wagtail.blocks.ListBlock( + wagtail.blocks.PageChooserBlock(page_type=["wagtailpages.BlogPage"]) + ), + ), + ] + ), + ), + ( + "airtable", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="Copied from the Airtable embed code. The word 'embed' will be in the url" + ), + ), + ( + "height", + wagtail.blocks.IntegerBlock( + default=533, + help_text="The pixel height on desktop view, usually copied from the Airtable embed code", + ), + ), + ] + ), + ), + ( + "typeform", + wagtail.blocks.StructBlock( + [ + ( + "embed_id", + wagtail.blocks.CharBlock( + help_text="The embed id of your Typeform page (e.g. if the form is on admin.typeform.com/form/e8zScc6t, the id will be: e8zScc6t)", + required=True, + ), + ), + ( + "button_type", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ( + "button_text", + wagtail.blocks.CharBlock( + help_text="This is a text prompt for users to open the typeform content", + required=True, + ), + ), + ] + ), + ), + ( + "datawrapper", + wagtail.embeds.blocks.EmbedBlock( + help_text='Enter the "visualization only" link of the Datawrapper chart. It looks something like this: https://datawrapper.dwcdn.net/KwSKp/1/', + icon="image", + template="wagtailpages/blocks/datawrapper_block.html", + ), + ), + ( + "listing", + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock(help_text="Heading for the block.", required=False), + ), + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ( + "highlighted_metadata", + wagtail.blocks.CharBlock( + help_text="Metadata to highlight on the card.", required=False + ), + ), + ( + "metadata", + wagtail.blocks.CharBlock( + help_text="Generic metadata.", required=False + ), + ), + ( + "body", + wagtail.blocks.RichTextBlock( + features=["bold"], + help_text="Body text of the card.", + required=False, + ), + ), + ( + "link_page", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to.", required=False + ), + ), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that the header should link out to.", + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + min_num=2, + ), + ), + ( + "cards_per_row", + wagtail.blocks.ChoiceBlock( + choices=[(2, "2"), (3, "3")], + help_text="Number of cards per row. Note: this is a max and fewer might be used if is less space is available.", + required=False, + ), + ), + ] + ), + ), + ( + "profiles", + wagtail.blocks.StructBlock( + [ + ( + "profiles", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "profile", + wagtail.snippets.blocks.SnippetChooserBlock( + networkapi.wagtailpages.pagemodels.profiles.Profile + ), + ) + ] + ), + min_num=1, + ), + ) + ] + ), + ), + ( + "article_teaser_block", + wagtail.blocks.StructBlock( + [ + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "article", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to.", + page_type=["wagtailpages.ArticlePage"], + required=False, + ), + ) + ] + ), + help_text="Please use a minimum of 3 cards.", + min_num=3, + ), + ) + ] + ), + ), + ( + "group_listing_block", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the group of cards.", required=False + ), + ), + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ( + "meta_data", + wagtail.blocks.CharBlock( + help_text="Optional meta data information for the card.", + required=False, + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ( + "body", + wagtail.blocks.RichTextBlock( + features=["bold", "link"], help_text="Body text of the card." + ), + ), + ( + "url", + wagtail.blocks.CharBlock( + help_text="The URL this card should link to.", required=False + ), + ), + ] + ) + ), + ), + ] + ), + ), + ( + "image_feature", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock(help_text="Image description (for screen readers)."), + ), + ("metadata", wagtail.blocks.CharBlock(required=False)), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ( + "title_link", + wagtail.blocks.PageChooserBlock( + help_text="Page that the title should link out to.", required=False + ), + ), + ("body", wagtail.blocks.CharBlock(required=False)), + ] + ), + ), + ( + "image_teaser_block", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ("text", wagtail.blocks.RichTextBlock(features=["bold"])), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ("url_label", wagtail.blocks.CharBlock(required=False)), + ("url", wagtail.blocks.CharBlock(required=False)), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ( + "link_button", + wagtail.blocks.ListBlock( + 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"', + 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 + ), + ), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ] + ), + help_text="Optional link button", + max_num=1, + min_num=0, + ), + ), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ] + ), + ), + ( + "text_only_teaser", + wagtail.blocks.StructBlock( + [ + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock(help_text="Heading for the card."), + ), + ( + "link_page", + wagtail.blocks.PageChooserBlock( + help_text="Page that the header should link out to.", + required=False, + ), + ), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that the header should link out to.", + required=False, + ), + ), + ("meta_data", wagtail.blocks.CharBlock(max_length=500)), + ( + "body", + wagtail.blocks.TextBlock( + help_text="Body text of the card.", + max_length=200, + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 3 cards.", + min_num=3, + ), + ) + ] + ), + ), + ( + "block_with_aside", + wagtail.blocks.StructBlock( + [ + ( + "content", + wagtail.blocks.StreamBlock( + [ + ( + "listing", + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock( + help_text="Heading for the block.", required=False + ), + ), + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "image", + wagtail.images.blocks.ImageChooserBlock(), + ), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", + required=False, + ), + ), + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the card." + ), + ), + ( + "highlighted_metadata", + wagtail.blocks.CharBlock( + help_text="Metadata to highlight on the card.", + required=False, + ), + ), + ( + "metadata", + wagtail.blocks.CharBlock( + help_text="Generic metadata.", + required=False, + ), + ), + ( + "body", + wagtail.blocks.RichTextBlock( + features=["bold"], + help_text="Body text of the card.", + required=False, + ), + ), + ( + "link_page", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to.", + required=False, + ), + ), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that the header should link out to.", + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + min_num=2, + ), + ), + ( + "cards_per_row", + wagtail.blocks.ChoiceBlock( + choices=[(2, "2"), (3, "3")], + help_text="Number of cards per row. Note: this is a max and fewer might be used if is less space is available.", + required=False, + ), + ), + ] + ), + ), + ( + "paragraph", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + ] + ), + ), + ], + help_text="The wider block that appears on the left on desktop", + icon="doc-full", + max_num=1, + ), + ), + ( + "aside", + wagtail.blocks.StreamBlock( + [ + ( + "aside_content", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the card.", required=False + ), + ), + ( + "body", + wagtail.blocks.TextBlock( + help_text="Body text of the card.", required=False + ), + ), + ] + ), + ), + ( + "linkbutton", + 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"', + 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 + ), + ), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ] + ), + ), + ( + "spacer", + wagtail.blocks.StructBlock( + [ + ( + "size", + wagtail.blocks.ChoiceBlock( + choices=[ + ("1", "quarter spacing"), + ("2", "half spacing"), + ("3", "single spacing"), + ("4", "one and a half spacing"), + ("5", "triple spacing"), + ] + ), + ) + ] + ), + ), + ], + help_text="Elements here will appear in the column on the right side of the page on desktop. This can be left blank if you would just like a 2/3 column on the left", + icon="doc-full", + required=False, + ), + ), + ] + ), + ), + ( + "accordion", + wagtail.blocks.StructBlock( + [ + ( + "accordion_items", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the Accordion Item" + ), + ), + ( + "content", + wagtail.blocks.StreamBlock( + [ + ( + "rich_text", + wagtail.blocks.RichTextBlock( + blank=True, + features=[ + "bold", + "italic", + "link", + "ul", + "ol", + "document-link", + ], + ), + ), + ( + "datawrapper", + wagtail.embeds.blocks.EmbedBlock( + help_text='Enter the "visualization only" link of the Datawrapper chart. It looks something like this: https://datawrapper.dwcdn.net/KwSKp/1/', + icon="image", + template="wagtailpages/blocks/datawrapper_block.html", + ), + ), + ( + "image", + wagtail.blocks.StructBlock( + [ + ( + "image", + wagtail.images.blocks.ImageChooserBlock(), + ), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", + required=True, + ), + ), + ] + ), + ), + ( + "video", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="For YouTube: go to your YouTube video and click “Share,” then “Embed,” and then copy and paste the provided URL only. For example: https://www.youtube.com/embed/3FIVXBawyQw For Vimeo: follow similar steps to grab the embed URL. For example: https://player.vimeo.com/video/9004979", + label="Embed URL", + ), + ), + ( + "caption", + wagtail.blocks.CharBlock(required=False), + ), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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, + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "video_width", + wagtail.blocks.ChoiceBlock( + choices=[ + ("normal", "Normal"), + ("wide", "Wide"), + ("full_width", "Full Width"), + ], + help_text="Wide videos are col-12, Full-Width videos reach both ends of the screen.", + ), + ), + ] + ), + ), + ] + ), + ), + ] + ) + ), + ) + ] + ), + ), + ], + blank=True, + use_json_field=True, + ), + ), + MigrateStreamData( + app_name="donate", + model_name="DonateHelpPage", + field_name="body", + operations_and_block_paths=[ + ( + AlterStreamChildBlockDataOperation( + block="image_teaser_block", operation=migrate_image_teaser_block + ), + "", + ), + ], + ), + migrations.AlterField( + model_name="donatehelppage", + name="body", + field=wagtail.fields.StreamField( + [ + ( + "paragraph", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + "large", + ], + template="wagtailpages/blocks/rich_text_block.html", + ), + ), + ( + "card_grid", + wagtail.blocks.StructBlock( + [ + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ("body", wagtail.blocks.TextBlock(help_text="Body text of the card.")), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that this card should link out to. (Note: If left blank, link will not render.) ", + required=False, + ), + ), + ( + "link_label", + wagtail.blocks.CharBlock( + help_text="Optional Label for the URL link above. (Note: If left blank, link will not render.) ", + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + ), + ) + ] + ), + ), + ( + "image", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "image_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide images are col-12, Full-Width Images reach both ends of the screen (16:6 images recommended for full width)", + ), + ), + ] + ), + ), + ( + "image_text", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ( + "text", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + ] + ), + ), + ( + "url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this image should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ] + ), + ), + ( + "image_text_mini", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ("text", wagtail.blocks.RichTextBlock(features=["bold", "italic", "link"])), + ] + ), + ), + ( + "image_grid", + wagtail.blocks.StructBlock( + [ + ( + "grid_items", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for this image.", required=False + ), + ), + ( + "caption", + wagtail.blocks.CharBlock( + help_text="Please remember to properly attribute any images we use.", + required=False, + ), + ), + ( + "url", + wagtail.blocks.CharBlock( + help_text="Optional URL that this figure should link out to.", + required=False, + ), + ), + ( + "square_image", + wagtail.blocks.BooleanBlock( + default=True, + help_text="If left checked, the image will be cropped to be square.", + required=False, + ), + ), + ] + ) + ), + ) + ] + ), + ), + ( + "video", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="For YouTube: go to your YouTube video and click “Share,” then “Embed,” and then copy and paste the provided URL only. For example: https://www.youtube.com/embed/3FIVXBawyQw For Vimeo: follow similar steps to grab the embed URL. For example: https://player.vimeo.com/video/9004979", + label="Embed URL", + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "video_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide videos are col-12, Full-Width videos reach both ends of the screen.", + ), + ), + ] + ), + ), + ( + "iframe", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.CharBlock( + help_text="Please note that only URLs from allow-listed domains will work." + ), + ), + ( + "height", + wagtail.blocks.IntegerBlock( + help_text="Optional integer pixel value for custom iFrame height", + required=False, + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "iframe_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide iframes are col-12, Full-Width iframes reach both ends of the screen", + ), + ), + ( + "disable_scroll", + wagtail.blocks.BooleanBlock( + default=False, + help_text='Checking this will add "scrolling=no" to the iframe. Use this if your iframe is rendering an unnecessary scroll bar or whitespace below it.', + required=False, + ), + ), + ] + ), + ), + ( + "linkbutton", + 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"', + 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), + ), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ] + ), + ), + ( + "spacer", + wagtail.blocks.StructBlock( + [ + ( + "size", + wagtail.blocks.ChoiceBlock( + choices=[ + ("1", "quarter spacing"), + ("2", "half spacing"), + ("3", "single spacing"), + ("4", "one and a half spacing"), + ("5", "triple spacing"), + ] + ), + ) + ] + ), + ), + ( + "single_quote", + wagtail.blocks.StructBlock( + [ + ("quote", wagtail.blocks.RichTextBlock(features=["bold"])), + ("attribution", wagtail.blocks.CharBlock(required=False)), + ( + "attribution_info", + wagtail.blocks.RichTextBlock(features=["bold", "link", "large"], required=False), + ), + ] + ), + ), + ( + "pulse_listing", + wagtail.blocks.StructBlock( + [ + ( + "search_terms", + wagtail.blocks.CharBlock( + help_text="Test your search at mozillapulse.org/search", + label="Search", + required=False, + ), + ), + ( + "max_number_of_results", + wagtail.blocks.IntegerBlock( + default=6, + help_text="Choose 1-12. If you want visitors to see more, link to a search or tag on Pulse.", + max_value=12, + min_value=0, + required=True, + ), + ), + ( + "only_featured_entries", + wagtail.blocks.BooleanBlock( + default=False, + help_text="Featured items are selected by Pulse moderators.", + label="Display only featured entries", + required=False, + ), + ), + ( + "newest_first", + wagtail.blocks.ChoiceBlock( + choices=[ + ("True", "Show newer entries first"), + ("False", "Show older entries first"), + ], + label="Sort", + ), + ), + ( + "advanced_filter_header", + wagtail.blocks.static_block.StaticBlock( + admin_text="-------- ADVANCED FILTERS: OPTIONS TO DISPLAY FEWER, MORE TARGETED RESULTS. --------", + label=" ", + ), + ), + ( + "issues", + wagtail.blocks.ChoiceBlock( + choices=[ + ("all", "All"), + ("Decentralization", "Decentralization"), + ("Digital Inclusion", "Digital Inclusion"), + ("Online Privacy & Security", "Online Privacy & Security"), + ("Open Innovation", "Open Innovation"), + ("Web Literacy", "Web Literacy"), + ] + ), + ), + ( + "help", + wagtail.blocks.ChoiceBlock( + choices=[ + ("all", "All"), + ("Attend", "Attend"), + ("Create content", "Create content"), + ("Code", "Code"), + ("Design", "Design"), + ("Fundraise", "Fundraise"), + ("Join community", "Join community"), + ("Localize & translate", "Localize & translate"), + ("Mentor", "Mentor"), + ("Plan & organize", "Plan & organize"), + ("Promote", "Promote"), + ("Take action", "Take action"), + ("Test & feedback", "Test & feedback"), + ("Write documentation", "Write documentation"), + ], + label="Type of help needed", + ), + ), + ( + "direct_link", + wagtail.blocks.BooleanBlock( + default=False, + help_text="Checked: user goes to project link. Unchecked: user goes to pulse entry", + label="Direct link", + required=False, + ), + ), + ] + ), + ), + ( + "profile_listing", + wagtail.blocks.StructBlock( + [ + ( + "max_number_of_results", + wagtail.blocks.IntegerBlock( + default=12, + help_text="Pick up to 48 profiles.", + max_value=48, + min_value=1, + required=True, + ), + ), + ( + "advanced_filter_header", + wagtail.blocks.static_block.StaticBlock( + admin_text="-------- ADVANCED FILTERS: OPTIONS TO DISPLAY FEWER, MORE TARGETED RESULTS. --------", + label=" ", + ), + ), + ( + "profile_type", + wagtail.blocks.CharBlock(default="", help_text="Example: Fellow.", required=False), + ), + ( + "program_type", + wagtail.blocks.CharBlock( + default="", help_text="Example: Tech Policy.", required=False + ), + ), + ("year", wagtail.blocks.CharBlock(default="", required=False)), + ] + ), + ), + ( + "profile_by_id", + wagtail.blocks.StructBlock( + [ + ( + "ids", + wagtail.blocks.CharBlock( + help_text="Show profiles for pulse users with specific profile ids (mozillapulse.org/profile/[##]). For multiple profiles, specify a comma separated list (e.g. 85,105,332).", + label="Profile by ID", + ), + ) + ] + ), + ), + ( + "profile_directory", + wagtail.blocks.StructBlock( + [ + ( + "max_number_of_results", + wagtail.blocks.IntegerBlock( + default=12, + help_text="Pick up to 48 profiles.", + max_value=48, + min_value=1, + required=True, + ), + ), + ( + "advanced_filter_header", + wagtail.blocks.static_block.StaticBlock( + admin_text="-------- ADVANCED FILTERS: OPTIONS TO DISPLAY FEWER, MORE TARGETED RESULTS. --------", + label=" ", + ), + ), + ( + "profile_type", + wagtail.blocks.CharBlock(default="", help_text="Example: Fellow.", required=False), + ), + ( + "program_type", + wagtail.blocks.CharBlock( + default="", help_text="Example: Tech Policy.", required=False + ), + ), + ("year", wagtail.blocks.CharBlock(default="", required=False)), + ( + "filter_values", + wagtail.blocks.CharBlock( + default="2019,2018,2017,2016,2015,2014,2013", + help_text="Example: 2019,2018,2017,2016,2015,2014,2013", + required=True, + ), + ), + ] + ), + ), + ( + "recent_blog_entries", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock(required=False)), + ( + "tag_filter", + wagtail.blocks.CharBlock( + help_text="Test this filter at foundation.mozilla.org/blog/tags/", + label="Filter by Tag", + required=False, + ), + ), + ( + "topic_filter", + wagtail.blocks.ChoiceBlock( + choices=networkapi.wagtailpages.pagemodels.blog.blog_topic.BlogPageTopic.get_topics, + help_text="Test this filter at foundation.mozilla.org/blog/topic/", + label="Filter by Topic", + required=False, + ), + ), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ] + ), + ), + ( + "blog_set", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock()), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ( + "blog_pages", + wagtail.blocks.ListBlock( + wagtail.blocks.PageChooserBlock(page_type=["wagtailpages.BlogPage"]) + ), + ), + ] + ), + ), + ( + "airtable", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="Copied from the Airtable embed code. The word 'embed' will be in the url" + ), + ), + ( + "height", + wagtail.blocks.IntegerBlock( + default=533, + help_text="The pixel height on desktop view, usually copied from the Airtable embed code", + ), + ), + ] + ), + ), + ( + "typeform", + wagtail.blocks.StructBlock( + [ + ( + "embed_id", + wagtail.blocks.CharBlock( + help_text="The embed id of your Typeform page (e.g. if the form is on admin.typeform.com/form/e8zScc6t, the id will be: e8zScc6t)", + required=True, + ), + ), + ( + "button_type", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ( + "button_text", + wagtail.blocks.CharBlock( + help_text="This is a text prompt for users to open the typeform content", + required=True, + ), + ), + ] + ), + ), + ( + "datawrapper", + wagtail.embeds.blocks.EmbedBlock( + help_text='Enter the "visualization only" link of the Datawrapper chart. It looks something like this: https://datawrapper.dwcdn.net/KwSKp/1/', + icon="image", + template="wagtailpages/blocks/datawrapper_block.html", + ), + ), + ( + "listing", + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock(help_text="Heading for the block.", required=False), + ), + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ( + "highlighted_metadata", + wagtail.blocks.CharBlock( + help_text="Metadata to highlight on the card.", required=False + ), + ), + ( + "metadata", + wagtail.blocks.CharBlock( + help_text="Generic metadata.", required=False + ), + ), + ( + "body", + wagtail.blocks.RichTextBlock( + features=["bold"], + help_text="Body text of the card.", + required=False, + ), + ), + ( + "link_page", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to.", required=False + ), + ), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that the header should link out to.", + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + min_num=2, + ), + ), + ( + "cards_per_row", + wagtail.blocks.ChoiceBlock( + choices=[(2, "2"), (3, "3")], + help_text="Number of cards per row. Note: this is a max and fewer might be used if is less space is available.", + required=False, + ), + ), + ] + ), + ), + ( + "profiles", + wagtail.blocks.StructBlock( + [ + ( + "profiles", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "profile", + wagtail.snippets.blocks.SnippetChooserBlock( + networkapi.wagtailpages.pagemodels.profiles.Profile + ), + ) + ] + ), + min_num=1, + ), + ) + ] + ), + ), + ( + "article_teaser_block", + wagtail.blocks.StructBlock( + [ + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "article", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to.", + page_type=["wagtailpages.ArticlePage"], + required=False, + ), + ) + ] + ), + help_text="Please use a minimum of 3 cards.", + min_num=3, + ), + ) + ] + ), + ), + ( + "group_listing_block", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the group of cards.", required=False + ), + ), + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ( + "meta_data", + wagtail.blocks.CharBlock( + help_text="Optional meta data information for the card.", + required=False, + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ( + "body", + wagtail.blocks.RichTextBlock( + features=["bold", "link"], help_text="Body text of the card." + ), + ), + ( + "url", + wagtail.blocks.CharBlock( + help_text="The URL this card should link to.", required=False + ), + ), + ] + ) + ), + ), + ] + ), + ), + ( + "image_feature", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock(help_text="Image description (for screen readers)."), + ), + ("metadata", wagtail.blocks.CharBlock(required=False)), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ( + "title_link", + wagtail.blocks.PageChooserBlock( + help_text="Page that the title should link out to.", required=False + ), + ), + ("body", wagtail.blocks.CharBlock(required=False)), + ] + ), + ), + ( + "image_teaser_block", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ("text", wagtail.blocks.RichTextBlock(features=["bold"])), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ( + "link_button", + wagtail.blocks.ListBlock( + 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"', + 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 + ), + ), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ] + ), + help_text="Optional link button", + max_num=1, + min_num=0, + ), + ), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ] + ), + ), + ( + "text_only_teaser", + wagtail.blocks.StructBlock( + [ + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock(help_text="Heading for the card."), + ), + ( + "link_page", + wagtail.blocks.PageChooserBlock( + help_text="Page that the header should link out to.", + required=False, + ), + ), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that the header should link out to.", + required=False, + ), + ), + ("meta_data", wagtail.blocks.CharBlock(max_length=500)), + ( + "body", + wagtail.blocks.TextBlock( + help_text="Body text of the card.", + max_length=200, + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 3 cards.", + min_num=3, + ), + ) + ] + ), + ), + ( + "block_with_aside", + wagtail.blocks.StructBlock( + [ + ( + "content", + wagtail.blocks.StreamBlock( + [ + ( + "listing", + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock( + help_text="Heading for the block.", required=False + ), + ), + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "image", + wagtail.images.blocks.ImageChooserBlock(), + ), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", + required=False, + ), + ), + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the card." + ), + ), + ( + "highlighted_metadata", + wagtail.blocks.CharBlock( + help_text="Metadata to highlight on the card.", + required=False, + ), + ), + ( + "metadata", + wagtail.blocks.CharBlock( + help_text="Generic metadata.", + required=False, + ), + ), + ( + "body", + wagtail.blocks.RichTextBlock( + features=["bold"], + help_text="Body text of the card.", + required=False, + ), + ), + ( + "link_page", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to.", + required=False, + ), + ), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that the header should link out to.", + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + min_num=2, + ), + ), + ( + "cards_per_row", + wagtail.blocks.ChoiceBlock( + choices=[(2, "2"), (3, "3")], + help_text="Number of cards per row. Note: this is a max and fewer might be used if is less space is available.", + required=False, + ), + ), + ] + ), + ), + ( + "paragraph", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + ] + ), + ), + ], + help_text="The wider block that appears on the left on desktop", + icon="doc-full", + max_num=1, + ), + ), + ( + "aside", + wagtail.blocks.StreamBlock( + [ + ( + "aside_content", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the card.", required=False + ), + ), + ( + "body", + wagtail.blocks.TextBlock( + help_text="Body text of the card.", required=False + ), + ), + ] + ), + ), + ( + "linkbutton", + 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"', + 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 + ), + ), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ] + ), + ), + ( + "spacer", + wagtail.blocks.StructBlock( + [ + ( + "size", + wagtail.blocks.ChoiceBlock( + choices=[ + ("1", "quarter spacing"), + ("2", "half spacing"), + ("3", "single spacing"), + ("4", "one and a half spacing"), + ("5", "triple spacing"), + ] + ), + ) + ] + ), + ), + ], + help_text="Elements here will appear in the column on the right side of the page on desktop. This can be left blank if you would just like a 2/3 column on the left", + icon="doc-full", + required=False, + ), + ), + ] + ), + ), + ( + "accordion", + wagtail.blocks.StructBlock( + [ + ( + "accordion_items", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the Accordion Item" + ), + ), + ( + "content", + wagtail.blocks.StreamBlock( + [ + ( + "rich_text", + wagtail.blocks.RichTextBlock( + blank=True, + features=[ + "bold", + "italic", + "link", + "ul", + "ol", + "document-link", + ], + ), + ), + ( + "datawrapper", + wagtail.embeds.blocks.EmbedBlock( + help_text='Enter the "visualization only" link of the Datawrapper chart. It looks something like this: https://datawrapper.dwcdn.net/KwSKp/1/', + icon="image", + template="wagtailpages/blocks/datawrapper_block.html", + ), + ), + ( + "image", + wagtail.blocks.StructBlock( + [ + ( + "image", + wagtail.images.blocks.ImageChooserBlock(), + ), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", + required=True, + ), + ), + ] + ), + ), + ( + "video", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="For YouTube: go to your YouTube video and click “Share,” then “Embed,” and then copy and paste the provided URL only. For example: https://www.youtube.com/embed/3FIVXBawyQw For Vimeo: follow similar steps to grab the embed URL. For example: https://player.vimeo.com/video/9004979", + label="Embed URL", + ), + ), + ( + "caption", + wagtail.blocks.CharBlock(required=False), + ), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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, + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "video_width", + wagtail.blocks.ChoiceBlock( + choices=[ + ("normal", "Normal"), + ("wide", "Wide"), + ("full_width", "Full Width"), + ], + help_text="Wide videos are col-12, Full-Width videos reach both ends of the screen.", + ), + ), + ] + ), + ), + ] + ), + ), + ] + ) + ), + ) + ] + ), + ), + ], + blank=True, + use_json_field=True, + ), + ), + ] diff --git a/network-api/networkapi/mozfest/migrations/0055_update_videoblock_with_linkblock.py b/network-api/networkapi/mozfest/migrations/0055_update_videoblock_with_linkblock.py new file mode 100644 index 00000000000..b43ecc5edd7 --- /dev/null +++ b/network-api/networkapi/mozfest/migrations/0055_update_videoblock_with_linkblock.py @@ -0,0 +1,4457 @@ +# Generated by Django 4.2.11 on 2024-07-03 00:44 + +import wagtail.blocks +import wagtail.blocks.static_block +import wagtail.documents.blocks +import wagtail.embeds.blocks +import wagtail.fields +import wagtail.images.blocks +import wagtail.snippets.blocks +import wagtailmedia.blocks +from django.db import migrations +from wagtail.blocks.migrations.migrate_operation import MigrateStreamData + +import networkapi.wagtailpages.pagemodels.blog.blog_topic +import networkapi.wagtailpages.pagemodels.profiles +import networkapi.wagtailpages.validators +from networkapi.utility.migration.operations import AlterStreamChildBlockDataOperation + + +def migrate_video_block(source_block): + new_value = { + "url": source_block["value"].get("url"), + "caption": source_block["value"].get("caption"), + "caption_url": [], + "video_width": source_block["value"].get("video_width"), + } + if "captionURL" in source_block["value"] and source_block["value"]["captionURL"]: + new_value["caption_url"] = [ + { + "link_to": "external_url", + "external_url": source_block["value"].get("captionURL"), + "new_window": True, + } + ] + return { + **source_block, + "value": new_value, + } + + +class Migration(migrations.Migration): + + dependencies = [ + ("mozfest", "0054_update_imagetextblock_with_linkblock"), + ] + + operations = [ + migrations.AlterField( + model_name="mozfestprimarypage", + name="body", + field=wagtail.fields.StreamField( + [ + ( + "paragraph", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + "large", + ], + template="wagtailpages/blocks/rich_text_block.html", + ), + ), + ( + "card_grid", + wagtail.blocks.StructBlock( + [ + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ("body", wagtail.blocks.TextBlock(help_text="Body text of the card.")), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that this card should link out to. (Note: If left blank, link will not render.) ", + required=False, + ), + ), + ( + "link_label", + wagtail.blocks.CharBlock( + help_text="Optional Label for the URL link above. (Note: If left blank, link will not render.) ", + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + ), + ) + ] + ), + ), + ( + "image", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "image_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide images are col-12, Full-Width Images reach both ends of the screen (16:6 images recommended for full width)", + ), + ), + ] + ), + ), + ( + "image_text", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ( + "text", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + ] + ), + ), + ( + "url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this image should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ] + ), + ), + ( + "image_text_mini", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ("text", wagtail.blocks.RichTextBlock(features=["bold", "italic", "link"])), + ] + ), + ), + ( + "image_grid", + wagtail.blocks.StructBlock( + [ + ( + "grid_items", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for this image.", required=False + ), + ), + ( + "caption", + wagtail.blocks.CharBlock( + help_text="Please remember to properly attribute any images we use.", + required=False, + ), + ), + ( + "url", + wagtail.blocks.CharBlock( + help_text="Optional URL that this figure should link out to.", + required=False, + ), + ), + ( + "square_image", + wagtail.blocks.BooleanBlock( + default=True, + help_text="If left checked, the image will be cropped to be square.", + required=False, + ), + ), + ] + ) + ), + ) + ] + ), + ), + ( + "video", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="For YouTube: go to your YouTube video and click “Share,” then “Embed,” and then copy and paste the provided URL only. For example: https://www.youtube.com/embed/3FIVXBawyQw For Vimeo: follow similar steps to grab the embed URL. For example: https://player.vimeo.com/video/9004979", + label="Embed URL", + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "captionURL", + wagtail.blocks.CharBlock( + help_text="Optional URL for caption to link to.", required=False + ), + ), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "video_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide videos are col-12, Full-Width videos reach both ends of the screen.", + ), + ), + ] + ), + ), + ( + "iframe", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.CharBlock( + help_text="Please note that only URLs from allow-listed domains will work." + ), + ), + ( + "height", + wagtail.blocks.IntegerBlock( + help_text="Optional integer pixel value for custom iFrame height", + required=False, + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "iframe_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide iframes are col-12, Full-Width iframes reach both ends of the screen", + ), + ), + ( + "disable_scroll", + wagtail.blocks.BooleanBlock( + default=False, + help_text='Checking this will add "scrolling=no" to the iframe. Use this if your iframe is rendering an unnecessary scroll bar or whitespace below it.', + required=False, + ), + ), + ] + ), + ), + ( + "linkbutton", + 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"', + 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), + ), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ] + ), + ), + ( + "spacer", + wagtail.blocks.StructBlock( + [ + ( + "size", + wagtail.blocks.ChoiceBlock( + choices=[ + ("1", "quarter spacing"), + ("2", "half spacing"), + ("3", "single spacing"), + ("4", "one and a half spacing"), + ("5", "triple spacing"), + ] + ), + ) + ] + ), + ), + ( + "single_quote", + wagtail.blocks.StructBlock( + [ + ("quote", wagtail.blocks.RichTextBlock(features=["bold"])), + ("attribution", wagtail.blocks.CharBlock(required=False)), + ( + "attribution_info", + wagtail.blocks.RichTextBlock(features=["bold", "link", "large"], required=False), + ), + ] + ), + ), + ( + "profile_by_id", + wagtail.blocks.StructBlock( + [ + ( + "ids", + wagtail.blocks.CharBlock( + help_text="Show profiles for pulse users with specific profile ids (mozillapulse.org/profile/[##]). For multiple profiles, specify a comma separated list (e.g. 85,105,332).", + label="Profile by ID", + ), + ) + ] + ), + ), + ( + "profile_directory", + wagtail.blocks.StructBlock( + [ + ( + "max_number_of_results", + wagtail.blocks.IntegerBlock( + default=12, + help_text="Pick up to 48 profiles.", + max_value=48, + min_value=1, + required=True, + ), + ), + ( + "advanced_filter_header", + wagtail.blocks.static_block.StaticBlock( + admin_text="-------- ADVANCED FILTERS: OPTIONS TO DISPLAY FEWER, MORE TARGETED RESULTS. --------", + label=" ", + ), + ), + ( + "profile_type", + wagtail.blocks.CharBlock(default="", help_text="Example: Fellow.", required=False), + ), + ( + "program_type", + wagtail.blocks.CharBlock( + default="", help_text="Example: Tech Policy.", required=False + ), + ), + ("year", wagtail.blocks.CharBlock(default="", required=False)), + ( + "filter_values", + wagtail.blocks.CharBlock( + default="2019,2018,2017,2016,2015,2014,2013", + help_text="Example: 2019,2018,2017,2016,2015,2014,2013", + required=True, + ), + ), + ] + ), + ), + ( + "recent_blog_entries", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock(required=False)), + ( + "tag_filter", + wagtail.blocks.CharBlock( + help_text="Test this filter at foundation.mozilla.org/blog/tags/", + label="Filter by Tag", + required=False, + ), + ), + ( + "topic_filter", + wagtail.blocks.ChoiceBlock( + choices=networkapi.wagtailpages.pagemodels.blog.blog_topic.BlogPageTopic.get_topics, + help_text="Test this filter at foundation.mozilla.org/blog/topic/", + label="Filter by Topic", + required=False, + ), + ), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ] + ), + ), + ( + "blog_set", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock()), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ( + "blog_pages", + wagtail.blocks.ListBlock( + wagtail.blocks.PageChooserBlock(page_type=["wagtailpages.BlogPage"]) + ), + ), + ] + ), + ), + ( + "datawrapper", + wagtail.embeds.blocks.EmbedBlock( + help_text='Enter the "visualization only" link of the Datawrapper chart. It looks something like this: https://datawrapper.dwcdn.net/KwSKp/1/', + icon="image", + template="wagtailpages/blocks/datawrapper_block.html", + ), + ), + ( + "listing", + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock(help_text="Heading for the block.", required=False), + ), + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ( + "highlighted_metadata", + wagtail.blocks.CharBlock( + help_text="Metadata to highlight on the card.", required=False + ), + ), + ( + "metadata", + wagtail.blocks.CharBlock( + help_text="Generic metadata.", required=False + ), + ), + ( + "body", + wagtail.blocks.RichTextBlock( + features=["bold"], + help_text="Body text of the card.", + required=False, + ), + ), + ( + "link_page", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to.", required=False + ), + ), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that the header should link out to.", + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + min_num=2, + ), + ), + ( + "cards_per_row", + wagtail.blocks.ChoiceBlock( + choices=[(2, "2"), (3, "3")], + help_text="Number of cards per row. Note: this is a max and fewer might be used if is less space is available.", + required=False, + ), + ), + ] + ), + ), + ( + "profiles", + wagtail.blocks.StructBlock( + [ + ( + "profiles", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "profile", + wagtail.snippets.blocks.SnippetChooserBlock( + networkapi.wagtailpages.pagemodels.profiles.Profile + ), + ) + ] + ), + min_num=1, + ), + ) + ] + ), + ), + ( + "group_listing_block", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the group of cards.", required=False + ), + ), + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ( + "meta_data", + wagtail.blocks.CharBlock( + help_text="Optional meta data information for the card.", + required=False, + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ( + "body", + wagtail.blocks.RichTextBlock( + features=["bold", "link"], help_text="Body text of the card." + ), + ), + ( + "url", + wagtail.blocks.CharBlock( + help_text="The URL this card should link to.", required=False + ), + ), + ] + ) + ), + ), + ] + ), + ), + ( + "image_feature", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock(help_text="Image description (for screen readers)."), + ), + ("metadata", wagtail.blocks.CharBlock(required=False)), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ( + "title_link", + wagtail.blocks.PageChooserBlock( + help_text="Page that the title should link out to.", required=False + ), + ), + ("body", wagtail.blocks.CharBlock(required=False)), + ] + ), + ), + ( + "image_teaser_block", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ("text", wagtail.blocks.RichTextBlock(features=["bold"])), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ("url_label", wagtail.blocks.CharBlock(required=False)), + ("url", wagtail.blocks.CharBlock(required=False)), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ] + ), + ), + ( + "text_only_teaser", + wagtail.blocks.StructBlock( + [ + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock(help_text="Heading for the card."), + ), + ( + "link_page", + wagtail.blocks.PageChooserBlock( + help_text="Page that the header should link out to.", + required=False, + ), + ), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that the header should link out to.", + required=False, + ), + ), + ("meta_data", wagtail.blocks.CharBlock(max_length=500)), + ( + "body", + wagtail.blocks.TextBlock( + help_text="Body text of the card.", + max_length=200, + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 3 cards.", + min_num=3, + ), + ) + ] + ), + ), + ( + "block_with_aside", + wagtail.blocks.StructBlock( + [ + ( + "content", + wagtail.blocks.StreamBlock( + [ + ( + "listing", + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock( + help_text="Heading for the block.", required=False + ), + ), + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "image", + wagtail.images.blocks.ImageChooserBlock(), + ), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", + required=False, + ), + ), + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the card." + ), + ), + ( + "highlighted_metadata", + wagtail.blocks.CharBlock( + help_text="Metadata to highlight on the card.", + required=False, + ), + ), + ( + "metadata", + wagtail.blocks.CharBlock( + help_text="Generic metadata.", + required=False, + ), + ), + ( + "body", + wagtail.blocks.RichTextBlock( + features=["bold"], + help_text="Body text of the card.", + required=False, + ), + ), + ( + "link_page", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to.", + required=False, + ), + ), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that the header should link out to.", + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + min_num=2, + ), + ), + ( + "cards_per_row", + wagtail.blocks.ChoiceBlock( + choices=[(2, "2"), (3, "3")], + help_text="Number of cards per row. Note: this is a max and fewer might be used if is less space is available.", + required=False, + ), + ), + ] + ), + ), + ( + "paragraph", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + ] + ), + ), + ], + help_text="The wider block that appears on the left on desktop", + icon="doc-full", + max_num=1, + ), + ), + ( + "aside", + wagtail.blocks.StreamBlock( + [ + ( + "aside_content", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the card.", required=False + ), + ), + ( + "body", + wagtail.blocks.TextBlock( + help_text="Body text of the card.", required=False + ), + ), + ] + ), + ), + ( + "linkbutton", + 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"', + 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 + ), + ), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ] + ), + ), + ( + "spacer", + wagtail.blocks.StructBlock( + [ + ( + "size", + wagtail.blocks.ChoiceBlock( + choices=[ + ("1", "quarter spacing"), + ("2", "half spacing"), + ("3", "single spacing"), + ("4", "one and a half spacing"), + ("5", "triple spacing"), + ] + ), + ) + ] + ), + ), + ], + help_text="Elements here will appear in the column on the right side of the page on desktop. This can be left blank if you would just like a 2/3 column on the left", + icon="doc-full", + required=False, + ), + ), + ] + ), + ), + ( + "accordion", + wagtail.blocks.StructBlock( + [ + ( + "accordion_items", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the Accordion Item" + ), + ), + ( + "content", + wagtail.blocks.StreamBlock( + [ + ( + "rich_text", + wagtail.blocks.RichTextBlock( + blank=True, + features=[ + "bold", + "italic", + "link", + "ul", + "ol", + "document-link", + ], + ), + ), + ( + "datawrapper", + wagtail.embeds.blocks.EmbedBlock( + help_text='Enter the "visualization only" link of the Datawrapper chart. It looks something like this: https://datawrapper.dwcdn.net/KwSKp/1/', + icon="image", + template="wagtailpages/blocks/datawrapper_block.html", + ), + ), + ( + "image", + wagtail.blocks.StructBlock( + [ + ( + "image", + wagtail.images.blocks.ImageChooserBlock(), + ), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", + required=True, + ), + ), + ] + ), + ), + ( + "video", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="For YouTube: go to your YouTube video and click “Share,” then “Embed,” and then copy and paste the provided URL only. For example: https://www.youtube.com/embed/3FIVXBawyQw For Vimeo: follow similar steps to grab the embed URL. For example: https://player.vimeo.com/video/9004979", + label="Embed URL", + ), + ), + ( + "caption", + wagtail.blocks.CharBlock(required=False), + ), + ( + "captionURL", + wagtail.blocks.CharBlock( + help_text="Optional URL for caption to link to.", + required=False, + ), + ), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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, + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "video_width", + wagtail.blocks.ChoiceBlock( + choices=[ + ("normal", "Normal"), + ("wide", "Wide"), + ("full_width", "Full Width"), + ], + help_text="Wide videos are col-12, Full-Width videos reach both ends of the screen.", + ), + ), + ] + ), + ), + ] + ), + ), + ] + ) + ), + ) + ] + ), + ), + ( + "session_slider", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock(help_text="Heading for the slider.")), + ( + "session_items", + wagtail.blocks.StreamBlock( + [ + ( + "session_item", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the card." + ), + ), + ( + "author_subheading", + wagtail.blocks.CharBlock( + help_text="Author of this session.", required=False + ), + ), + ( + "image", + wagtail.images.blocks.ImageChooserBlock( + help_text="The image associated with this session." + ), + ), + ( + "body", + wagtail.blocks.RichTextBlock( + help_text="Body text of this card." + ), + ), + ( + "video", + wagtailmedia.blocks.VideoChooserBlock( + help_text="Video that will autoplay when this card is hovered on", + required=False, + ), + ), + ( + "link", + wagtail.blocks.StreamBlock( + [ + ( + "internal", + wagtail.blocks.StructBlock( + [ + ( + "link", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to." + ), + ) + ] + ), + ), + ( + "external", + wagtail.blocks.StructBlock( + [ + ( + "link", + wagtail.blocks.URLBlock( + help_text="URL that this should link out to." + ), + ) + ] + ), + ), + ], + help_text="Page or external URL this card will link out to.", + max_num=1, + ), + ), + ] + ), + ) + ], + help_text="A list of sessions in the slider.", + ), + ), + ( + "button", + wagtail.blocks.StreamBlock( + [ + ( + "internal", + wagtail.blocks.StructBlock( + [ + ( + "label", + wagtail.blocks.CharBlock(help_text="Label for this link."), + ), + ( + "link", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to." + ), + ), + ] + ), + ), + ( + "external", + wagtail.blocks.StructBlock( + [ + ( + "label", + wagtail.blocks.CharBlock(help_text="Label for this link."), + ), + ( + "link", + wagtail.blocks.URLBlock( + help_text="URL that this should link out to." + ), + ), + ] + ), + ), + ], + help_text="Button that appears below the slider.", + max_num=1, + required=False, + ), + ), + ] + ), + ), + ( + "current_events_slider", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock(help_text="Heading for the slider.")), + ( + "current_events", + wagtail.blocks.StreamBlock( + [ + ( + "current_event", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock(help_text="Heading of the card."), + ), + ( + "subheading_link", + wagtail.blocks.StreamBlock( + [ + ( + "internal", + wagtail.blocks.StructBlock( + [ + ( + "label", + wagtail.blocks.CharBlock( + help_text="Label for this link." + ), + ), + ( + "link", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to." + ), + ), + ] + ), + ), + ( + "external", + wagtail.blocks.StructBlock( + [ + ( + "label", + wagtail.blocks.CharBlock( + help_text="Label for this link." + ), + ), + ( + "link", + wagtail.blocks.URLBlock( + help_text="URL that this should link out to." + ), + ), + ] + ), + ), + ], + help_text="The link that appears below the card heading.", + max_num=1, + required=False, + ), + ), + ( + "image", + wagtail.images.blocks.ImageChooserBlock( + help_text="The image associated with this event." + ), + ), + ( + "body", + wagtail.blocks.TextBlock( + help_text="Body text of the card." + ), + ), + ( + "buttons", + wagtail.blocks.StreamBlock( + [ + ( + "internal", + wagtail.blocks.StructBlock( + [ + ( + "label", + wagtail.blocks.CharBlock( + help_text="Label for this link." + ), + ), + ( + "link", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to." + ), + ), + ] + ), + ), + ( + "external", + wagtail.blocks.StructBlock( + [ + ( + "label", + wagtail.blocks.CharBlock( + help_text="Label for this link." + ), + ), + ( + "link", + wagtail.blocks.URLBlock( + help_text="URL that this should link out to." + ), + ), + ] + ), + ), + ( + "document", + wagtail.blocks.StructBlock( + [ + ( + "label", + wagtail.blocks.CharBlock( + help_text="Label for this link." + ), + ), + ( + "document", + wagtail.documents.blocks.DocumentChooserBlock( + help_text="Document that this should link out to." + ), + ), + ], + help_text='An iCal document can be attached here for an "Add to Calendar" button.', + ), + ), + ], + help_text="A list of buttons that will appear at the bottom of the card.", + max_num=2, + ), + ), + ] + ), + ) + ], + help_text="A list of current events in the slider.", + ), + ), + ] + ), + ), + ( + "spaces", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock()), + ( + "cards", + wagtail.blocks.StreamBlock( + [ + ( + "space_card", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the card." + ), + ), + ( + "body", + wagtail.blocks.TextBlock( + help_text="Body text of the card." + ), + ), + ( + "link", + wagtail.blocks.StreamBlock( + [ + ( + "internal", + wagtail.blocks.StructBlock( + [ + ( + "link", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to." + ), + ) + ] + ), + ), + ( + "external", + wagtail.blocks.StructBlock( + [ + ( + "link", + wagtail.blocks.URLBlock( + help_text="URL that this should link out to." + ), + ) + ] + ), + ), + ], + help_text="Page or external URL this card will link out to.", + max_num=1, + ), + ), + ] + ), + ) + ], + help_text="A list of Spaces Cards.", + ), + ), + ] + ), + ), + ( + "tito_widget", + wagtail.blocks.StructBlock( + [ + ( + "button_label", + wagtail.blocks.CharBlock(help_text="The text to show on the Tito button."), + ), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ( + "event", + wagtail.snippets.blocks.SnippetChooserBlock( + "events.TitoEvent", help_event="The Tito event to be displayed" + ), + ), + ( + "releases", + wagtail.blocks.CharBlock( + help_text='Comma-separated list of ticket/release IDs to limit to, e.g. "3elajg6qcxu,6qiiw4socs4"', + required=False, + ), + ), + ] + ), + ), + ( + "statistics", + wagtail.blocks.StructBlock( + [ + ( + "statistics", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="The statistic figure, e.g '1000+' or '10%'" + ), + ), + ( + "description", + wagtail.blocks.CharBlock( + help_text="Context or description for the statistic" + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + max_num=4, + min_num=2, + ), + ) + ] + ), + ), + ( + "carousel_and_text", + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock(help_text="Heading for the block.", required=False), + ), + ("text", wagtail.blocks.RichTextBlock(features=["bold", "italic", "link"])), + ( + "link_url", + wagtail.blocks.URLBlock( + help_text="A CTA URL for a link displayed", required=False + ), + ), + ( + "link_label", + wagtail.blocks.CharBlock(help_text="Label for the CTA link.", required=False), + ), + ( + "carousel_images", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", + required=True, + ), + ), + ] + ), + max_num=4, + ), + ), + ] + ), + ), + ( + "tickets", + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock(help_text="Heading for the block.", required=False), + ), + ( + "tickets", + wagtail.blocks.ListBlock( + wagtail.snippets.blocks.SnippetChooserBlock("mozfest.Ticket"), max_num=3 + ), + ), + ] + ), + ), + ( + "dark_quote", + wagtail.blocks.StructBlock( + [ + ("quote", wagtail.blocks.RichTextBlock(features=["bold"])), + ("attribution", wagtail.blocks.CharBlock(required=False)), + ( + "attribution_info", + wagtail.blocks.RichTextBlock(features=["bold", "link", "large"], required=False), + ), + ] + ), + ), + ( + "cta", + 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"', + 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), + ), + ("heading", wagtail.blocks.CharBlock(required=False)), + ("text", wagtail.blocks.CharBlock(required=False)), + ("dark_background", wagtail.blocks.BooleanBlock(required=False)), + ] + ), + ), + ( + "newsletter_signup", + wagtail.blocks.StructBlock( + [ + ( + "snippet", + wagtail.snippets.blocks.SnippetChooserBlock( + "mozfest.NewsletterSignupWithBackground" + ), + ) + ] + ), + ), + ( + "mixed_content", + wagtail.blocks.StructBlock( + [ + ( + "video", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="For YouTube: go to your YouTube video and click “Share,” then “Embed,” and then copy and paste the provided URL only. For example: https://www.youtube.com/embed/3FIVXBawyQw For Vimeo: follow similar steps to grab the embed URL. For example: https://player.vimeo.com/video/9004979", + label="Embed URL", + ), + ), + ( + "caption", + wagtail.blocks.CharBlock( + help_text="Optional caption for the video, displayed next to the play button.", + max_length=25, + required=False, + ), + ), + ( + "title", + wagtail.blocks.CharBlock( + help_text="Optional title for the video.", + max_length=50, + required=False, + ), + ), + ( + "text", + wagtail.blocks.CharBlock( + help_text="Text content to display with the video title.", + required=False, + ), + ), + ( + "thumbnail", + wagtail.images.blocks.ImageChooserBlock( + help_text="The image to show before the video is played." + ), + ), + ] + ), + ), + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ( + "highlighted_metadata", + wagtail.blocks.CharBlock( + help_text="Metadata to highlight on the card.", required=False + ), + ), + ( + "metadata", + wagtail.blocks.CharBlock( + help_text="Generic metadata.", required=False + ), + ), + ( + "body", + wagtail.blocks.RichTextBlock( + features=["bold"], + help_text="Body text of the card.", + required=False, + ), + ), + ( + "link_page", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to.", required=False + ), + ), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that the header should link out to.", + required=False, + ), + ), + ] + ), + max_num=4, + min_num=1, + ), + ), + ("link_url", wagtail.blocks.URLBlock(required=False)), + ("link_text", wagtail.blocks.CharBlock(max_length=50, required=False)), + ] + ), + ), + ], + use_json_field=True, + ), + ), + MigrateStreamData( + app_name="mozfest", + model_name="mozfestprimarypage", + field_name="body", + operations_and_block_paths=[ + (AlterStreamChildBlockDataOperation(block="video", operation=migrate_video_block), ""), + ], + ), + migrations.AlterField( + model_name="mozfestprimarypage", + name="body", + field=wagtail.fields.StreamField( + [ + ( + "paragraph", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + "large", + ], + template="wagtailpages/blocks/rich_text_block.html", + ), + ), + ( + "card_grid", + wagtail.blocks.StructBlock( + [ + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ("body", wagtail.blocks.TextBlock(help_text="Body text of the card.")), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that this card should link out to. (Note: If left blank, link will not render.) ", + required=False, + ), + ), + ( + "link_label", + wagtail.blocks.CharBlock( + help_text="Optional Label for the URL link above. (Note: If left blank, link will not render.) ", + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + ), + ) + ] + ), + ), + ( + "image", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "image_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide images are col-12, Full-Width Images reach both ends of the screen (16:6 images recommended for full width)", + ), + ), + ] + ), + ), + ( + "image_text", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ( + "text", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + ] + ), + ), + ( + "url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this image should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ] + ), + ), + ( + "image_text_mini", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ("text", wagtail.blocks.RichTextBlock(features=["bold", "italic", "link"])), + ] + ), + ), + ( + "image_grid", + wagtail.blocks.StructBlock( + [ + ( + "grid_items", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for this image.", required=False + ), + ), + ( + "caption", + wagtail.blocks.CharBlock( + help_text="Please remember to properly attribute any images we use.", + required=False, + ), + ), + ( + "url", + wagtail.blocks.CharBlock( + help_text="Optional URL that this figure should link out to.", + required=False, + ), + ), + ( + "square_image", + wagtail.blocks.BooleanBlock( + default=True, + help_text="If left checked, the image will be cropped to be square.", + required=False, + ), + ), + ] + ) + ), + ) + ] + ), + ), + ( + "video", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="For YouTube: go to your YouTube video and click “Share,” then “Embed,” and then copy and paste the provided URL only. For example: https://www.youtube.com/embed/3FIVXBawyQw For Vimeo: follow similar steps to grab the embed URL. For example: https://player.vimeo.com/video/9004979", + label="Embed URL", + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "video_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide videos are col-12, Full-Width videos reach both ends of the screen.", + ), + ), + ] + ), + ), + ( + "iframe", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.CharBlock( + help_text="Please note that only URLs from allow-listed domains will work." + ), + ), + ( + "height", + wagtail.blocks.IntegerBlock( + help_text="Optional integer pixel value for custom iFrame height", + required=False, + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "iframe_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide iframes are col-12, Full-Width iframes reach both ends of the screen", + ), + ), + ( + "disable_scroll", + wagtail.blocks.BooleanBlock( + default=False, + help_text='Checking this will add "scrolling=no" to the iframe. Use this if your iframe is rendering an unnecessary scroll bar or whitespace below it.', + required=False, + ), + ), + ] + ), + ), + ( + "linkbutton", + 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"', + 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), + ), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ] + ), + ), + ( + "spacer", + wagtail.blocks.StructBlock( + [ + ( + "size", + wagtail.blocks.ChoiceBlock( + choices=[ + ("1", "quarter spacing"), + ("2", "half spacing"), + ("3", "single spacing"), + ("4", "one and a half spacing"), + ("5", "triple spacing"), + ] + ), + ) + ] + ), + ), + ( + "single_quote", + wagtail.blocks.StructBlock( + [ + ("quote", wagtail.blocks.RichTextBlock(features=["bold"])), + ("attribution", wagtail.blocks.CharBlock(required=False)), + ( + "attribution_info", + wagtail.blocks.RichTextBlock(features=["bold", "link", "large"], required=False), + ), + ] + ), + ), + ( + "profile_by_id", + wagtail.blocks.StructBlock( + [ + ( + "ids", + wagtail.blocks.CharBlock( + help_text="Show profiles for pulse users with specific profile ids (mozillapulse.org/profile/[##]). For multiple profiles, specify a comma separated list (e.g. 85,105,332).", + label="Profile by ID", + ), + ) + ] + ), + ), + ( + "profile_directory", + wagtail.blocks.StructBlock( + [ + ( + "max_number_of_results", + wagtail.blocks.IntegerBlock( + default=12, + help_text="Pick up to 48 profiles.", + max_value=48, + min_value=1, + required=True, + ), + ), + ( + "advanced_filter_header", + wagtail.blocks.static_block.StaticBlock( + admin_text="-------- ADVANCED FILTERS: OPTIONS TO DISPLAY FEWER, MORE TARGETED RESULTS. --------", + label=" ", + ), + ), + ( + "profile_type", + wagtail.blocks.CharBlock(default="", help_text="Example: Fellow.", required=False), + ), + ( + "program_type", + wagtail.blocks.CharBlock( + default="", help_text="Example: Tech Policy.", required=False + ), + ), + ("year", wagtail.blocks.CharBlock(default="", required=False)), + ( + "filter_values", + wagtail.blocks.CharBlock( + default="2019,2018,2017,2016,2015,2014,2013", + help_text="Example: 2019,2018,2017,2016,2015,2014,2013", + required=True, + ), + ), + ] + ), + ), + ( + "recent_blog_entries", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock(required=False)), + ( + "tag_filter", + wagtail.blocks.CharBlock( + help_text="Test this filter at foundation.mozilla.org/blog/tags/", + label="Filter by Tag", + required=False, + ), + ), + ( + "topic_filter", + wagtail.blocks.ChoiceBlock( + choices=networkapi.wagtailpages.pagemodels.blog.blog_topic.BlogPageTopic.get_topics, + help_text="Test this filter at foundation.mozilla.org/blog/topic/", + label="Filter by Topic", + required=False, + ), + ), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ] + ), + ), + ( + "blog_set", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock()), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ( + "blog_pages", + wagtail.blocks.ListBlock( + wagtail.blocks.PageChooserBlock(page_type=["wagtailpages.BlogPage"]) + ), + ), + ] + ), + ), + ( + "datawrapper", + wagtail.embeds.blocks.EmbedBlock( + help_text='Enter the "visualization only" link of the Datawrapper chart. It looks something like this: https://datawrapper.dwcdn.net/KwSKp/1/', + icon="image", + template="wagtailpages/blocks/datawrapper_block.html", + ), + ), + ( + "listing", + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock(help_text="Heading for the block.", required=False), + ), + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ( + "highlighted_metadata", + wagtail.blocks.CharBlock( + help_text="Metadata to highlight on the card.", required=False + ), + ), + ( + "metadata", + wagtail.blocks.CharBlock( + help_text="Generic metadata.", required=False + ), + ), + ( + "body", + wagtail.blocks.RichTextBlock( + features=["bold"], + help_text="Body text of the card.", + required=False, + ), + ), + ( + "link_page", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to.", required=False + ), + ), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that the header should link out to.", + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + min_num=2, + ), + ), + ( + "cards_per_row", + wagtail.blocks.ChoiceBlock( + choices=[(2, "2"), (3, "3")], + help_text="Number of cards per row. Note: this is a max and fewer might be used if is less space is available.", + required=False, + ), + ), + ] + ), + ), + ( + "profiles", + wagtail.blocks.StructBlock( + [ + ( + "profiles", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "profile", + wagtail.snippets.blocks.SnippetChooserBlock( + networkapi.wagtailpages.pagemodels.profiles.Profile + ), + ) + ] + ), + min_num=1, + ), + ) + ] + ), + ), + ( + "group_listing_block", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the group of cards.", required=False + ), + ), + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ( + "meta_data", + wagtail.blocks.CharBlock( + help_text="Optional meta data information for the card.", + required=False, + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ( + "body", + wagtail.blocks.RichTextBlock( + features=["bold", "link"], help_text="Body text of the card." + ), + ), + ( + "url", + wagtail.blocks.CharBlock( + help_text="The URL this card should link to.", required=False + ), + ), + ] + ) + ), + ), + ] + ), + ), + ( + "image_feature", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock(help_text="Image description (for screen readers)."), + ), + ("metadata", wagtail.blocks.CharBlock(required=False)), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ( + "title_link", + wagtail.blocks.PageChooserBlock( + help_text="Page that the title should link out to.", required=False + ), + ), + ("body", wagtail.blocks.CharBlock(required=False)), + ] + ), + ), + ( + "image_teaser_block", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ("text", wagtail.blocks.RichTextBlock(features=["bold"])), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ("url_label", wagtail.blocks.CharBlock(required=False)), + ("url", wagtail.blocks.CharBlock(required=False)), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ] + ), + ), + ( + "text_only_teaser", + wagtail.blocks.StructBlock( + [ + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock(help_text="Heading for the card."), + ), + ( + "link_page", + wagtail.blocks.PageChooserBlock( + help_text="Page that the header should link out to.", + required=False, + ), + ), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that the header should link out to.", + required=False, + ), + ), + ("meta_data", wagtail.blocks.CharBlock(max_length=500)), + ( + "body", + wagtail.blocks.TextBlock( + help_text="Body text of the card.", + max_length=200, + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 3 cards.", + min_num=3, + ), + ) + ] + ), + ), + ( + "block_with_aside", + wagtail.blocks.StructBlock( + [ + ( + "content", + wagtail.blocks.StreamBlock( + [ + ( + "listing", + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock( + help_text="Heading for the block.", required=False + ), + ), + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "image", + wagtail.images.blocks.ImageChooserBlock(), + ), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", + required=False, + ), + ), + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the card." + ), + ), + ( + "highlighted_metadata", + wagtail.blocks.CharBlock( + help_text="Metadata to highlight on the card.", + required=False, + ), + ), + ( + "metadata", + wagtail.blocks.CharBlock( + help_text="Generic metadata.", + required=False, + ), + ), + ( + "body", + wagtail.blocks.RichTextBlock( + features=["bold"], + help_text="Body text of the card.", + required=False, + ), + ), + ( + "link_page", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to.", + required=False, + ), + ), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that the header should link out to.", + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + min_num=2, + ), + ), + ( + "cards_per_row", + wagtail.blocks.ChoiceBlock( + choices=[(2, "2"), (3, "3")], + help_text="Number of cards per row. Note: this is a max and fewer might be used if is less space is available.", + required=False, + ), + ), + ] + ), + ), + ( + "paragraph", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + ] + ), + ), + ], + help_text="The wider block that appears on the left on desktop", + icon="doc-full", + max_num=1, + ), + ), + ( + "aside", + wagtail.blocks.StreamBlock( + [ + ( + "aside_content", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the card.", required=False + ), + ), + ( + "body", + wagtail.blocks.TextBlock( + help_text="Body text of the card.", required=False + ), + ), + ] + ), + ), + ( + "linkbutton", + 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"', + 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 + ), + ), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ] + ), + ), + ( + "spacer", + wagtail.blocks.StructBlock( + [ + ( + "size", + wagtail.blocks.ChoiceBlock( + choices=[ + ("1", "quarter spacing"), + ("2", "half spacing"), + ("3", "single spacing"), + ("4", "one and a half spacing"), + ("5", "triple spacing"), + ] + ), + ) + ] + ), + ), + ], + help_text="Elements here will appear in the column on the right side of the page on desktop. This can be left blank if you would just like a 2/3 column on the left", + icon="doc-full", + required=False, + ), + ), + ] + ), + ), + ( + "accordion", + wagtail.blocks.StructBlock( + [ + ( + "accordion_items", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the Accordion Item" + ), + ), + ( + "content", + wagtail.blocks.StreamBlock( + [ + ( + "rich_text", + wagtail.blocks.RichTextBlock( + blank=True, + features=[ + "bold", + "italic", + "link", + "ul", + "ol", + "document-link", + ], + ), + ), + ( + "datawrapper", + wagtail.embeds.blocks.EmbedBlock( + help_text='Enter the "visualization only" link of the Datawrapper chart. It looks something like this: https://datawrapper.dwcdn.net/KwSKp/1/', + icon="image", + template="wagtailpages/blocks/datawrapper_block.html", + ), + ), + ( + "image", + wagtail.blocks.StructBlock( + [ + ( + "image", + wagtail.images.blocks.ImageChooserBlock(), + ), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", + required=True, + ), + ), + ] + ), + ), + ( + "video", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="For YouTube: go to your YouTube video and click “Share,” then “Embed,” and then copy and paste the provided URL only. For example: https://www.youtube.com/embed/3FIVXBawyQw For Vimeo: follow similar steps to grab the embed URL. For example: https://player.vimeo.com/video/9004979", + label="Embed URL", + ), + ), + ( + "caption", + wagtail.blocks.CharBlock(required=False), + ), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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, + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "video_width", + wagtail.blocks.ChoiceBlock( + choices=[ + ("normal", "Normal"), + ("wide", "Wide"), + ("full_width", "Full Width"), + ], + help_text="Wide videos are col-12, Full-Width videos reach both ends of the screen.", + ), + ), + ] + ), + ), + ] + ), + ), + ] + ) + ), + ) + ] + ), + ), + ( + "session_slider", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock(help_text="Heading for the slider.")), + ( + "session_items", + wagtail.blocks.StreamBlock( + [ + ( + "session_item", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the card." + ), + ), + ( + "author_subheading", + wagtail.blocks.CharBlock( + help_text="Author of this session.", required=False + ), + ), + ( + "image", + wagtail.images.blocks.ImageChooserBlock( + help_text="The image associated with this session." + ), + ), + ( + "body", + wagtail.blocks.RichTextBlock( + help_text="Body text of this card." + ), + ), + ( + "video", + wagtailmedia.blocks.VideoChooserBlock( + help_text="Video that will autoplay when this card is hovered on", + required=False, + ), + ), + ( + "link", + wagtail.blocks.StreamBlock( + [ + ( + "internal", + wagtail.blocks.StructBlock( + [ + ( + "link", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to." + ), + ) + ] + ), + ), + ( + "external", + wagtail.blocks.StructBlock( + [ + ( + "link", + wagtail.blocks.URLBlock( + help_text="URL that this should link out to." + ), + ) + ] + ), + ), + ], + help_text="Page or external URL this card will link out to.", + max_num=1, + ), + ), + ] + ), + ) + ], + help_text="A list of sessions in the slider.", + ), + ), + ( + "button", + wagtail.blocks.StreamBlock( + [ + ( + "internal", + wagtail.blocks.StructBlock( + [ + ( + "label", + wagtail.blocks.CharBlock(help_text="Label for this link."), + ), + ( + "link", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to." + ), + ), + ] + ), + ), + ( + "external", + wagtail.blocks.StructBlock( + [ + ( + "label", + wagtail.blocks.CharBlock(help_text="Label for this link."), + ), + ( + "link", + wagtail.blocks.URLBlock( + help_text="URL that this should link out to." + ), + ), + ] + ), + ), + ], + help_text="Button that appears below the slider.", + max_num=1, + required=False, + ), + ), + ] + ), + ), + ( + "current_events_slider", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock(help_text="Heading for the slider.")), + ( + "current_events", + wagtail.blocks.StreamBlock( + [ + ( + "current_event", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock(help_text="Heading of the card."), + ), + ( + "subheading_link", + wagtail.blocks.StreamBlock( + [ + ( + "internal", + wagtail.blocks.StructBlock( + [ + ( + "label", + wagtail.blocks.CharBlock( + help_text="Label for this link." + ), + ), + ( + "link", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to." + ), + ), + ] + ), + ), + ( + "external", + wagtail.blocks.StructBlock( + [ + ( + "label", + wagtail.blocks.CharBlock( + help_text="Label for this link." + ), + ), + ( + "link", + wagtail.blocks.URLBlock( + help_text="URL that this should link out to." + ), + ), + ] + ), + ), + ], + help_text="The link that appears below the card heading.", + max_num=1, + required=False, + ), + ), + ( + "image", + wagtail.images.blocks.ImageChooserBlock( + help_text="The image associated with this event." + ), + ), + ( + "body", + wagtail.blocks.TextBlock( + help_text="Body text of the card." + ), + ), + ( + "buttons", + wagtail.blocks.StreamBlock( + [ + ( + "internal", + wagtail.blocks.StructBlock( + [ + ( + "label", + wagtail.blocks.CharBlock( + help_text="Label for this link." + ), + ), + ( + "link", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to." + ), + ), + ] + ), + ), + ( + "external", + wagtail.blocks.StructBlock( + [ + ( + "label", + wagtail.blocks.CharBlock( + help_text="Label for this link." + ), + ), + ( + "link", + wagtail.blocks.URLBlock( + help_text="URL that this should link out to." + ), + ), + ] + ), + ), + ( + "document", + wagtail.blocks.StructBlock( + [ + ( + "label", + wagtail.blocks.CharBlock( + help_text="Label for this link." + ), + ), + ( + "document", + wagtail.documents.blocks.DocumentChooserBlock( + help_text="Document that this should link out to." + ), + ), + ], + help_text='An iCal document can be attached here for an "Add to Calendar" button.', + ), + ), + ], + help_text="A list of buttons that will appear at the bottom of the card.", + max_num=2, + ), + ), + ] + ), + ) + ], + help_text="A list of current events in the slider.", + ), + ), + ] + ), + ), + ( + "spaces", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock()), + ( + "cards", + wagtail.blocks.StreamBlock( + [ + ( + "space_card", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the card." + ), + ), + ( + "body", + wagtail.blocks.TextBlock( + help_text="Body text of the card." + ), + ), + ( + "link", + wagtail.blocks.StreamBlock( + [ + ( + "internal", + wagtail.blocks.StructBlock( + [ + ( + "link", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to." + ), + ) + ] + ), + ), + ( + "external", + wagtail.blocks.StructBlock( + [ + ( + "link", + wagtail.blocks.URLBlock( + help_text="URL that this should link out to." + ), + ) + ] + ), + ), + ], + help_text="Page or external URL this card will link out to.", + max_num=1, + ), + ), + ] + ), + ) + ], + help_text="A list of Spaces Cards.", + ), + ), + ] + ), + ), + ( + "tito_widget", + wagtail.blocks.StructBlock( + [ + ( + "button_label", + wagtail.blocks.CharBlock(help_text="The text to show on the Tito button."), + ), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ( + "event", + wagtail.snippets.blocks.SnippetChooserBlock( + "events.TitoEvent", help_event="The Tito event to be displayed" + ), + ), + ( + "releases", + wagtail.blocks.CharBlock( + help_text='Comma-separated list of ticket/release IDs to limit to, e.g. "3elajg6qcxu,6qiiw4socs4"', + required=False, + ), + ), + ] + ), + ), + ( + "statistics", + wagtail.blocks.StructBlock( + [ + ( + "statistics", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="The statistic figure, e.g '1000+' or '10%'" + ), + ), + ( + "description", + wagtail.blocks.CharBlock( + help_text="Context or description for the statistic" + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + max_num=4, + min_num=2, + ), + ) + ] + ), + ), + ( + "carousel_and_text", + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock(help_text="Heading for the block.", required=False), + ), + ("text", wagtail.blocks.RichTextBlock(features=["bold", "italic", "link"])), + ( + "link_url", + wagtail.blocks.URLBlock( + help_text="A CTA URL for a link displayed", required=False + ), + ), + ( + "link_label", + wagtail.blocks.CharBlock(help_text="Label for the CTA link.", required=False), + ), + ( + "carousel_images", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", + required=True, + ), + ), + ] + ), + max_num=4, + ), + ), + ] + ), + ), + ( + "tickets", + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock(help_text="Heading for the block.", required=False), + ), + ( + "tickets", + wagtail.blocks.ListBlock( + wagtail.snippets.blocks.SnippetChooserBlock("mozfest.Ticket"), max_num=3 + ), + ), + ] + ), + ), + ( + "dark_quote", + wagtail.blocks.StructBlock( + [ + ("quote", wagtail.blocks.RichTextBlock(features=["bold"])), + ("attribution", wagtail.blocks.CharBlock(required=False)), + ( + "attribution_info", + wagtail.blocks.RichTextBlock(features=["bold", "link", "large"], required=False), + ), + ] + ), + ), + ( + "cta", + 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"', + 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), + ), + ("heading", wagtail.blocks.CharBlock(required=False)), + ("text", wagtail.blocks.CharBlock(required=False)), + ("dark_background", wagtail.blocks.BooleanBlock(required=False)), + ] + ), + ), + ( + "newsletter_signup", + wagtail.blocks.StructBlock( + [ + ( + "snippet", + wagtail.snippets.blocks.SnippetChooserBlock( + "mozfest.NewsletterSignupWithBackground" + ), + ) + ] + ), + ), + ( + "mixed_content", + wagtail.blocks.StructBlock( + [ + ( + "video", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="For YouTube: go to your YouTube video and click “Share,” then “Embed,” and then copy and paste the provided URL only. For example: https://www.youtube.com/embed/3FIVXBawyQw For Vimeo: follow similar steps to grab the embed URL. For example: https://player.vimeo.com/video/9004979", + label="Embed URL", + ), + ), + ( + "caption", + wagtail.blocks.CharBlock( + help_text="Optional caption for the video, displayed next to the play button.", + max_length=25, + required=False, + ), + ), + ( + "title", + wagtail.blocks.CharBlock( + help_text="Optional title for the video.", + max_length=50, + required=False, + ), + ), + ( + "text", + wagtail.blocks.CharBlock( + help_text="Text content to display with the video title.", + required=False, + ), + ), + ( + "thumbnail", + wagtail.images.blocks.ImageChooserBlock( + help_text="The image to show before the video is played." + ), + ), + ] + ), + ), + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ( + "highlighted_metadata", + wagtail.blocks.CharBlock( + help_text="Metadata to highlight on the card.", required=False + ), + ), + ( + "metadata", + wagtail.blocks.CharBlock( + help_text="Generic metadata.", required=False + ), + ), + ( + "body", + wagtail.blocks.RichTextBlock( + features=["bold"], + help_text="Body text of the card.", + required=False, + ), + ), + ( + "link_page", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to.", required=False + ), + ), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that the header should link out to.", + required=False, + ), + ), + ] + ), + max_num=4, + min_num=1, + ), + ), + ("link_url", wagtail.blocks.URLBlock(required=False)), + ("link_text", wagtail.blocks.CharBlock(max_length=50, required=False)), + ] + ), + ), + ], + use_json_field=True, + ), + ), + ] diff --git a/network-api/networkapi/mozfest/migrations/0056_update_imageteaserblock_with_linkblock.py b/network-api/networkapi/mozfest/migrations/0056_update_imageteaserblock_with_linkblock.py new file mode 100644 index 00000000000..538bc82d26f --- /dev/null +++ b/network-api/networkapi/mozfest/migrations/0056_update_imageteaserblock_with_linkblock.py @@ -0,0 +1,4630 @@ +# Generated by Django 4.2.14 on 2024-07-15 23:38 + +import wagtail.blocks +import wagtail.blocks.static_block +import wagtail.documents.blocks +import wagtail.embeds.blocks +import wagtail.fields +import wagtail.images.blocks +import wagtail.snippets.blocks +import wagtailmedia.blocks +from django.db import migrations +from wagtail.blocks.migrations.migrate_operation import MigrateStreamData + +import networkapi.wagtailpages.pagemodels.blog.blog_topic +import networkapi.wagtailpages.pagemodels.profiles +import networkapi.wagtailpages.validators +from networkapi.utility.migration.operations import AlterStreamChildBlockDataOperation + + +def migrate_image_teaser_block(source_block): + new_value = { + "title": source_block["value"].get("title", ""), + "text": source_block["value"].get("text", ""), + "image": source_block["value"].get("image"), + "altText": source_block["value"].get("altText", ""), + "link": [], + "styling": source_block["value"].get("styling", "btn-primary"), + "top_divider": source_block["value"].get("top_divider", False), + "bottom_divider": source_block["value"].get("bottom_divider", False), + } + if "url" in source_block["value"] and source_block["value"]["url"]: + new_value["link_button"] = [ + { + "link_to": "external_url", + "external_url": source_block["value"]["url"], + "label": source_block["value"].get("url_label", ""), + "new_window": True, + "styling": source_block["value"].get("styling", "btn-primary"), + } + ] + return { + **source_block, + "value": new_value, + } + + +class Migration(migrations.Migration): + + dependencies = [ + ("mozfest", "0055_update_videoblock_with_linkblock"), + ] + + operations = [ + migrations.AlterField( + model_name="mozfestprimarypage", + name="body", + field=wagtail.fields.StreamField( + [ + ( + "paragraph", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + "large", + ], + template="wagtailpages/blocks/rich_text_block.html", + ), + ), + ( + "card_grid", + wagtail.blocks.StructBlock( + [ + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ("body", wagtail.blocks.TextBlock(help_text="Body text of the card.")), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that this card should link out to. (Note: If left blank, link will not render.) ", + required=False, + ), + ), + ( + "link_label", + wagtail.blocks.CharBlock( + help_text="Optional Label for the URL link above. (Note: If left blank, link will not render.) ", + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + ), + ) + ] + ), + ), + ( + "image", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "image_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide images are col-12, Full-Width Images reach both ends of the screen (16:6 images recommended for full width)", + ), + ), + ] + ), + ), + ( + "image_text", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ( + "text", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + ] + ), + ), + ( + "url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this image should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ] + ), + ), + ( + "image_text_mini", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ("text", wagtail.blocks.RichTextBlock(features=["bold", "italic", "link"])), + ] + ), + ), + ( + "image_grid", + wagtail.blocks.StructBlock( + [ + ( + "grid_items", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for this image.", required=False + ), + ), + ( + "caption", + wagtail.blocks.CharBlock( + help_text="Please remember to properly attribute any images we use.", + required=False, + ), + ), + ( + "url", + wagtail.blocks.CharBlock( + help_text="Optional URL that this figure should link out to.", + required=False, + ), + ), + ( + "square_image", + wagtail.blocks.BooleanBlock( + default=True, + help_text="If left checked, the image will be cropped to be square.", + required=False, + ), + ), + ] + ) + ), + ) + ] + ), + ), + ( + "video", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="For YouTube: go to your YouTube video and click “Share,” then “Embed,” and then copy and paste the provided URL only. For example: https://www.youtube.com/embed/3FIVXBawyQw For Vimeo: follow similar steps to grab the embed URL. For example: https://player.vimeo.com/video/9004979", + label="Embed URL", + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "video_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide videos are col-12, Full-Width videos reach both ends of the screen.", + ), + ), + ] + ), + ), + ( + "iframe", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.CharBlock( + help_text="Please note that only URLs from allow-listed domains will work." + ), + ), + ( + "height", + wagtail.blocks.IntegerBlock( + help_text="Optional integer pixel value for custom iFrame height", + required=False, + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "iframe_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide iframes are col-12, Full-Width iframes reach both ends of the screen", + ), + ), + ( + "disable_scroll", + wagtail.blocks.BooleanBlock( + default=False, + help_text='Checking this will add "scrolling=no" to the iframe. Use this if your iframe is rendering an unnecessary scroll bar or whitespace below it.', + required=False, + ), + ), + ] + ), + ), + ( + "linkbutton", + 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"', + 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), + ), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ] + ), + ), + ( + "spacer", + wagtail.blocks.StructBlock( + [ + ( + "size", + wagtail.blocks.ChoiceBlock( + choices=[ + ("1", "quarter spacing"), + ("2", "half spacing"), + ("3", "single spacing"), + ("4", "one and a half spacing"), + ("5", "triple spacing"), + ] + ), + ) + ] + ), + ), + ( + "single_quote", + wagtail.blocks.StructBlock( + [ + ("quote", wagtail.blocks.RichTextBlock(features=["bold"])), + ("attribution", wagtail.blocks.CharBlock(required=False)), + ( + "attribution_info", + wagtail.blocks.RichTextBlock(features=["bold", "link", "large"], required=False), + ), + ] + ), + ), + ( + "profile_by_id", + wagtail.blocks.StructBlock( + [ + ( + "ids", + wagtail.blocks.CharBlock( + help_text="Show profiles for pulse users with specific profile ids (mozillapulse.org/profile/[##]). For multiple profiles, specify a comma separated list (e.g. 85,105,332).", + label="Profile by ID", + ), + ) + ] + ), + ), + ( + "profile_directory", + wagtail.blocks.StructBlock( + [ + ( + "max_number_of_results", + wagtail.blocks.IntegerBlock( + default=12, + help_text="Pick up to 48 profiles.", + max_value=48, + min_value=1, + required=True, + ), + ), + ( + "advanced_filter_header", + wagtail.blocks.static_block.StaticBlock( + admin_text="-------- ADVANCED FILTERS: OPTIONS TO DISPLAY FEWER, MORE TARGETED RESULTS. --------", + label=" ", + ), + ), + ( + "profile_type", + wagtail.blocks.CharBlock(default="", help_text="Example: Fellow.", required=False), + ), + ( + "program_type", + wagtail.blocks.CharBlock( + default="", help_text="Example: Tech Policy.", required=False + ), + ), + ("year", wagtail.blocks.CharBlock(default="", required=False)), + ( + "filter_values", + wagtail.blocks.CharBlock( + default="2019,2018,2017,2016,2015,2014,2013", + help_text="Example: 2019,2018,2017,2016,2015,2014,2013", + required=True, + ), + ), + ] + ), + ), + ( + "recent_blog_entries", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock(required=False)), + ( + "tag_filter", + wagtail.blocks.CharBlock( + help_text="Test this filter at foundation.mozilla.org/blog/tags/", + label="Filter by Tag", + required=False, + ), + ), + ( + "topic_filter", + wagtail.blocks.ChoiceBlock( + choices=networkapi.wagtailpages.pagemodels.blog.blog_topic.BlogPageTopic.get_topics, + help_text="Test this filter at foundation.mozilla.org/blog/topic/", + label="Filter by Topic", + required=False, + ), + ), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ] + ), + ), + ( + "blog_set", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock()), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ( + "blog_pages", + wagtail.blocks.ListBlock( + wagtail.blocks.PageChooserBlock(page_type=["wagtailpages.BlogPage"]) + ), + ), + ] + ), + ), + ( + "datawrapper", + wagtail.embeds.blocks.EmbedBlock( + help_text='Enter the "visualization only" link of the Datawrapper chart. It looks something like this: https://datawrapper.dwcdn.net/KwSKp/1/', + icon="image", + template="wagtailpages/blocks/datawrapper_block.html", + ), + ), + ( + "listing", + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock(help_text="Heading for the block.", required=False), + ), + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ( + "highlighted_metadata", + wagtail.blocks.CharBlock( + help_text="Metadata to highlight on the card.", required=False + ), + ), + ( + "metadata", + wagtail.blocks.CharBlock( + help_text="Generic metadata.", required=False + ), + ), + ( + "body", + wagtail.blocks.RichTextBlock( + features=["bold"], + help_text="Body text of the card.", + required=False, + ), + ), + ( + "link_page", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to.", required=False + ), + ), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that the header should link out to.", + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + min_num=2, + ), + ), + ( + "cards_per_row", + wagtail.blocks.ChoiceBlock( + choices=[(2, "2"), (3, "3")], + help_text="Number of cards per row. Note: this is a max and fewer might be used if is less space is available.", + required=False, + ), + ), + ] + ), + ), + ( + "profiles", + wagtail.blocks.StructBlock( + [ + ( + "profiles", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "profile", + wagtail.snippets.blocks.SnippetChooserBlock( + networkapi.wagtailpages.pagemodels.profiles.Profile + ), + ) + ] + ), + min_num=1, + ), + ) + ] + ), + ), + ( + "group_listing_block", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the group of cards.", required=False + ), + ), + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ( + "meta_data", + wagtail.blocks.CharBlock( + help_text="Optional meta data information for the card.", + required=False, + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ( + "body", + wagtail.blocks.RichTextBlock( + features=["bold", "link"], help_text="Body text of the card." + ), + ), + ( + "url", + wagtail.blocks.CharBlock( + help_text="The URL this card should link to.", required=False + ), + ), + ] + ) + ), + ), + ] + ), + ), + ( + "image_feature", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock(help_text="Image description (for screen readers)."), + ), + ("metadata", wagtail.blocks.CharBlock(required=False)), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ( + "title_link", + wagtail.blocks.PageChooserBlock( + help_text="Page that the title should link out to.", required=False + ), + ), + ("body", wagtail.blocks.CharBlock(required=False)), + ] + ), + ), + ( + "image_teaser_block", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ("text", wagtail.blocks.RichTextBlock(features=["bold"])), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ("url_label", wagtail.blocks.CharBlock(required=False)), + ("url", wagtail.blocks.CharBlock(required=False)), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ( + "link_button", + wagtail.blocks.ListBlock( + 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"', + 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 + ), + ), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ] + ), + help_text="Optional link button", + max_num=1, + min_num=0, + ), + ), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ] + ), + ), + ( + "text_only_teaser", + wagtail.blocks.StructBlock( + [ + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock(help_text="Heading for the card."), + ), + ( + "link_page", + wagtail.blocks.PageChooserBlock( + help_text="Page that the header should link out to.", + required=False, + ), + ), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that the header should link out to.", + required=False, + ), + ), + ("meta_data", wagtail.blocks.CharBlock(max_length=500)), + ( + "body", + wagtail.blocks.TextBlock( + help_text="Body text of the card.", + max_length=200, + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 3 cards.", + min_num=3, + ), + ) + ] + ), + ), + ( + "block_with_aside", + wagtail.blocks.StructBlock( + [ + ( + "content", + wagtail.blocks.StreamBlock( + [ + ( + "listing", + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock( + help_text="Heading for the block.", required=False + ), + ), + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "image", + wagtail.images.blocks.ImageChooserBlock(), + ), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", + required=False, + ), + ), + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the card." + ), + ), + ( + "highlighted_metadata", + wagtail.blocks.CharBlock( + help_text="Metadata to highlight on the card.", + required=False, + ), + ), + ( + "metadata", + wagtail.blocks.CharBlock( + help_text="Generic metadata.", + required=False, + ), + ), + ( + "body", + wagtail.blocks.RichTextBlock( + features=["bold"], + help_text="Body text of the card.", + required=False, + ), + ), + ( + "link_page", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to.", + required=False, + ), + ), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that the header should link out to.", + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + min_num=2, + ), + ), + ( + "cards_per_row", + wagtail.blocks.ChoiceBlock( + choices=[(2, "2"), (3, "3")], + help_text="Number of cards per row. Note: this is a max and fewer might be used if is less space is available.", + required=False, + ), + ), + ] + ), + ), + ( + "paragraph", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + ] + ), + ), + ], + help_text="The wider block that appears on the left on desktop", + icon="doc-full", + max_num=1, + ), + ), + ( + "aside", + wagtail.blocks.StreamBlock( + [ + ( + "aside_content", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the card.", required=False + ), + ), + ( + "body", + wagtail.blocks.TextBlock( + help_text="Body text of the card.", required=False + ), + ), + ] + ), + ), + ( + "linkbutton", + 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"', + 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 + ), + ), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ] + ), + ), + ( + "spacer", + wagtail.blocks.StructBlock( + [ + ( + "size", + wagtail.blocks.ChoiceBlock( + choices=[ + ("1", "quarter spacing"), + ("2", "half spacing"), + ("3", "single spacing"), + ("4", "one and a half spacing"), + ("5", "triple spacing"), + ] + ), + ) + ] + ), + ), + ], + help_text="Elements here will appear in the column on the right side of the page on desktop. This can be left blank if you would just like a 2/3 column on the left", + icon="doc-full", + required=False, + ), + ), + ] + ), + ), + ( + "accordion", + wagtail.blocks.StructBlock( + [ + ( + "accordion_items", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the Accordion Item" + ), + ), + ( + "content", + wagtail.blocks.StreamBlock( + [ + ( + "rich_text", + wagtail.blocks.RichTextBlock( + blank=True, + features=[ + "bold", + "italic", + "link", + "ul", + "ol", + "document-link", + ], + ), + ), + ( + "datawrapper", + wagtail.embeds.blocks.EmbedBlock( + help_text='Enter the "visualization only" link of the Datawrapper chart. It looks something like this: https://datawrapper.dwcdn.net/KwSKp/1/', + icon="image", + template="wagtailpages/blocks/datawrapper_block.html", + ), + ), + ( + "image", + wagtail.blocks.StructBlock( + [ + ( + "image", + wagtail.images.blocks.ImageChooserBlock(), + ), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", + required=True, + ), + ), + ] + ), + ), + ( + "video", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="For YouTube: go to your YouTube video and click “Share,” then “Embed,” and then copy and paste the provided URL only. For example: https://www.youtube.com/embed/3FIVXBawyQw For Vimeo: follow similar steps to grab the embed URL. For example: https://player.vimeo.com/video/9004979", + label="Embed URL", + ), + ), + ( + "caption", + wagtail.blocks.CharBlock(required=False), + ), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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, + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "video_width", + wagtail.blocks.ChoiceBlock( + choices=[ + ("normal", "Normal"), + ("wide", "Wide"), + ("full_width", "Full Width"), + ], + help_text="Wide videos are col-12, Full-Width videos reach both ends of the screen.", + ), + ), + ] + ), + ), + ] + ), + ), + ] + ) + ), + ) + ] + ), + ), + ( + "session_slider", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock(help_text="Heading for the slider.")), + ( + "session_items", + wagtail.blocks.StreamBlock( + [ + ( + "session_item", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the card." + ), + ), + ( + "author_subheading", + wagtail.blocks.CharBlock( + help_text="Author of this session.", required=False + ), + ), + ( + "image", + wagtail.images.blocks.ImageChooserBlock( + help_text="The image associated with this session." + ), + ), + ( + "body", + wagtail.blocks.RichTextBlock( + help_text="Body text of this card." + ), + ), + ( + "video", + wagtailmedia.blocks.VideoChooserBlock( + help_text="Video that will autoplay when this card is hovered on", + required=False, + ), + ), + ( + "link", + wagtail.blocks.StreamBlock( + [ + ( + "internal", + wagtail.blocks.StructBlock( + [ + ( + "link", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to." + ), + ) + ] + ), + ), + ( + "external", + wagtail.blocks.StructBlock( + [ + ( + "link", + wagtail.blocks.URLBlock( + help_text="URL that this should link out to." + ), + ) + ] + ), + ), + ], + help_text="Page or external URL this card will link out to.", + max_num=1, + ), + ), + ] + ), + ) + ], + help_text="A list of sessions in the slider.", + ), + ), + ( + "button", + wagtail.blocks.StreamBlock( + [ + ( + "internal", + wagtail.blocks.StructBlock( + [ + ( + "label", + wagtail.blocks.CharBlock(help_text="Label for this link."), + ), + ( + "link", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to." + ), + ), + ] + ), + ), + ( + "external", + wagtail.blocks.StructBlock( + [ + ( + "label", + wagtail.blocks.CharBlock(help_text="Label for this link."), + ), + ( + "link", + wagtail.blocks.URLBlock( + help_text="URL that this should link out to." + ), + ), + ] + ), + ), + ], + help_text="Button that appears below the slider.", + max_num=1, + required=False, + ), + ), + ] + ), + ), + ( + "current_events_slider", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock(help_text="Heading for the slider.")), + ( + "current_events", + wagtail.blocks.StreamBlock( + [ + ( + "current_event", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock(help_text="Heading of the card."), + ), + ( + "subheading_link", + wagtail.blocks.StreamBlock( + [ + ( + "internal", + wagtail.blocks.StructBlock( + [ + ( + "label", + wagtail.blocks.CharBlock( + help_text="Label for this link." + ), + ), + ( + "link", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to." + ), + ), + ] + ), + ), + ( + "external", + wagtail.blocks.StructBlock( + [ + ( + "label", + wagtail.blocks.CharBlock( + help_text="Label for this link." + ), + ), + ( + "link", + wagtail.blocks.URLBlock( + help_text="URL that this should link out to." + ), + ), + ] + ), + ), + ], + help_text="The link that appears below the card heading.", + max_num=1, + required=False, + ), + ), + ( + "image", + wagtail.images.blocks.ImageChooserBlock( + help_text="The image associated with this event." + ), + ), + ( + "body", + wagtail.blocks.TextBlock( + help_text="Body text of the card." + ), + ), + ( + "buttons", + wagtail.blocks.StreamBlock( + [ + ( + "internal", + wagtail.blocks.StructBlock( + [ + ( + "label", + wagtail.blocks.CharBlock( + help_text="Label for this link." + ), + ), + ( + "link", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to." + ), + ), + ] + ), + ), + ( + "external", + wagtail.blocks.StructBlock( + [ + ( + "label", + wagtail.blocks.CharBlock( + help_text="Label for this link." + ), + ), + ( + "link", + wagtail.blocks.URLBlock( + help_text="URL that this should link out to." + ), + ), + ] + ), + ), + ( + "document", + wagtail.blocks.StructBlock( + [ + ( + "label", + wagtail.blocks.CharBlock( + help_text="Label for this link." + ), + ), + ( + "document", + wagtail.documents.blocks.DocumentChooserBlock( + help_text="Document that this should link out to." + ), + ), + ], + help_text='An iCal document can be attached here for an "Add to Calendar" button.', + ), + ), + ], + help_text="A list of buttons that will appear at the bottom of the card.", + max_num=2, + ), + ), + ] + ), + ) + ], + help_text="A list of current events in the slider.", + ), + ), + ] + ), + ), + ( + "spaces", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock()), + ( + "cards", + wagtail.blocks.StreamBlock( + [ + ( + "space_card", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the card." + ), + ), + ( + "body", + wagtail.blocks.TextBlock( + help_text="Body text of the card." + ), + ), + ( + "link", + wagtail.blocks.StreamBlock( + [ + ( + "internal", + wagtail.blocks.StructBlock( + [ + ( + "link", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to." + ), + ) + ] + ), + ), + ( + "external", + wagtail.blocks.StructBlock( + [ + ( + "link", + wagtail.blocks.URLBlock( + help_text="URL that this should link out to." + ), + ) + ] + ), + ), + ], + help_text="Page or external URL this card will link out to.", + max_num=1, + ), + ), + ] + ), + ) + ], + help_text="A list of Spaces Cards.", + ), + ), + ] + ), + ), + ( + "tito_widget", + wagtail.blocks.StructBlock( + [ + ( + "button_label", + wagtail.blocks.CharBlock(help_text="The text to show on the Tito button."), + ), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ( + "event", + wagtail.snippets.blocks.SnippetChooserBlock( + "events.TitoEvent", help_event="The Tito event to be displayed" + ), + ), + ( + "releases", + wagtail.blocks.CharBlock( + help_text='Comma-separated list of ticket/release IDs to limit to, e.g. "3elajg6qcxu,6qiiw4socs4"', + required=False, + ), + ), + ] + ), + ), + ( + "statistics", + wagtail.blocks.StructBlock( + [ + ( + "statistics", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="The statistic figure, e.g '1000+' or '10%'" + ), + ), + ( + "description", + wagtail.blocks.CharBlock( + help_text="Context or description for the statistic" + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + max_num=4, + min_num=2, + ), + ) + ] + ), + ), + ( + "carousel_and_text", + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock(help_text="Heading for the block.", required=False), + ), + ("text", wagtail.blocks.RichTextBlock(features=["bold", "italic", "link"])), + ( + "link_url", + wagtail.blocks.URLBlock( + help_text="A CTA URL for a link displayed", required=False + ), + ), + ( + "link_label", + wagtail.blocks.CharBlock(help_text="Label for the CTA link.", required=False), + ), + ( + "carousel_images", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", + required=True, + ), + ), + ] + ), + max_num=4, + ), + ), + ] + ), + ), + ( + "tickets", + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock(help_text="Heading for the block.", required=False), + ), + ( + "tickets", + wagtail.blocks.ListBlock( + wagtail.snippets.blocks.SnippetChooserBlock("mozfest.Ticket"), max_num=3 + ), + ), + ] + ), + ), + ( + "dark_quote", + wagtail.blocks.StructBlock( + [ + ("quote", wagtail.blocks.RichTextBlock(features=["bold"])), + ("attribution", wagtail.blocks.CharBlock(required=False)), + ( + "attribution_info", + wagtail.blocks.RichTextBlock(features=["bold", "link", "large"], required=False), + ), + ] + ), + ), + ( + "cta", + 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"', + 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), + ), + ("heading", wagtail.blocks.CharBlock(required=False)), + ("text", wagtail.blocks.CharBlock(required=False)), + ("dark_background", wagtail.blocks.BooleanBlock(required=False)), + ] + ), + ), + ( + "newsletter_signup", + wagtail.blocks.StructBlock( + [ + ( + "snippet", + wagtail.snippets.blocks.SnippetChooserBlock( + "mozfest.NewsletterSignupWithBackground" + ), + ) + ] + ), + ), + ( + "mixed_content", + wagtail.blocks.StructBlock( + [ + ( + "video", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="For YouTube: go to your YouTube video and click “Share,” then “Embed,” and then copy and paste the provided URL only. For example: https://www.youtube.com/embed/3FIVXBawyQw For Vimeo: follow similar steps to grab the embed URL. For example: https://player.vimeo.com/video/9004979", + label="Embed URL", + ), + ), + ( + "caption", + wagtail.blocks.CharBlock( + help_text="Optional caption for the video, displayed next to the play button.", + max_length=25, + required=False, + ), + ), + ( + "title", + wagtail.blocks.CharBlock( + help_text="Optional title for the video.", + max_length=50, + required=False, + ), + ), + ( + "text", + wagtail.blocks.CharBlock( + help_text="Text content to display with the video title.", + required=False, + ), + ), + ( + "thumbnail", + wagtail.images.blocks.ImageChooserBlock( + help_text="The image to show before the video is played." + ), + ), + ] + ), + ), + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ( + "highlighted_metadata", + wagtail.blocks.CharBlock( + help_text="Metadata to highlight on the card.", required=False + ), + ), + ( + "metadata", + wagtail.blocks.CharBlock( + help_text="Generic metadata.", required=False + ), + ), + ( + "body", + wagtail.blocks.RichTextBlock( + features=["bold"], + help_text="Body text of the card.", + required=False, + ), + ), + ( + "link_page", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to.", required=False + ), + ), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that the header should link out to.", + required=False, + ), + ), + ] + ), + max_num=4, + min_num=1, + ), + ), + ("link_url", wagtail.blocks.URLBlock(required=False)), + ("link_text", wagtail.blocks.CharBlock(max_length=50, required=False)), + ] + ), + ), + ], + use_json_field=True, + ), + ), + MigrateStreamData( + app_name="mozfest", + model_name="mozfestprimarypage", + field_name="body", + operations_and_block_paths=[ + ( + AlterStreamChildBlockDataOperation( + block="image_teaser_block", operation=migrate_image_teaser_block + ), + "", + ), + ], + ), + migrations.AlterField( + model_name="mozfestprimarypage", + name="body", + field=wagtail.fields.StreamField( + [ + ( + "paragraph", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + "large", + ], + template="wagtailpages/blocks/rich_text_block.html", + ), + ), + ( + "card_grid", + wagtail.blocks.StructBlock( + [ + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ("body", wagtail.blocks.TextBlock(help_text="Body text of the card.")), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that this card should link out to. (Note: If left blank, link will not render.) ", + required=False, + ), + ), + ( + "link_label", + wagtail.blocks.CharBlock( + help_text="Optional Label for the URL link above. (Note: If left blank, link will not render.) ", + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + ), + ) + ] + ), + ), + ( + "image", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "image_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide images are col-12, Full-Width Images reach both ends of the screen (16:6 images recommended for full width)", + ), + ), + ] + ), + ), + ( + "image_text", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ( + "text", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + ] + ), + ), + ( + "url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this image should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ] + ), + ), + ( + "image_text_mini", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ("text", wagtail.blocks.RichTextBlock(features=["bold", "italic", "link"])), + ] + ), + ), + ( + "image_grid", + wagtail.blocks.StructBlock( + [ + ( + "grid_items", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for this image.", required=False + ), + ), + ( + "caption", + wagtail.blocks.CharBlock( + help_text="Please remember to properly attribute any images we use.", + required=False, + ), + ), + ( + "url", + wagtail.blocks.CharBlock( + help_text="Optional URL that this figure should link out to.", + required=False, + ), + ), + ( + "square_image", + wagtail.blocks.BooleanBlock( + default=True, + help_text="If left checked, the image will be cropped to be square.", + required=False, + ), + ), + ] + ) + ), + ) + ] + ), + ), + ( + "video", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="For YouTube: go to your YouTube video and click “Share,” then “Embed,” and then copy and paste the provided URL only. For example: https://www.youtube.com/embed/3FIVXBawyQw For Vimeo: follow similar steps to grab the embed URL. For example: https://player.vimeo.com/video/9004979", + label="Embed URL", + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "video_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide videos are col-12, Full-Width videos reach both ends of the screen.", + ), + ), + ] + ), + ), + ( + "iframe", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.CharBlock( + help_text="Please note that only URLs from allow-listed domains will work." + ), + ), + ( + "height", + wagtail.blocks.IntegerBlock( + help_text="Optional integer pixel value for custom iFrame height", + required=False, + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "iframe_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide iframes are col-12, Full-Width iframes reach both ends of the screen", + ), + ), + ( + "disable_scroll", + wagtail.blocks.BooleanBlock( + default=False, + help_text='Checking this will add "scrolling=no" to the iframe. Use this if your iframe is rendering an unnecessary scroll bar or whitespace below it.', + required=False, + ), + ), + ] + ), + ), + ( + "linkbutton", + 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"', + 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), + ), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ] + ), + ), + ( + "spacer", + wagtail.blocks.StructBlock( + [ + ( + "size", + wagtail.blocks.ChoiceBlock( + choices=[ + ("1", "quarter spacing"), + ("2", "half spacing"), + ("3", "single spacing"), + ("4", "one and a half spacing"), + ("5", "triple spacing"), + ] + ), + ) + ] + ), + ), + ( + "single_quote", + wagtail.blocks.StructBlock( + [ + ("quote", wagtail.blocks.RichTextBlock(features=["bold"])), + ("attribution", wagtail.blocks.CharBlock(required=False)), + ( + "attribution_info", + wagtail.blocks.RichTextBlock(features=["bold", "link", "large"], required=False), + ), + ] + ), + ), + ( + "profile_by_id", + wagtail.blocks.StructBlock( + [ + ( + "ids", + wagtail.blocks.CharBlock( + help_text="Show profiles for pulse users with specific profile ids (mozillapulse.org/profile/[##]). For multiple profiles, specify a comma separated list (e.g. 85,105,332).", + label="Profile by ID", + ), + ) + ] + ), + ), + ( + "profile_directory", + wagtail.blocks.StructBlock( + [ + ( + "max_number_of_results", + wagtail.blocks.IntegerBlock( + default=12, + help_text="Pick up to 48 profiles.", + max_value=48, + min_value=1, + required=True, + ), + ), + ( + "advanced_filter_header", + wagtail.blocks.static_block.StaticBlock( + admin_text="-------- ADVANCED FILTERS: OPTIONS TO DISPLAY FEWER, MORE TARGETED RESULTS. --------", + label=" ", + ), + ), + ( + "profile_type", + wagtail.blocks.CharBlock(default="", help_text="Example: Fellow.", required=False), + ), + ( + "program_type", + wagtail.blocks.CharBlock( + default="", help_text="Example: Tech Policy.", required=False + ), + ), + ("year", wagtail.blocks.CharBlock(default="", required=False)), + ( + "filter_values", + wagtail.blocks.CharBlock( + default="2019,2018,2017,2016,2015,2014,2013", + help_text="Example: 2019,2018,2017,2016,2015,2014,2013", + required=True, + ), + ), + ] + ), + ), + ( + "recent_blog_entries", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock(required=False)), + ( + "tag_filter", + wagtail.blocks.CharBlock( + help_text="Test this filter at foundation.mozilla.org/blog/tags/", + label="Filter by Tag", + required=False, + ), + ), + ( + "topic_filter", + wagtail.blocks.ChoiceBlock( + choices=networkapi.wagtailpages.pagemodels.blog.blog_topic.BlogPageTopic.get_topics, + help_text="Test this filter at foundation.mozilla.org/blog/topic/", + label="Filter by Topic", + required=False, + ), + ), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ] + ), + ), + ( + "blog_set", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock()), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ( + "blog_pages", + wagtail.blocks.ListBlock( + wagtail.blocks.PageChooserBlock(page_type=["wagtailpages.BlogPage"]) + ), + ), + ] + ), + ), + ( + "datawrapper", + wagtail.embeds.blocks.EmbedBlock( + help_text='Enter the "visualization only" link of the Datawrapper chart. It looks something like this: https://datawrapper.dwcdn.net/KwSKp/1/', + icon="image", + template="wagtailpages/blocks/datawrapper_block.html", + ), + ), + ( + "listing", + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock(help_text="Heading for the block.", required=False), + ), + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ( + "highlighted_metadata", + wagtail.blocks.CharBlock( + help_text="Metadata to highlight on the card.", required=False + ), + ), + ( + "metadata", + wagtail.blocks.CharBlock( + help_text="Generic metadata.", required=False + ), + ), + ( + "body", + wagtail.blocks.RichTextBlock( + features=["bold"], + help_text="Body text of the card.", + required=False, + ), + ), + ( + "link_page", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to.", required=False + ), + ), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that the header should link out to.", + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + min_num=2, + ), + ), + ( + "cards_per_row", + wagtail.blocks.ChoiceBlock( + choices=[(2, "2"), (3, "3")], + help_text="Number of cards per row. Note: this is a max and fewer might be used if is less space is available.", + required=False, + ), + ), + ] + ), + ), + ( + "profiles", + wagtail.blocks.StructBlock( + [ + ( + "profiles", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "profile", + wagtail.snippets.blocks.SnippetChooserBlock( + networkapi.wagtailpages.pagemodels.profiles.Profile + ), + ) + ] + ), + min_num=1, + ), + ) + ] + ), + ), + ( + "group_listing_block", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the group of cards.", required=False + ), + ), + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ( + "meta_data", + wagtail.blocks.CharBlock( + help_text="Optional meta data information for the card.", + required=False, + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ( + "body", + wagtail.blocks.RichTextBlock( + features=["bold", "link"], help_text="Body text of the card." + ), + ), + ( + "url", + wagtail.blocks.CharBlock( + help_text="The URL this card should link to.", required=False + ), + ), + ] + ) + ), + ), + ] + ), + ), + ( + "image_feature", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock(help_text="Image description (for screen readers)."), + ), + ("metadata", wagtail.blocks.CharBlock(required=False)), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ( + "title_link", + wagtail.blocks.PageChooserBlock( + help_text="Page that the title should link out to.", required=False + ), + ), + ("body", wagtail.blocks.CharBlock(required=False)), + ] + ), + ), + ( + "image_teaser_block", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ("text", wagtail.blocks.RichTextBlock(features=["bold"])), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ( + "link_button", + wagtail.blocks.ListBlock( + 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"', + 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 + ), + ), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ] + ), + help_text="Optional link button", + max_num=1, + min_num=0, + ), + ), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ] + ), + ), + ( + "text_only_teaser", + wagtail.blocks.StructBlock( + [ + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock(help_text="Heading for the card."), + ), + ( + "link_page", + wagtail.blocks.PageChooserBlock( + help_text="Page that the header should link out to.", + required=False, + ), + ), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that the header should link out to.", + required=False, + ), + ), + ("meta_data", wagtail.blocks.CharBlock(max_length=500)), + ( + "body", + wagtail.blocks.TextBlock( + help_text="Body text of the card.", + max_length=200, + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 3 cards.", + min_num=3, + ), + ) + ] + ), + ), + ( + "block_with_aside", + wagtail.blocks.StructBlock( + [ + ( + "content", + wagtail.blocks.StreamBlock( + [ + ( + "listing", + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock( + help_text="Heading for the block.", required=False + ), + ), + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "image", + wagtail.images.blocks.ImageChooserBlock(), + ), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", + required=False, + ), + ), + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the card." + ), + ), + ( + "highlighted_metadata", + wagtail.blocks.CharBlock( + help_text="Metadata to highlight on the card.", + required=False, + ), + ), + ( + "metadata", + wagtail.blocks.CharBlock( + help_text="Generic metadata.", + required=False, + ), + ), + ( + "body", + wagtail.blocks.RichTextBlock( + features=["bold"], + help_text="Body text of the card.", + required=False, + ), + ), + ( + "link_page", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to.", + required=False, + ), + ), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that the header should link out to.", + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + min_num=2, + ), + ), + ( + "cards_per_row", + wagtail.blocks.ChoiceBlock( + choices=[(2, "2"), (3, "3")], + help_text="Number of cards per row. Note: this is a max and fewer might be used if is less space is available.", + required=False, + ), + ), + ] + ), + ), + ( + "paragraph", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + ] + ), + ), + ], + help_text="The wider block that appears on the left on desktop", + icon="doc-full", + max_num=1, + ), + ), + ( + "aside", + wagtail.blocks.StreamBlock( + [ + ( + "aside_content", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the card.", required=False + ), + ), + ( + "body", + wagtail.blocks.TextBlock( + help_text="Body text of the card.", required=False + ), + ), + ] + ), + ), + ( + "linkbutton", + 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"', + 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 + ), + ), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ] + ), + ), + ( + "spacer", + wagtail.blocks.StructBlock( + [ + ( + "size", + wagtail.blocks.ChoiceBlock( + choices=[ + ("1", "quarter spacing"), + ("2", "half spacing"), + ("3", "single spacing"), + ("4", "one and a half spacing"), + ("5", "triple spacing"), + ] + ), + ) + ] + ), + ), + ], + help_text="Elements here will appear in the column on the right side of the page on desktop. This can be left blank if you would just like a 2/3 column on the left", + icon="doc-full", + required=False, + ), + ), + ] + ), + ), + ( + "accordion", + wagtail.blocks.StructBlock( + [ + ( + "accordion_items", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the Accordion Item" + ), + ), + ( + "content", + wagtail.blocks.StreamBlock( + [ + ( + "rich_text", + wagtail.blocks.RichTextBlock( + blank=True, + features=[ + "bold", + "italic", + "link", + "ul", + "ol", + "document-link", + ], + ), + ), + ( + "datawrapper", + wagtail.embeds.blocks.EmbedBlock( + help_text='Enter the "visualization only" link of the Datawrapper chart. It looks something like this: https://datawrapper.dwcdn.net/KwSKp/1/', + icon="image", + template="wagtailpages/blocks/datawrapper_block.html", + ), + ), + ( + "image", + wagtail.blocks.StructBlock( + [ + ( + "image", + wagtail.images.blocks.ImageChooserBlock(), + ), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", + required=True, + ), + ), + ] + ), + ), + ( + "video", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="For YouTube: go to your YouTube video and click “Share,” then “Embed,” and then copy and paste the provided URL only. For example: https://www.youtube.com/embed/3FIVXBawyQw For Vimeo: follow similar steps to grab the embed URL. For example: https://player.vimeo.com/video/9004979", + label="Embed URL", + ), + ), + ( + "caption", + wagtail.blocks.CharBlock(required=False), + ), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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, + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "video_width", + wagtail.blocks.ChoiceBlock( + choices=[ + ("normal", "Normal"), + ("wide", "Wide"), + ("full_width", "Full Width"), + ], + help_text="Wide videos are col-12, Full-Width videos reach both ends of the screen.", + ), + ), + ] + ), + ), + ] + ), + ), + ] + ) + ), + ) + ] + ), + ), + ( + "session_slider", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock(help_text="Heading for the slider.")), + ( + "session_items", + wagtail.blocks.StreamBlock( + [ + ( + "session_item", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the card." + ), + ), + ( + "author_subheading", + wagtail.blocks.CharBlock( + help_text="Author of this session.", required=False + ), + ), + ( + "image", + wagtail.images.blocks.ImageChooserBlock( + help_text="The image associated with this session." + ), + ), + ( + "body", + wagtail.blocks.RichTextBlock( + help_text="Body text of this card." + ), + ), + ( + "video", + wagtailmedia.blocks.VideoChooserBlock( + help_text="Video that will autoplay when this card is hovered on", + required=False, + ), + ), + ( + "link", + wagtail.blocks.StreamBlock( + [ + ( + "internal", + wagtail.blocks.StructBlock( + [ + ( + "link", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to." + ), + ) + ] + ), + ), + ( + "external", + wagtail.blocks.StructBlock( + [ + ( + "link", + wagtail.blocks.URLBlock( + help_text="URL that this should link out to." + ), + ) + ] + ), + ), + ], + help_text="Page or external URL this card will link out to.", + max_num=1, + ), + ), + ] + ), + ) + ], + help_text="A list of sessions in the slider.", + ), + ), + ( + "button", + wagtail.blocks.StreamBlock( + [ + ( + "internal", + wagtail.blocks.StructBlock( + [ + ( + "label", + wagtail.blocks.CharBlock(help_text="Label for this link."), + ), + ( + "link", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to." + ), + ), + ] + ), + ), + ( + "external", + wagtail.blocks.StructBlock( + [ + ( + "label", + wagtail.blocks.CharBlock(help_text="Label for this link."), + ), + ( + "link", + wagtail.blocks.URLBlock( + help_text="URL that this should link out to." + ), + ), + ] + ), + ), + ], + help_text="Button that appears below the slider.", + max_num=1, + required=False, + ), + ), + ] + ), + ), + ( + "current_events_slider", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock(help_text="Heading for the slider.")), + ( + "current_events", + wagtail.blocks.StreamBlock( + [ + ( + "current_event", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock(help_text="Heading of the card."), + ), + ( + "subheading_link", + wagtail.blocks.StreamBlock( + [ + ( + "internal", + wagtail.blocks.StructBlock( + [ + ( + "label", + wagtail.blocks.CharBlock( + help_text="Label for this link." + ), + ), + ( + "link", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to." + ), + ), + ] + ), + ), + ( + "external", + wagtail.blocks.StructBlock( + [ + ( + "label", + wagtail.blocks.CharBlock( + help_text="Label for this link." + ), + ), + ( + "link", + wagtail.blocks.URLBlock( + help_text="URL that this should link out to." + ), + ), + ] + ), + ), + ], + help_text="The link that appears below the card heading.", + max_num=1, + required=False, + ), + ), + ( + "image", + wagtail.images.blocks.ImageChooserBlock( + help_text="The image associated with this event." + ), + ), + ( + "body", + wagtail.blocks.TextBlock( + help_text="Body text of the card." + ), + ), + ( + "buttons", + wagtail.blocks.StreamBlock( + [ + ( + "internal", + wagtail.blocks.StructBlock( + [ + ( + "label", + wagtail.blocks.CharBlock( + help_text="Label for this link." + ), + ), + ( + "link", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to." + ), + ), + ] + ), + ), + ( + "external", + wagtail.blocks.StructBlock( + [ + ( + "label", + wagtail.blocks.CharBlock( + help_text="Label for this link." + ), + ), + ( + "link", + wagtail.blocks.URLBlock( + help_text="URL that this should link out to." + ), + ), + ] + ), + ), + ( + "document", + wagtail.blocks.StructBlock( + [ + ( + "label", + wagtail.blocks.CharBlock( + help_text="Label for this link." + ), + ), + ( + "document", + wagtail.documents.blocks.DocumentChooserBlock( + help_text="Document that this should link out to." + ), + ), + ], + help_text='An iCal document can be attached here for an "Add to Calendar" button.', + ), + ), + ], + help_text="A list of buttons that will appear at the bottom of the card.", + max_num=2, + ), + ), + ] + ), + ) + ], + help_text="A list of current events in the slider.", + ), + ), + ] + ), + ), + ( + "spaces", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock()), + ( + "cards", + wagtail.blocks.StreamBlock( + [ + ( + "space_card", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the card." + ), + ), + ( + "body", + wagtail.blocks.TextBlock( + help_text="Body text of the card." + ), + ), + ( + "link", + wagtail.blocks.StreamBlock( + [ + ( + "internal", + wagtail.blocks.StructBlock( + [ + ( + "link", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to." + ), + ) + ] + ), + ), + ( + "external", + wagtail.blocks.StructBlock( + [ + ( + "link", + wagtail.blocks.URLBlock( + help_text="URL that this should link out to." + ), + ) + ] + ), + ), + ], + help_text="Page or external URL this card will link out to.", + max_num=1, + ), + ), + ] + ), + ) + ], + help_text="A list of Spaces Cards.", + ), + ), + ] + ), + ), + ( + "tito_widget", + wagtail.blocks.StructBlock( + [ + ( + "button_label", + wagtail.blocks.CharBlock(help_text="The text to show on the Tito button."), + ), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ( + "event", + wagtail.snippets.blocks.SnippetChooserBlock( + "events.TitoEvent", help_event="The Tito event to be displayed" + ), + ), + ( + "releases", + wagtail.blocks.CharBlock( + help_text='Comma-separated list of ticket/release IDs to limit to, e.g. "3elajg6qcxu,6qiiw4socs4"', + required=False, + ), + ), + ] + ), + ), + ( + "statistics", + wagtail.blocks.StructBlock( + [ + ( + "statistics", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="The statistic figure, e.g '1000+' or '10%'" + ), + ), + ( + "description", + wagtail.blocks.CharBlock( + help_text="Context or description for the statistic" + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + max_num=4, + min_num=2, + ), + ) + ] + ), + ), + ( + "carousel_and_text", + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock(help_text="Heading for the block.", required=False), + ), + ("text", wagtail.blocks.RichTextBlock(features=["bold", "italic", "link"])), + ( + "link_url", + wagtail.blocks.URLBlock( + help_text="A CTA URL for a link displayed", required=False + ), + ), + ( + "link_label", + wagtail.blocks.CharBlock(help_text="Label for the CTA link.", required=False), + ), + ( + "carousel_images", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", + required=True, + ), + ), + ] + ), + max_num=4, + ), + ), + ] + ), + ), + ( + "tickets", + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock(help_text="Heading for the block.", required=False), + ), + ( + "tickets", + wagtail.blocks.ListBlock( + wagtail.snippets.blocks.SnippetChooserBlock("mozfest.Ticket"), max_num=3 + ), + ), + ] + ), + ), + ( + "dark_quote", + wagtail.blocks.StructBlock( + [ + ("quote", wagtail.blocks.RichTextBlock(features=["bold"])), + ("attribution", wagtail.blocks.CharBlock(required=False)), + ( + "attribution_info", + wagtail.blocks.RichTextBlock(features=["bold", "link", "large"], required=False), + ), + ] + ), + ), + ( + "cta", + 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"', + 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), + ), + ("heading", wagtail.blocks.CharBlock(required=False)), + ("text", wagtail.blocks.CharBlock(required=False)), + ("dark_background", wagtail.blocks.BooleanBlock(required=False)), + ] + ), + ), + ( + "newsletter_signup", + wagtail.blocks.StructBlock( + [ + ( + "snippet", + wagtail.snippets.blocks.SnippetChooserBlock( + "mozfest.NewsletterSignupWithBackground" + ), + ) + ] + ), + ), + ( + "mixed_content", + wagtail.blocks.StructBlock( + [ + ( + "video", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="For YouTube: go to your YouTube video and click “Share,” then “Embed,” and then copy and paste the provided URL only. For example: https://www.youtube.com/embed/3FIVXBawyQw For Vimeo: follow similar steps to grab the embed URL. For example: https://player.vimeo.com/video/9004979", + label="Embed URL", + ), + ), + ( + "caption", + wagtail.blocks.CharBlock( + help_text="Optional caption for the video, displayed next to the play button.", + max_length=25, + required=False, + ), + ), + ( + "title", + wagtail.blocks.CharBlock( + help_text="Optional title for the video.", + max_length=50, + required=False, + ), + ), + ( + "text", + wagtail.blocks.CharBlock( + help_text="Text content to display with the video title.", + required=False, + ), + ), + ( + "thumbnail", + wagtail.images.blocks.ImageChooserBlock( + help_text="The image to show before the video is played." + ), + ), + ] + ), + ), + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ( + "highlighted_metadata", + wagtail.blocks.CharBlock( + help_text="Metadata to highlight on the card.", required=False + ), + ), + ( + "metadata", + wagtail.blocks.CharBlock( + help_text="Generic metadata.", required=False + ), + ), + ( + "body", + wagtail.blocks.RichTextBlock( + features=["bold"], + help_text="Body text of the card.", + required=False, + ), + ), + ( + "link_page", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to.", required=False + ), + ), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that the header should link out to.", + required=False, + ), + ), + ] + ), + max_num=4, + min_num=1, + ), + ), + ("link_url", wagtail.blocks.URLBlock(required=False)), + ("link_text", wagtail.blocks.CharBlock(max_length=50, required=False)), + ] + ), + ), + ], + use_json_field=True, + ), + ), + ] diff --git a/network-api/networkapi/utility/faker/streamfield_provider.py b/network-api/networkapi/utility/faker/streamfield_provider.py index e61730cddc7..bf7879b77e8 100644 --- a/network-api/networkapi/utility/faker/streamfield_provider.py +++ b/network-api/networkapi/utility/faker/streamfield_provider.py @@ -195,8 +195,13 @@ def generate_dark_quote_field(): def generate_video_field(): caption = fake.paragraph(nb_sentences=1, variable_nb_sentences=False) - captionURL = fake.url(schemes=["https"]) - + caption_external_url = [ + { + "link_to": "external_url", + "external_url": fake.url(schemes=["https"]), + "new_window": True, + } + ] return generate_field( "video", { @@ -205,7 +210,7 @@ def generate_video_field(): # See details: https://github.com/mozilla/foundation.mozilla.org/issues/3833#issuecomment-562240677 "url": "https://www.youtube.com/embed/83fk3RT8318", "caption": caption, - "captionURL": captionURL, + "caption_url": caption_external_url, "video_width": "full_width", }, ) @@ -675,6 +680,18 @@ def generate_mixed_content_field(): ) +def generate_app_install_download_button_field(): + return generate_field( + "button", + { + "link_to": "external_url", + "external_url": fake.url(schemes=["https"]), + "label": " ".join(fake.words(nb=2)), + "new_window": True, + }, + ) + + class StreamfieldProvider(BaseProvider): """ A custom Faker Provider for relative image urls, for use with factory_boy @@ -734,6 +751,7 @@ def streamfield(self, fields=None): "profiles": generate_profiles_field, "newsletter_signup": generate_newsletter_signup_with_background_field, "mixed_content": generate_mixed_content_field, + "app_install_download_button": generate_app_install_download_button_field, } streamfield_data = [] diff --git a/network-api/networkapi/wagtailpages/factory/__init__.py b/network-api/networkapi/wagtailpages/factory/__init__.py index 54c14dffa06..5b4921c214f 100644 --- a/network-api/networkapi/wagtailpages/factory/__init__.py +++ b/network-api/networkapi/wagtailpages/factory/__init__.py @@ -1,6 +1,7 @@ from networkapi.wagtailpages.factory.libraries import rcc, research_hub from . import ( + app_install_page, bannered_campaign_page, blog, buyersguide, @@ -50,6 +51,7 @@ def generate(seed): rcc.generate(seed) # homepage_cause_statement_link requires child pages of homepage to exist homepage_cause_statement_link.generate(seed) + app_install_page.generate(seed) __all__ = [ diff --git a/network-api/networkapi/wagtailpages/factory/app_install_page.py b/network-api/networkapi/wagtailpages/factory/app_install_page.py new file mode 100644 index 00000000000..89c442e9683 --- /dev/null +++ b/network-api/networkapi/wagtailpages/factory/app_install_page.py @@ -0,0 +1,39 @@ +from factory import Faker, SubFactory +from wagtail_factories import PageFactory + +from networkapi.utility.faker.helpers import reseed +from networkapi.wagtailpages import models as pagemodels +from networkapi.wagtailpages.factory import image_factory +from networkapi.wagtailpages.models import AppInstallPage + +from .petition import PetitionFactory + + +class AppInstallPageFactory(PageFactory): + class Meta: + model = AppInstallPage + exclude = ( + "title_text", + "header_text", + "header", + ) + + title = "Regrets Reporter Page" + slug = "regretsreporter" + hero_heading = Faker("text", max_nb_chars=50) + hero_subheading = Faker("text", max_nb_chars=50) + hero_background = SubFactory(image_factory.ImageFactory) + download_buttons = Faker("streamfield", fields=["app_install_download_button"] * 2) + cta = SubFactory(PetitionFactory) + body = Faker("streamfield", fields=["header", "paragraph", "image", "spacer", "image_text", "quote"]) + + +def generate(seed): + reseed(seed) + + print("Generating PNI Homepage") + AppInstallPageFactory.create( + parent=pagemodels.Homepage.objects.first(), + title="App Install Page", + slug="app-install-page", + ) diff --git a/network-api/networkapi/wagtailpages/migrations/0144_alter_appinstallpage_hero_heading_and_more.py b/network-api/networkapi/wagtailpages/migrations/0144_alter_appinstallpage_hero_heading_and_more.py new file mode 100644 index 00000000000..4c2ae7f15f2 --- /dev/null +++ b/network-api/networkapi/wagtailpages/migrations/0144_alter_appinstallpage_hero_heading_and_more.py @@ -0,0 +1,23 @@ +# Generated by Django 4.2.11 on 2024-07-02 19:55 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("wagtailpages", "0143_delete_youtuberegretsreporterextensionpage"), + ] + + operations = [ + migrations.AlterField( + model_name="appinstallpage", + name="hero_heading", + field=models.CharField(help_text="Hero story headline", max_length=250), + ), + migrations.AlterField( + model_name="appinstallpage", + name="hero_subheading", + field=models.CharField(blank=True, help_text="Hero story subheadline", max_length=250), + ), + ] diff --git a/network-api/networkapi/wagtailpages/migrations/0145_update_videoblock_with_linkblock.py b/network-api/networkapi/wagtailpages/migrations/0145_update_videoblock_with_linkblock.py new file mode 100644 index 00000000000..5fb62a16f9a --- /dev/null +++ b/network-api/networkapi/wagtailpages/migrations/0145_update_videoblock_with_linkblock.py @@ -0,0 +1,17007 @@ +# Generated by Django 4.2.11 on 2024-07-03 00:44 + +import django.core.validators +import wagtail.blocks +import wagtail.blocks.static_block +import wagtail.contrib.table_block.blocks +import wagtail.documents.blocks +import wagtail.embeds.blocks +import wagtail.fields +import wagtail.images.blocks +import wagtail.snippets.blocks +import wagtailmedia.blocks +from django.db import migrations +from wagtail.blocks.migrations.migrate_operation import MigrateStreamData + +import networkapi.wagtailpages.pagemodels.blog.blog_topic +import networkapi.wagtailpages.pagemodels.customblocks.articles +import networkapi.wagtailpages.pagemodels.profiles +import networkapi.wagtailpages.validators +from networkapi.utility.migration.operations import AlterStreamChildBlockDataOperation + + +def migrate_video_block(source_block): + new_value = { + "url": source_block["value"].get("url"), + "caption": source_block["value"].get("caption"), + "caption_url": [], + "video_width": source_block["value"].get("video_width"), + } + if "captionURL" in source_block["value"] and source_block["value"]["captionURL"]: + new_value["caption_url"] = [ + { + "link_to": "external_url", + "external_url": source_block["value"].get("captionURL"), + "new_window": True, + } + ] + return { + **source_block, + "value": new_value, + } + + +class Migration(migrations.Migration): + + dependencies = [ + ("wagtailpages", "0144_alter_appinstallpage_hero_heading_and_more"), + ] + + operations = [ + migrations.AlterField( + model_name="articlepage", + name="body", + field=wagtail.fields.StreamField( + [ + ( + "accordion", + wagtail.blocks.StructBlock( + [ + ( + "accordion_items", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the Accordion Item" + ), + ), + ( + "content", + wagtail.blocks.StreamBlock( + [ + ( + "rich_text", + wagtail.blocks.RichTextBlock( + blank=True, + features=[ + "bold", + "italic", + "link", + "ul", + "ol", + "document-link", + ], + ), + ), + ( + "datawrapper", + wagtail.embeds.blocks.EmbedBlock( + help_text='Enter the "visualization only" link of the Datawrapper chart. It looks something like this: https://datawrapper.dwcdn.net/KwSKp/1/', + icon="image", + template="wagtailpages/blocks/datawrapper_block.html", + ), + ), + ( + "image", + wagtail.blocks.StructBlock( + [ + ( + "image", + wagtail.images.blocks.ImageChooserBlock(), + ), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", + required=True, + ), + ), + ] + ), + ), + ( + "video", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="For YouTube: go to your YouTube video and click “Share,” then “Embed,” and then copy and paste the provided URL only. For example: https://www.youtube.com/embed/3FIVXBawyQw For Vimeo: follow similar steps to grab the embed URL. For example: https://player.vimeo.com/video/9004979", + label="Embed URL", + ), + ), + ( + "caption", + wagtail.blocks.CharBlock(required=False), + ), + ( + "captionURL", + wagtail.blocks.CharBlock( + help_text="Optional URL for caption to link to.", + required=False, + ), + ), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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, + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "video_width", + wagtail.blocks.ChoiceBlock( + choices=[ + ("normal", "Normal"), + ("wide", "Wide"), + ("full_width", "Full Width"), + ], + help_text="Wide videos are col-12, Full-Width videos reach both ends of the screen.", + ), + ), + ] + ), + ), + ] + ), + ), + ] + ) + ), + ) + ] + ), + ), + ( + "airtable", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="Copied from the Airtable embed code. The word 'embed' will be in the url" + ), + ), + ( + "height", + wagtail.blocks.IntegerBlock( + default=533, + help_text="The pixel height on desktop view, usually copied from the Airtable embed code", + ), + ), + ] + ), + ), + ( + "datawrapper", + wagtail.embeds.blocks.EmbedBlock( + help_text='Enter the "visualization only" link of the Datawrapper chart. It looks something like this: https://datawrapper.dwcdn.net/KwSKp/1/', + icon="image", + template="wagtailpages/blocks/datawrapper_block.html", + ), + ), + ( + "callout", + wagtail.blocks.RichTextBlock( + features=["bold", "italic", "link", "h2", "h3", "h4", "ul", "ol"], + template="wagtailpages/blocks/article_blockquote_block.html", + ), + ), + ( + "card_grid", + wagtail.blocks.StructBlock( + [ + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ("body", wagtail.blocks.TextBlock(help_text="Body text of the card.")), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that this card should link out to. (Note: If left blank, link will not render.) ", + required=False, + ), + ), + ( + "link_label", + wagtail.blocks.CharBlock( + help_text="Optional Label for the URL link above. (Note: If left blank, link will not render.) ", + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + ), + ) + ] + ), + ), + ( + "content", + networkapi.wagtailpages.pagemodels.customblocks.articles.ArticleRichText( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + "large", + "image", + "footnotes", + ] + ), + ), + ( + "image", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "caption", + wagtail.blocks.RichTextBlock( + features=["bold", "italic", "link"], label="Image caption", required=False + ), + ), + ("alt_text", wagtail.blocks.CharBlock(required=False)), + ( + "wide_image", + wagtail.blocks.BooleanBlock( + default=False, + help_text='Checking this will use a wider version of this image, but not full width. For an edge-to-edge image, use the "Wide Image" block.', + required=False, + ), + ), + ] + ), + ), + ( + "image_grid", + wagtail.blocks.StructBlock( + [ + ( + "grid_items", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for this image.", required=False + ), + ), + ( + "caption", + wagtail.blocks.CharBlock( + help_text="Please remember to properly attribute any images we use.", + required=False, + ), + ), + ( + "url", + wagtail.blocks.CharBlock( + help_text="Optional URL that this figure should link out to.", + required=False, + ), + ), + ( + "square_image", + wagtail.blocks.BooleanBlock( + default=True, + help_text="If left checked, the image will be cropped to be square.", + required=False, + ), + ), + ] + ) + ), + ) + ] + ), + ), + ( + "image_text", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ( + "text", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + ] + ), + ), + ( + "url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this image should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ] + ), + ), + ( + "double_image", + wagtail.blocks.StructBlock( + [ + ("image_1", wagtail.images.blocks.ImageChooserBlock()), + ( + "image_1_caption", + wagtail.blocks.RichTextBlock( + features=["bold", "italic", "link"], label="Image caption", required=False + ), + ), + ("image_2", wagtail.images.blocks.ImageChooserBlock()), + ( + "image_2_caption", + wagtail.blocks.RichTextBlock( + features=["bold", "italic", "link"], label="Image caption", required=False + ), + ), + ] + ), + ), + ( + "full_width_image", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "image_height", + wagtail.blocks.IntegerBlock( + default=410, + help_text="A custom height for this image. The image will be 1400px wide by this height. Note: This may cause images to look pixelated. If the browser is wider than 1400px the height will scale vertically while the width scales horizontally", + ), + ), + ( + "caption", + wagtail.blocks.RichTextBlock( + features=["bold", "italic", "link"], label="Image caption", required=False + ), + ), + ] + ), + ), + ( + "iframe", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.CharBlock( + help_text="Please note that only URLs from allow-listed domains will work." + ), + ), + ( + "height", + wagtail.blocks.IntegerBlock( + help_text="Optional integer pixel value for custom iFrame height", + required=False, + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "iframe_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide iframes are col-12, Full-Width iframes reach both ends of the screen", + ), + ), + ( + "disable_scroll", + wagtail.blocks.BooleanBlock( + default=False, + help_text='Checking this will add "scrolling=no" to the iframe. Use this if your iframe is rendering an unnecessary scroll bar or whitespace below it.', + required=False, + ), + ), + ] + ), + ), + ( + "linkbutton", + 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"', + 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), + ), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ] + ), + ), + ( + "single_quote", + wagtail.blocks.StructBlock( + [ + ("quote", wagtail.blocks.RichTextBlock(features=["bold"])), + ("attribution", wagtail.blocks.CharBlock(required=False)), + ( + "attribution_info", + wagtail.blocks.RichTextBlock(features=["bold", "link", "large"], required=False), + ), + ] + ), + ), + ( + "slider", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock(help_text="Heading for the slider.", required=False), + ), + ( + "slides", + wagtail.blocks.StreamBlock( + [ + ( + "slide", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading of the card.", required=False + ), + ), + ( + "image", + wagtail.images.blocks.ImageChooserBlock( + help_text="The image associated with this event." + ), + ), + ( + "caption", + wagtail.blocks.TextBlock( + help_text="Caption for slider image", required=False + ), + ), + ( + "body", + wagtail.blocks.RichTextBlock( + blank=True, + features=["bold", "italic", "link", "large"], + required=False, + ), + ), + ( + "buttons", + wagtail.blocks.StreamBlock( + [ + ( + "internal", + wagtail.blocks.StructBlock( + [ + ( + "label", + wagtail.blocks.CharBlock( + help_text="Label for this link." + ), + ), + ( + "link", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to." + ), + ), + ] + ), + ), + ( + "external", + wagtail.blocks.StructBlock( + [ + ( + "label", + wagtail.blocks.CharBlock( + help_text="Label for this link." + ), + ), + ( + "link", + wagtail.blocks.URLBlock( + help_text="URL that this should link out to." + ), + ), + ] + ), + ), + ( + "document", + wagtail.blocks.StructBlock( + [ + ( + "label", + wagtail.blocks.CharBlock( + help_text="Label for this link." + ), + ), + ( + "document", + wagtail.documents.blocks.DocumentChooserBlock( + help_text="Document that this should link out to." + ), + ), + ], + help_text='An iCal document can be attached here for an "Add to Calendar" button.', + ), + ), + ], + help_text="A list of buttons that will appear at the bottom of the card.", + max_num=2, + required=False, + ), + ), + ] + ), + ) + ], + help_text="A list of slides.", + ), + ), + ] + ), + ), + ( + "spacer", + wagtail.blocks.StructBlock( + [ + ( + "size", + wagtail.blocks.ChoiceBlock( + choices=[ + ("1", "quarter spacing"), + ("2", "half spacing"), + ("3", "single spacing"), + ("4", "one and a half spacing"), + ("5", "triple spacing"), + ] + ), + ) + ] + ), + ), + ( + "table", + wagtail.contrib.table_block.blocks.TableBlock( + template="wagtailpages/blocks/article_table_block.html" + ), + ), + ( + "video", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="For YouTube: go to your YouTube video and click “Share,” then “Embed,” and then copy and paste the provided URL only. For example: https://www.youtube.com/embed/3FIVXBawyQw For Vimeo: follow similar steps to grab the embed URL. For example: https://player.vimeo.com/video/9004979", + label="Embed URL", + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "captionURL", + wagtail.blocks.CharBlock( + help_text="Optional URL for caption to link to.", required=False + ), + ), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "video_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide videos are col-12, Full-Width videos reach both ends of the screen.", + ), + ), + ] + ), + ), + ( + "advanced_table", + wagtail.blocks.StructBlock( + [ + ( + "header", + wagtail.blocks.BooleanBlock( + help_text="Display the first row as a header.", required=False + ), + ), + ( + "column", + wagtail.blocks.BooleanBlock( + help_text="Display the first column as a header.", required=False + ), + ), + ( + "caption", + wagtail.blocks.CharBlock( + help_text="A heading that identifies the overall topic of the table, and is useful for screen reader users", + required=False, + ), + ), + ( + "wide", + wagtail.blocks.BooleanBlock( + default=True, + help_text="If this is checked, the table will render wider than the other page body content.", + required=False, + ), + ), + ( + "table", + wagtail.blocks.StreamBlock( + [ + ( + "row", + wagtail.blocks.StreamBlock( + [ + ( + "cell", + wagtail.blocks.StructBlock( + [ + ( + "centered_text", + wagtail.blocks.BooleanBlock(required=False), + ), + ( + "column_width", + wagtail.blocks.IntegerBlock( + default=1, + help_text="Enter the number of extra cell columns you want to merge together. Merging a cell column will expand a cell to the right. To merge two cells together, set the column width to 2. For 3, set 3. Default is 1. Min 1. Max 20.", + validators=[ + django.core.validators.MaxValueValidator( + 20 + ), + django.core.validators.MinValueValidator( + 1 + ), + ], + ), + ), + ( + "content", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "ul", + "ol", + ] + ), + ), + ] + ), + ) + ] + ), + ) + ] + ), + ), + ] + ), + ), + ], + use_json_field=True, + ), + ), + migrations.AlterField( + model_name="blogpage", + name="body", + field=wagtail.fields.StreamField( + [ + ( + "accordion", + wagtail.blocks.StructBlock( + [ + ( + "accordion_items", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the Accordion Item" + ), + ), + ( + "content", + wagtail.blocks.StreamBlock( + [ + ( + "rich_text", + wagtail.blocks.RichTextBlock( + blank=True, + features=[ + "bold", + "italic", + "link", + "ul", + "ol", + "document-link", + ], + ), + ), + ( + "datawrapper", + wagtail.embeds.blocks.EmbedBlock( + help_text='Enter the "visualization only" link of the Datawrapper chart. It looks something like this: https://datawrapper.dwcdn.net/KwSKp/1/', + icon="image", + template="wagtailpages/blocks/datawrapper_block.html", + ), + ), + ( + "image", + wagtail.blocks.StructBlock( + [ + ( + "image", + wagtail.images.blocks.ImageChooserBlock(), + ), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", + required=True, + ), + ), + ] + ), + ), + ( + "video", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="For YouTube: go to your YouTube video and click “Share,” then “Embed,” and then copy and paste the provided URL only. For example: https://www.youtube.com/embed/3FIVXBawyQw For Vimeo: follow similar steps to grab the embed URL. For example: https://player.vimeo.com/video/9004979", + label="Embed URL", + ), + ), + ( + "caption", + wagtail.blocks.CharBlock(required=False), + ), + ( + "captionURL", + wagtail.blocks.CharBlock( + help_text="Optional URL for caption to link to.", + required=False, + ), + ), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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, + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "video_width", + wagtail.blocks.ChoiceBlock( + choices=[ + ("normal", "Normal"), + ("wide", "Wide"), + ("full_width", "Full Width"), + ], + help_text="Wide videos are col-12, Full-Width videos reach both ends of the screen.", + ), + ), + ] + ), + ), + ] + ), + ), + ] + ) + ), + ) + ] + ), + ), + ( + "paragraph", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + ], + template="wagtailpages/blocks/rich_text_block.html", + ), + ), + ( + "card_grid", + wagtail.blocks.StructBlock( + [ + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ("body", wagtail.blocks.TextBlock(help_text="Body text of the card.")), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that this card should link out to. (Note: If left blank, link will not render.) ", + required=False, + ), + ), + ( + "link_label", + wagtail.blocks.CharBlock( + help_text="Optional Label for the URL link above. (Note: If left blank, link will not render.) ", + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + ), + ) + ] + ), + ), + ( + "CTA_card", + wagtail.blocks.StructBlock( + [ + ( + "style", + wagtail.blocks.ChoiceBlock( + choices=[("pop", "Pop"), ("outline", "Outline"), ("filled", "Filled")] + ), + ), + ( + "title", + wagtail.blocks.CharBlock( + help_text="Optional title for the card.", max_length=100, required=False + ), + ), + ( + "body", + wagtail.blocks.RichTextBlock( + features=["bold", "italic", "link", "hr", "h4", "h5", "ul", "ol"], + help_text="Body text of the card.", + ), + ), + ( + "image", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", + required=True, + ), + ), + ] + ), + default=[], + max_num=1, + min_num=0, + ), + ), + ( + "button", + wagtail.blocks.ListBlock( + 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"', + 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 + ), + ), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ] + ), + default=[], + max_num=1, + min_num=0, + ), + ), + ] + ), + ), + ( + "CTA_card_with_text", + wagtail.blocks.StructBlock( + [ + ( + "alignment", + wagtail.blocks.ChoiceBlock( + choices=[("right", "Right"), ("left", "Left")], + help_text="For full-width cards, please use a regular Blog CTA Card block with a separate paragraph.", + ), + ), + ( + "card", + wagtail.blocks.StructBlock( + [ + ( + "style", + wagtail.blocks.ChoiceBlock( + choices=[ + ("pop", "Pop"), + ("outline", "Outline"), + ("filled", "Filled"), + ] + ), + ), + ( + "title", + wagtail.blocks.CharBlock( + help_text="Optional title for the card.", + max_length=100, + required=False, + ), + ), + ( + "body", + wagtail.blocks.RichTextBlock( + features=["bold", "italic", "link", "hr", "h4", "h5", "ul", "ol"], + help_text="Body text of the card.", + ), + ), + ( + "image", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", + required=True, + ), + ), + ] + ), + default=[], + max_num=1, + min_num=0, + ), + ), + ( + "button", + wagtail.blocks.ListBlock( + 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"', + 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 + ), + ), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ] + ), + default=[], + max_num=1, + min_num=0, + ), + ), + ], + required=True, + template="wagtailpages/blocks/blog_cta_card_block_regular.html", + ), + ), + ( + "paragraph", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + ], + help_text="Text to be displayed next to the card.", + template="wagtailpages/blocks/rich_text_block.html", + ), + ), + ] + ), + ), + ( + "image_grid", + wagtail.blocks.StructBlock( + [ + ( + "grid_items", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for this image.", required=False + ), + ), + ( + "caption", + wagtail.blocks.CharBlock( + help_text="Please remember to properly attribute any images we use.", + required=False, + ), + ), + ( + "url", + wagtail.blocks.CharBlock( + help_text="Optional URL that this figure should link out to.", + required=False, + ), + ), + ( + "square_image", + wagtail.blocks.BooleanBlock( + default=True, + help_text="If left checked, the image will be cropped to be square.", + required=False, + ), + ), + ] + ) + ), + ) + ] + ), + ), + ( + "iframe", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.CharBlock( + help_text="Please note that only URLs from allow-listed domains will work." + ), + ), + ( + "height", + wagtail.blocks.IntegerBlock( + help_text="Optional integer pixel value for custom iFrame height", + required=False, + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "iframe_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide iframes are col-12, Full-Width iframes reach both ends of the screen", + ), + ), + ( + "disable_scroll", + wagtail.blocks.BooleanBlock( + default=False, + help_text='Checking this will add "scrolling=no" to the iframe. Use this if your iframe is rendering an unnecessary scroll bar or whitespace below it.', + required=False, + ), + ), + ] + ), + ), + ( + "image", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "image_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide images are col-12, Full-Width Images reach both ends of the screen (16:6 images recommended for full width)", + ), + ), + ] + ), + ), + ( + "audio", + wagtail.blocks.StructBlock( + [ + ("audio", wagtailmedia.blocks.AudioChooserBlock()), + ("caption", wagtail.blocks.CharBlock(required=False)), + ] + ), + ), + ( + "image_text", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ( + "text", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + ] + ), + ), + ( + "url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this image should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ] + ), + ), + ( + "image_text_mini", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ("text", wagtail.blocks.RichTextBlock(features=["bold", "italic", "link"])), + ] + ), + ), + ( + "video", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="For YouTube: go to your YouTube video and click “Share,” then “Embed,” and then copy and paste the provided URL only. For example: https://www.youtube.com/embed/3FIVXBawyQw For Vimeo: follow similar steps to grab the embed URL. For example: https://player.vimeo.com/video/9004979", + label="Embed URL", + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "captionURL", + wagtail.blocks.CharBlock( + help_text="Optional URL for caption to link to.", required=False + ), + ), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "video_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide videos are col-12, Full-Width videos reach both ends of the screen.", + ), + ), + ] + ), + ), + ( + "linkbutton", + 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"', + 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), + ), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ] + ), + ), + ( + "looping_video", + wagtail.blocks.StructBlock( + [ + ( + "video_url", + wagtail.blocks.CharBlock( + help_text='Log into Vimeo using 1Password and upload the desired video. Then select the video and click "Advanced", "Distribution", and "Video File Links". Copy and paste the link here.', + label="Embed URL", + ), + ) + ] + ), + ), + ( + "pulse_listing", + wagtail.blocks.StructBlock( + [ + ( + "search_terms", + wagtail.blocks.CharBlock( + help_text="Test your search at mozillapulse.org/search", + label="Search", + required=False, + ), + ), + ( + "max_number_of_results", + wagtail.blocks.IntegerBlock( + default=6, + help_text="Choose 1-12. If you want visitors to see more, link to a search or tag on Pulse.", + max_value=12, + min_value=0, + required=True, + ), + ), + ( + "only_featured_entries", + wagtail.blocks.BooleanBlock( + default=False, + help_text="Featured items are selected by Pulse moderators.", + label="Display only featured entries", + required=False, + ), + ), + ( + "newest_first", + wagtail.blocks.ChoiceBlock( + choices=[ + ("True", "Show newer entries first"), + ("False", "Show older entries first"), + ], + label="Sort", + ), + ), + ( + "advanced_filter_header", + wagtail.blocks.static_block.StaticBlock( + admin_text="-------- ADVANCED FILTERS: OPTIONS TO DISPLAY FEWER, MORE TARGETED RESULTS. --------", + label=" ", + ), + ), + ( + "issues", + wagtail.blocks.ChoiceBlock( + choices=[ + ("all", "All"), + ("Decentralization", "Decentralization"), + ("Digital Inclusion", "Digital Inclusion"), + ("Online Privacy & Security", "Online Privacy & Security"), + ("Open Innovation", "Open Innovation"), + ("Web Literacy", "Web Literacy"), + ] + ), + ), + ( + "help", + wagtail.blocks.ChoiceBlock( + choices=[ + ("all", "All"), + ("Attend", "Attend"), + ("Create content", "Create content"), + ("Code", "Code"), + ("Design", "Design"), + ("Fundraise", "Fundraise"), + ("Join community", "Join community"), + ("Localize & translate", "Localize & translate"), + ("Mentor", "Mentor"), + ("Plan & organize", "Plan & organize"), + ("Promote", "Promote"), + ("Take action", "Take action"), + ("Test & feedback", "Test & feedback"), + ("Write documentation", "Write documentation"), + ], + label="Type of help needed", + ), + ), + ( + "direct_link", + wagtail.blocks.BooleanBlock( + default=False, + help_text="Checked: user goes to project link. Unchecked: user goes to pulse entry", + label="Direct link", + required=False, + ), + ), + ] + ), + ), + ( + "single_quote", + wagtail.blocks.StructBlock( + [ + ("quote", wagtail.blocks.RichTextBlock(features=["bold"])), + ("attribution", wagtail.blocks.CharBlock(required=False)), + ( + "attribution_info", + wagtail.blocks.RichTextBlock(features=["bold", "link", "large"], required=False), + ), + ] + ), + ), + ( + "slider", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock(help_text="Heading for the slider.", required=False), + ), + ( + "slides", + wagtail.blocks.StreamBlock( + [ + ( + "slide", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading of the card.", required=False + ), + ), + ( + "image", + wagtail.images.blocks.ImageChooserBlock( + help_text="The image associated with this event." + ), + ), + ( + "caption", + wagtail.blocks.TextBlock( + help_text="Caption for slider image", required=False + ), + ), + ( + "body", + wagtail.blocks.RichTextBlock( + blank=True, + features=["bold", "italic", "link", "large"], + required=False, + ), + ), + ( + "buttons", + wagtail.blocks.StreamBlock( + [ + ( + "internal", + wagtail.blocks.StructBlock( + [ + ( + "label", + wagtail.blocks.CharBlock( + help_text="Label for this link." + ), + ), + ( + "link", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to." + ), + ), + ] + ), + ), + ( + "external", + wagtail.blocks.StructBlock( + [ + ( + "label", + wagtail.blocks.CharBlock( + help_text="Label for this link." + ), + ), + ( + "link", + wagtail.blocks.URLBlock( + help_text="URL that this should link out to." + ), + ), + ] + ), + ), + ( + "document", + wagtail.blocks.StructBlock( + [ + ( + "label", + wagtail.blocks.CharBlock( + help_text="Label for this link." + ), + ), + ( + "document", + wagtail.documents.blocks.DocumentChooserBlock( + help_text="Document that this should link out to." + ), + ), + ], + help_text='An iCal document can be attached here for an "Add to Calendar" button.', + ), + ), + ], + help_text="A list of buttons that will appear at the bottom of the card.", + max_num=2, + required=False, + ), + ), + ] + ), + ) + ], + help_text="A list of slides.", + ), + ), + ] + ), + ), + ( + "spacer", + wagtail.blocks.StructBlock( + [ + ( + "size", + wagtail.blocks.ChoiceBlock( + choices=[ + ("1", "quarter spacing"), + ("2", "half spacing"), + ("3", "single spacing"), + ("4", "one and a half spacing"), + ("5", "triple spacing"), + ] + ), + ) + ] + ), + ), + ( + "airtable", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="Copied from the Airtable embed code. The word 'embed' will be in the url" + ), + ), + ( + "height", + wagtail.blocks.IntegerBlock( + default=533, + help_text="The pixel height on desktop view, usually copied from the Airtable embed code", + ), + ), + ] + ), + ), + ( + "datawrapper", + wagtail.embeds.blocks.EmbedBlock( + help_text='Enter the "visualization only" link of the Datawrapper chart. It looks something like this: https://datawrapper.dwcdn.net/KwSKp/1/', + icon="image", + template="wagtailpages/blocks/datawrapper_block.html", + ), + ), + ( + "typeform", + wagtail.blocks.StructBlock( + [ + ( + "embed_id", + wagtail.blocks.CharBlock( + help_text="The embed id of your Typeform page (e.g. if the form is on admin.typeform.com/form/e8zScc6t, the id will be: e8zScc6t)", + required=True, + ), + ), + ( + "button_type", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ( + "button_text", + wagtail.blocks.CharBlock( + help_text="This is a text prompt for users to open the typeform content", + required=True, + ), + ), + ] + ), + ), + ( + "newsletter_signup", + wagtail.blocks.StructBlock( + [("signup", wagtail.snippets.blocks.SnippetChooserBlock("wagtailpages.BlogSignup"))] + ), + ), + ], + use_json_field=True, + ), + ), + migrations.AlterField( + model_name="buyersguidearticlepage", + name="body", + field=wagtail.fields.StreamField( + [ + ( + "accordion", + wagtail.blocks.StructBlock( + [ + ( + "accordion_items", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the Accordion Item" + ), + ), + ( + "content", + wagtail.blocks.StreamBlock( + [ + ( + "rich_text", + wagtail.blocks.RichTextBlock( + blank=True, + features=[ + "bold", + "italic", + "link", + "ul", + "ol", + "document-link", + ], + ), + ), + ( + "datawrapper", + wagtail.embeds.blocks.EmbedBlock( + help_text='Enter the "visualization only" link of the Datawrapper chart. It looks something like this: https://datawrapper.dwcdn.net/KwSKp/1/', + icon="image", + template="wagtailpages/blocks/datawrapper_block.html", + ), + ), + ( + "image", + wagtail.blocks.StructBlock( + [ + ( + "image", + wagtail.images.blocks.ImageChooserBlock(), + ), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", + required=True, + ), + ), + ] + ), + ), + ( + "video", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="For YouTube: go to your YouTube video and click “Share,” then “Embed,” and then copy and paste the provided URL only. For example: https://www.youtube.com/embed/3FIVXBawyQw For Vimeo: follow similar steps to grab the embed URL. For example: https://player.vimeo.com/video/9004979", + label="Embed URL", + ), + ), + ( + "caption", + wagtail.blocks.CharBlock(required=False), + ), + ( + "captionURL", + wagtail.blocks.CharBlock( + help_text="Optional URL for caption to link to.", + required=False, + ), + ), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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, + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "video_width", + wagtail.blocks.ChoiceBlock( + choices=[ + ("normal", "Normal"), + ("wide", "Wide"), + ("full_width", "Full Width"), + ], + help_text="Wide videos are col-12, Full-Width videos reach both ends of the screen.", + ), + ), + ] + ), + ), + ] + ), + ), + ] + ) + ), + ) + ] + ), + ), + ( + "paragraph", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + ], + template="wagtailpages/blocks/rich_text_block.html", + ), + ), + ( + "card_grid", + wagtail.blocks.StructBlock( + [ + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ("body", wagtail.blocks.TextBlock(help_text="Body text of the card.")), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that this card should link out to. (Note: If left blank, link will not render.) ", + required=False, + ), + ), + ( + "link_label", + wagtail.blocks.CharBlock( + help_text="Optional Label for the URL link above. (Note: If left blank, link will not render.) ", + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + ), + ) + ] + ), + ), + ( + "image_grid", + wagtail.blocks.StructBlock( + [ + ( + "grid_items", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for this image.", required=False + ), + ), + ( + "caption", + wagtail.blocks.CharBlock( + help_text="Please remember to properly attribute any images we use.", + required=False, + ), + ), + ( + "url", + wagtail.blocks.CharBlock( + help_text="Optional URL that this figure should link out to.", + required=False, + ), + ), + ( + "square_image", + wagtail.blocks.BooleanBlock( + default=True, + help_text="If left checked, the image will be cropped to be square.", + required=False, + ), + ), + ] + ) + ), + ) + ] + ), + ), + ( + "iframe", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.CharBlock( + help_text="Please note that only URLs from allow-listed domains will work." + ), + ), + ( + "height", + wagtail.blocks.IntegerBlock( + help_text="Optional integer pixel value for custom iFrame height", + required=False, + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "iframe_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide iframes are col-12, Full-Width iframes reach both ends of the screen", + ), + ), + ( + "disable_scroll", + wagtail.blocks.BooleanBlock( + default=False, + help_text='Checking this will add "scrolling=no" to the iframe. Use this if your iframe is rendering an unnecessary scroll bar or whitespace below it.', + required=False, + ), + ), + ] + ), + ), + ( + "image", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "image_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide images are col-12, Full-Width Images reach both ends of the screen (16:6 images recommended for full width)", + ), + ), + ] + ), + ), + ( + "audio", + wagtail.blocks.StructBlock( + [ + ("audio", wagtailmedia.blocks.AudioChooserBlock()), + ("caption", wagtail.blocks.CharBlock(required=False)), + ] + ), + ), + ( + "image_text", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ( + "text", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + ] + ), + ), + ( + "url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this image should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ] + ), + ), + ( + "image_text_mini", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ("text", wagtail.blocks.RichTextBlock(features=["bold", "italic", "link"])), + ] + ), + ), + ( + "video", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="For YouTube: go to your YouTube video and click “Share,” then “Embed,” and then copy and paste the provided URL only. For example: https://www.youtube.com/embed/3FIVXBawyQw For Vimeo: follow similar steps to grab the embed URL. For example: https://player.vimeo.com/video/9004979", + label="Embed URL", + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "captionURL", + wagtail.blocks.CharBlock( + help_text="Optional URL for caption to link to.", required=False + ), + ), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "video_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide videos are col-12, Full-Width videos reach both ends of the screen.", + ), + ), + ] + ), + ), + ( + "linkbutton", + 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"', + 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), + ), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ] + ), + ), + ( + "looping_video", + wagtail.blocks.StructBlock( + [ + ( + "video_url", + wagtail.blocks.CharBlock( + help_text='Log into Vimeo using 1Password and upload the desired video. Then select the video and click "Advanced", "Distribution", and "Video File Links". Copy and paste the link here.', + label="Embed URL", + ), + ) + ] + ), + ), + ( + "pulse_listing", + wagtail.blocks.StructBlock( + [ + ( + "search_terms", + wagtail.blocks.CharBlock( + help_text="Test your search at mozillapulse.org/search", + label="Search", + required=False, + ), + ), + ( + "max_number_of_results", + wagtail.blocks.IntegerBlock( + default=6, + help_text="Choose 1-12. If you want visitors to see more, link to a search or tag on Pulse.", + max_value=12, + min_value=0, + required=True, + ), + ), + ( + "only_featured_entries", + wagtail.blocks.BooleanBlock( + default=False, + help_text="Featured items are selected by Pulse moderators.", + label="Display only featured entries", + required=False, + ), + ), + ( + "newest_first", + wagtail.blocks.ChoiceBlock( + choices=[ + ("True", "Show newer entries first"), + ("False", "Show older entries first"), + ], + label="Sort", + ), + ), + ( + "advanced_filter_header", + wagtail.blocks.static_block.StaticBlock( + admin_text="-------- ADVANCED FILTERS: OPTIONS TO DISPLAY FEWER, MORE TARGETED RESULTS. --------", + label=" ", + ), + ), + ( + "issues", + wagtail.blocks.ChoiceBlock( + choices=[ + ("all", "All"), + ("Decentralization", "Decentralization"), + ("Digital Inclusion", "Digital Inclusion"), + ("Online Privacy & Security", "Online Privacy & Security"), + ("Open Innovation", "Open Innovation"), + ("Web Literacy", "Web Literacy"), + ] + ), + ), + ( + "help", + wagtail.blocks.ChoiceBlock( + choices=[ + ("all", "All"), + ("Attend", "Attend"), + ("Create content", "Create content"), + ("Code", "Code"), + ("Design", "Design"), + ("Fundraise", "Fundraise"), + ("Join community", "Join community"), + ("Localize & translate", "Localize & translate"), + ("Mentor", "Mentor"), + ("Plan & organize", "Plan & organize"), + ("Promote", "Promote"), + ("Take action", "Take action"), + ("Test & feedback", "Test & feedback"), + ("Write documentation", "Write documentation"), + ], + label="Type of help needed", + ), + ), + ( + "direct_link", + wagtail.blocks.BooleanBlock( + default=False, + help_text="Checked: user goes to project link. Unchecked: user goes to pulse entry", + label="Direct link", + required=False, + ), + ), + ] + ), + ), + ( + "single_quote", + wagtail.blocks.StructBlock( + [ + ("quote", wagtail.blocks.RichTextBlock(features=["bold"])), + ("attribution", wagtail.blocks.CharBlock(required=False)), + ( + "attribution_info", + wagtail.blocks.RichTextBlock(features=["bold", "link", "large"], required=False), + ), + ] + ), + ), + ( + "slider", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock(help_text="Heading for the slider.", required=False), + ), + ( + "slides", + wagtail.blocks.StreamBlock( + [ + ( + "slide", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading of the card.", required=False + ), + ), + ( + "image", + wagtail.images.blocks.ImageChooserBlock( + help_text="The image associated with this event." + ), + ), + ( + "caption", + wagtail.blocks.TextBlock( + help_text="Caption for slider image", required=False + ), + ), + ( + "body", + wagtail.blocks.RichTextBlock( + blank=True, + features=["bold", "italic", "link", "large"], + required=False, + ), + ), + ( + "buttons", + wagtail.blocks.StreamBlock( + [ + ( + "internal", + wagtail.blocks.StructBlock( + [ + ( + "label", + wagtail.blocks.CharBlock( + help_text="Label for this link." + ), + ), + ( + "link", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to." + ), + ), + ] + ), + ), + ( + "external", + wagtail.blocks.StructBlock( + [ + ( + "label", + wagtail.blocks.CharBlock( + help_text="Label for this link." + ), + ), + ( + "link", + wagtail.blocks.URLBlock( + help_text="URL that this should link out to." + ), + ), + ] + ), + ), + ( + "document", + wagtail.blocks.StructBlock( + [ + ( + "label", + wagtail.blocks.CharBlock( + help_text="Label for this link." + ), + ), + ( + "document", + wagtail.documents.blocks.DocumentChooserBlock( + help_text="Document that this should link out to." + ), + ), + ], + help_text='An iCal document can be attached here for an "Add to Calendar" button.', + ), + ), + ], + help_text="A list of buttons that will appear at the bottom of the card.", + max_num=2, + required=False, + ), + ), + ] + ), + ) + ], + help_text="A list of slides.", + ), + ), + ] + ), + ), + ( + "spacer", + wagtail.blocks.StructBlock( + [ + ( + "size", + wagtail.blocks.ChoiceBlock( + choices=[ + ("1", "quarter spacing"), + ("2", "half spacing"), + ("3", "single spacing"), + ("4", "one and a half spacing"), + ("5", "triple spacing"), + ] + ), + ) + ] + ), + ), + ( + "airtable", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="Copied from the Airtable embed code. The word 'embed' will be in the url" + ), + ), + ( + "height", + wagtail.blocks.IntegerBlock( + default=533, + help_text="The pixel height on desktop view, usually copied from the Airtable embed code", + ), + ), + ] + ), + ), + ( + "datawrapper", + wagtail.embeds.blocks.EmbedBlock( + help_text='Enter the "visualization only" link of the Datawrapper chart. It looks something like this: https://datawrapper.dwcdn.net/KwSKp/1/', + icon="image", + template="wagtailpages/blocks/datawrapper_block.html", + ), + ), + ( + "typeform", + wagtail.blocks.StructBlock( + [ + ( + "embed_id", + wagtail.blocks.CharBlock( + help_text="The embed id of your Typeform page (e.g. if the form is on admin.typeform.com/form/e8zScc6t, the id will be: e8zScc6t)", + required=True, + ), + ), + ( + "button_type", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ( + "button_text", + wagtail.blocks.CharBlock( + help_text="This is a text prompt for users to open the typeform content", + required=True, + ), + ), + ] + ), + ), + ], + null=True, + use_json_field=True, + ), + ), + migrations.AlterField( + model_name="buyersguidecampaignpage", + name="body", + field=wagtail.fields.StreamField( + [ + ( + "accordion", + wagtail.blocks.StructBlock( + [ + ( + "accordion_items", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the Accordion Item" + ), + ), + ( + "content", + wagtail.blocks.StreamBlock( + [ + ( + "rich_text", + wagtail.blocks.RichTextBlock( + blank=True, + features=[ + "bold", + "italic", + "link", + "ul", + "ol", + "document-link", + ], + ), + ), + ( + "datawrapper", + wagtail.embeds.blocks.EmbedBlock( + help_text='Enter the "visualization only" link of the Datawrapper chart. It looks something like this: https://datawrapper.dwcdn.net/KwSKp/1/', + icon="image", + template="wagtailpages/blocks/datawrapper_block.html", + ), + ), + ( + "image", + wagtail.blocks.StructBlock( + [ + ( + "image", + wagtail.images.blocks.ImageChooserBlock(), + ), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", + required=True, + ), + ), + ] + ), + ), + ( + "video", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="For YouTube: go to your YouTube video and click “Share,” then “Embed,” and then copy and paste the provided URL only. For example: https://www.youtube.com/embed/3FIVXBawyQw For Vimeo: follow similar steps to grab the embed URL. For example: https://player.vimeo.com/video/9004979", + label="Embed URL", + ), + ), + ( + "caption", + wagtail.blocks.CharBlock(required=False), + ), + ( + "captionURL", + wagtail.blocks.CharBlock( + help_text="Optional URL for caption to link to.", + required=False, + ), + ), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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, + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "video_width", + wagtail.blocks.ChoiceBlock( + choices=[ + ("normal", "Normal"), + ("wide", "Wide"), + ("full_width", "Full Width"), + ], + help_text="Wide videos are col-12, Full-Width videos reach both ends of the screen.", + ), + ), + ] + ), + ), + ] + ), + ), + ] + ) + ), + ) + ] + ), + ), + ( + "paragraph", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + ], + template="wagtailpages/blocks/rich_text_block.html", + ), + ), + ( + "card_grid", + wagtail.blocks.StructBlock( + [ + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ("body", wagtail.blocks.TextBlock(help_text="Body text of the card.")), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that this card should link out to. (Note: If left blank, link will not render.) ", + required=False, + ), + ), + ( + "link_label", + wagtail.blocks.CharBlock( + help_text="Optional Label for the URL link above. (Note: If left blank, link will not render.) ", + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + ), + ) + ] + ), + ), + ( + "image_grid", + wagtail.blocks.StructBlock( + [ + ( + "grid_items", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for this image.", required=False + ), + ), + ( + "caption", + wagtail.blocks.CharBlock( + help_text="Please remember to properly attribute any images we use.", + required=False, + ), + ), + ( + "url", + wagtail.blocks.CharBlock( + help_text="Optional URL that this figure should link out to.", + required=False, + ), + ), + ( + "square_image", + wagtail.blocks.BooleanBlock( + default=True, + help_text="If left checked, the image will be cropped to be square.", + required=False, + ), + ), + ] + ) + ), + ) + ] + ), + ), + ( + "iframe", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.CharBlock( + help_text="Please note that only URLs from allow-listed domains will work." + ), + ), + ( + "height", + wagtail.blocks.IntegerBlock( + help_text="Optional integer pixel value for custom iFrame height", + required=False, + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "iframe_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide iframes are col-12, Full-Width iframes reach both ends of the screen", + ), + ), + ( + "disable_scroll", + wagtail.blocks.BooleanBlock( + default=False, + help_text='Checking this will add "scrolling=no" to the iframe. Use this if your iframe is rendering an unnecessary scroll bar or whitespace below it.', + required=False, + ), + ), + ] + ), + ), + ( + "image", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "image_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide images are col-12, Full-Width Images reach both ends of the screen (16:6 images recommended for full width)", + ), + ), + ] + ), + ), + ( + "audio", + wagtail.blocks.StructBlock( + [ + ("audio", wagtailmedia.blocks.AudioChooserBlock()), + ("caption", wagtail.blocks.CharBlock(required=False)), + ] + ), + ), + ( + "image_text", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ( + "text", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + ] + ), + ), + ( + "url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this image should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ] + ), + ), + ( + "image_text_mini", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ("text", wagtail.blocks.RichTextBlock(features=["bold", "italic", "link"])), + ] + ), + ), + ( + "video", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="For YouTube: go to your YouTube video and click “Share,” then “Embed,” and then copy and paste the provided URL only. For example: https://www.youtube.com/embed/3FIVXBawyQw For Vimeo: follow similar steps to grab the embed URL. For example: https://player.vimeo.com/video/9004979", + label="Embed URL", + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "captionURL", + wagtail.blocks.CharBlock( + help_text="Optional URL for caption to link to.", required=False + ), + ), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "video_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide videos are col-12, Full-Width videos reach both ends of the screen.", + ), + ), + ] + ), + ), + ( + "linkbutton", + 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"', + 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), + ), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ] + ), + ), + ( + "looping_video", + wagtail.blocks.StructBlock( + [ + ( + "video_url", + wagtail.blocks.CharBlock( + help_text='Log into Vimeo using 1Password and upload the desired video. Then select the video and click "Advanced", "Distribution", and "Video File Links". Copy and paste the link here.', + label="Embed URL", + ), + ) + ] + ), + ), + ( + "pulse_listing", + wagtail.blocks.StructBlock( + [ + ( + "search_terms", + wagtail.blocks.CharBlock( + help_text="Test your search at mozillapulse.org/search", + label="Search", + required=False, + ), + ), + ( + "max_number_of_results", + wagtail.blocks.IntegerBlock( + default=6, + help_text="Choose 1-12. If you want visitors to see more, link to a search or tag on Pulse.", + max_value=12, + min_value=0, + required=True, + ), + ), + ( + "only_featured_entries", + wagtail.blocks.BooleanBlock( + default=False, + help_text="Featured items are selected by Pulse moderators.", + label="Display only featured entries", + required=False, + ), + ), + ( + "newest_first", + wagtail.blocks.ChoiceBlock( + choices=[ + ("True", "Show newer entries first"), + ("False", "Show older entries first"), + ], + label="Sort", + ), + ), + ( + "advanced_filter_header", + wagtail.blocks.static_block.StaticBlock( + admin_text="-------- ADVANCED FILTERS: OPTIONS TO DISPLAY FEWER, MORE TARGETED RESULTS. --------", + label=" ", + ), + ), + ( + "issues", + wagtail.blocks.ChoiceBlock( + choices=[ + ("all", "All"), + ("Decentralization", "Decentralization"), + ("Digital Inclusion", "Digital Inclusion"), + ("Online Privacy & Security", "Online Privacy & Security"), + ("Open Innovation", "Open Innovation"), + ("Web Literacy", "Web Literacy"), + ] + ), + ), + ( + "help", + wagtail.blocks.ChoiceBlock( + choices=[ + ("all", "All"), + ("Attend", "Attend"), + ("Create content", "Create content"), + ("Code", "Code"), + ("Design", "Design"), + ("Fundraise", "Fundraise"), + ("Join community", "Join community"), + ("Localize & translate", "Localize & translate"), + ("Mentor", "Mentor"), + ("Plan & organize", "Plan & organize"), + ("Promote", "Promote"), + ("Take action", "Take action"), + ("Test & feedback", "Test & feedback"), + ("Write documentation", "Write documentation"), + ], + label="Type of help needed", + ), + ), + ( + "direct_link", + wagtail.blocks.BooleanBlock( + default=False, + help_text="Checked: user goes to project link. Unchecked: user goes to pulse entry", + label="Direct link", + required=False, + ), + ), + ] + ), + ), + ( + "single_quote", + wagtail.blocks.StructBlock( + [ + ("quote", wagtail.blocks.RichTextBlock(features=["bold"])), + ("attribution", wagtail.blocks.CharBlock(required=False)), + ( + "attribution_info", + wagtail.blocks.RichTextBlock(features=["bold", "link", "large"], required=False), + ), + ] + ), + ), + ( + "slider", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock(help_text="Heading for the slider.", required=False), + ), + ( + "slides", + wagtail.blocks.StreamBlock( + [ + ( + "slide", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading of the card.", required=False + ), + ), + ( + "image", + wagtail.images.blocks.ImageChooserBlock( + help_text="The image associated with this event." + ), + ), + ( + "caption", + wagtail.blocks.TextBlock( + help_text="Caption for slider image", required=False + ), + ), + ( + "body", + wagtail.blocks.RichTextBlock( + blank=True, + features=["bold", "italic", "link", "large"], + required=False, + ), + ), + ( + "buttons", + wagtail.blocks.StreamBlock( + [ + ( + "internal", + wagtail.blocks.StructBlock( + [ + ( + "label", + wagtail.blocks.CharBlock( + help_text="Label for this link." + ), + ), + ( + "link", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to." + ), + ), + ] + ), + ), + ( + "external", + wagtail.blocks.StructBlock( + [ + ( + "label", + wagtail.blocks.CharBlock( + help_text="Label for this link." + ), + ), + ( + "link", + wagtail.blocks.URLBlock( + help_text="URL that this should link out to." + ), + ), + ] + ), + ), + ( + "document", + wagtail.blocks.StructBlock( + [ + ( + "label", + wagtail.blocks.CharBlock( + help_text="Label for this link." + ), + ), + ( + "document", + wagtail.documents.blocks.DocumentChooserBlock( + help_text="Document that this should link out to." + ), + ), + ], + help_text='An iCal document can be attached here for an "Add to Calendar" button.', + ), + ), + ], + help_text="A list of buttons that will appear at the bottom of the card.", + max_num=2, + required=False, + ), + ), + ] + ), + ) + ], + help_text="A list of slides.", + ), + ), + ] + ), + ), + ( + "spacer", + wagtail.blocks.StructBlock( + [ + ( + "size", + wagtail.blocks.ChoiceBlock( + choices=[ + ("1", "quarter spacing"), + ("2", "half spacing"), + ("3", "single spacing"), + ("4", "one and a half spacing"), + ("5", "triple spacing"), + ] + ), + ) + ] + ), + ), + ( + "airtable", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="Copied from the Airtable embed code. The word 'embed' will be in the url" + ), + ), + ( + "height", + wagtail.blocks.IntegerBlock( + default=533, + help_text="The pixel height on desktop view, usually copied from the Airtable embed code", + ), + ), + ] + ), + ), + ( + "datawrapper", + wagtail.embeds.blocks.EmbedBlock( + help_text='Enter the "visualization only" link of the Datawrapper chart. It looks something like this: https://datawrapper.dwcdn.net/KwSKp/1/', + icon="image", + template="wagtailpages/blocks/datawrapper_block.html", + ), + ), + ( + "typeform", + wagtail.blocks.StructBlock( + [ + ( + "embed_id", + wagtail.blocks.CharBlock( + help_text="The embed id of your Typeform page (e.g. if the form is on admin.typeform.com/form/e8zScc6t, the id will be: e8zScc6t)", + required=True, + ), + ), + ( + "button_type", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ( + "button_text", + wagtail.blocks.CharBlock( + help_text="This is a text prompt for users to open the typeform content", + required=True, + ), + ), + ] + ), + ), + ], + use_json_field=True, + ), + ), + migrations.AlterField( + model_name="modularpage", + name="body", + field=wagtail.fields.StreamField( + [ + ( + "paragraph", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + "large", + ], + template="wagtailpages/blocks/rich_text_block.html", + ), + ), + ( + "card_grid", + wagtail.blocks.StructBlock( + [ + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ("body", wagtail.blocks.TextBlock(help_text="Body text of the card.")), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that this card should link out to. (Note: If left blank, link will not render.) ", + required=False, + ), + ), + ( + "link_label", + wagtail.blocks.CharBlock( + help_text="Optional Label for the URL link above. (Note: If left blank, link will not render.) ", + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + ), + ) + ] + ), + ), + ( + "image", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "image_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide images are col-12, Full-Width Images reach both ends of the screen (16:6 images recommended for full width)", + ), + ), + ] + ), + ), + ( + "image_text", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ( + "text", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + ] + ), + ), + ( + "url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this image should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ] + ), + ), + ( + "image_text_mini", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ("text", wagtail.blocks.RichTextBlock(features=["bold", "italic", "link"])), + ] + ), + ), + ( + "image_grid", + wagtail.blocks.StructBlock( + [ + ( + "grid_items", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for this image.", required=False + ), + ), + ( + "caption", + wagtail.blocks.CharBlock( + help_text="Please remember to properly attribute any images we use.", + required=False, + ), + ), + ( + "url", + wagtail.blocks.CharBlock( + help_text="Optional URL that this figure should link out to.", + required=False, + ), + ), + ( + "square_image", + wagtail.blocks.BooleanBlock( + default=True, + help_text="If left checked, the image will be cropped to be square.", + required=False, + ), + ), + ] + ) + ), + ) + ] + ), + ), + ( + "video", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="For YouTube: go to your YouTube video and click “Share,” then “Embed,” and then copy and paste the provided URL only. For example: https://www.youtube.com/embed/3FIVXBawyQw For Vimeo: follow similar steps to grab the embed URL. For example: https://player.vimeo.com/video/9004979", + label="Embed URL", + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "captionURL", + wagtail.blocks.CharBlock( + help_text="Optional URL for caption to link to.", required=False + ), + ), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "video_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide videos are col-12, Full-Width videos reach both ends of the screen.", + ), + ), + ] + ), + ), + ( + "iframe", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.CharBlock( + help_text="Please note that only URLs from allow-listed domains will work." + ), + ), + ( + "height", + wagtail.blocks.IntegerBlock( + help_text="Optional integer pixel value for custom iFrame height", + required=False, + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "iframe_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide iframes are col-12, Full-Width iframes reach both ends of the screen", + ), + ), + ( + "disable_scroll", + wagtail.blocks.BooleanBlock( + default=False, + help_text='Checking this will add "scrolling=no" to the iframe. Use this if your iframe is rendering an unnecessary scroll bar or whitespace below it.', + required=False, + ), + ), + ] + ), + ), + ( + "linkbutton", + 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"', + 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), + ), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ] + ), + ), + ( + "spacer", + wagtail.blocks.StructBlock( + [ + ( + "size", + wagtail.blocks.ChoiceBlock( + choices=[ + ("1", "quarter spacing"), + ("2", "half spacing"), + ("3", "single spacing"), + ("4", "one and a half spacing"), + ("5", "triple spacing"), + ] + ), + ) + ] + ), + ), + ( + "single_quote", + wagtail.blocks.StructBlock( + [ + ("quote", wagtail.blocks.RichTextBlock(features=["bold"])), + ("attribution", wagtail.blocks.CharBlock(required=False)), + ( + "attribution_info", + wagtail.blocks.RichTextBlock(features=["bold", "link", "large"], required=False), + ), + ] + ), + ), + ( + "pulse_listing", + wagtail.blocks.StructBlock( + [ + ( + "search_terms", + wagtail.blocks.CharBlock( + help_text="Test your search at mozillapulse.org/search", + label="Search", + required=False, + ), + ), + ( + "max_number_of_results", + wagtail.blocks.IntegerBlock( + default=6, + help_text="Choose 1-12. If you want visitors to see more, link to a search or tag on Pulse.", + max_value=12, + min_value=0, + required=True, + ), + ), + ( + "only_featured_entries", + wagtail.blocks.BooleanBlock( + default=False, + help_text="Featured items are selected by Pulse moderators.", + label="Display only featured entries", + required=False, + ), + ), + ( + "newest_first", + wagtail.blocks.ChoiceBlock( + choices=[ + ("True", "Show newer entries first"), + ("False", "Show older entries first"), + ], + label="Sort", + ), + ), + ( + "advanced_filter_header", + wagtail.blocks.static_block.StaticBlock( + admin_text="-------- ADVANCED FILTERS: OPTIONS TO DISPLAY FEWER, MORE TARGETED RESULTS. --------", + label=" ", + ), + ), + ( + "issues", + wagtail.blocks.ChoiceBlock( + choices=[ + ("all", "All"), + ("Decentralization", "Decentralization"), + ("Digital Inclusion", "Digital Inclusion"), + ("Online Privacy & Security", "Online Privacy & Security"), + ("Open Innovation", "Open Innovation"), + ("Web Literacy", "Web Literacy"), + ] + ), + ), + ( + "help", + wagtail.blocks.ChoiceBlock( + choices=[ + ("all", "All"), + ("Attend", "Attend"), + ("Create content", "Create content"), + ("Code", "Code"), + ("Design", "Design"), + ("Fundraise", "Fundraise"), + ("Join community", "Join community"), + ("Localize & translate", "Localize & translate"), + ("Mentor", "Mentor"), + ("Plan & organize", "Plan & organize"), + ("Promote", "Promote"), + ("Take action", "Take action"), + ("Test & feedback", "Test & feedback"), + ("Write documentation", "Write documentation"), + ], + label="Type of help needed", + ), + ), + ( + "direct_link", + wagtail.blocks.BooleanBlock( + default=False, + help_text="Checked: user goes to project link. Unchecked: user goes to pulse entry", + label="Direct link", + required=False, + ), + ), + ] + ), + ), + ( + "profile_listing", + wagtail.blocks.StructBlock( + [ + ( + "max_number_of_results", + wagtail.blocks.IntegerBlock( + default=12, + help_text="Pick up to 48 profiles.", + max_value=48, + min_value=1, + required=True, + ), + ), + ( + "advanced_filter_header", + wagtail.blocks.static_block.StaticBlock( + admin_text="-------- ADVANCED FILTERS: OPTIONS TO DISPLAY FEWER, MORE TARGETED RESULTS. --------", + label=" ", + ), + ), + ( + "profile_type", + wagtail.blocks.CharBlock(default="", help_text="Example: Fellow.", required=False), + ), + ( + "program_type", + wagtail.blocks.CharBlock( + default="", help_text="Example: Tech Policy.", required=False + ), + ), + ("year", wagtail.blocks.CharBlock(default="", required=False)), + ] + ), + ), + ( + "profile_by_id", + wagtail.blocks.StructBlock( + [ + ( + "ids", + wagtail.blocks.CharBlock( + help_text="Show profiles for pulse users with specific profile ids (mozillapulse.org/profile/[##]). For multiple profiles, specify a comma separated list (e.g. 85,105,332).", + label="Profile by ID", + ), + ) + ] + ), + ), + ( + "profile_directory", + wagtail.blocks.StructBlock( + [ + ( + "max_number_of_results", + wagtail.blocks.IntegerBlock( + default=12, + help_text="Pick up to 48 profiles.", + max_value=48, + min_value=1, + required=True, + ), + ), + ( + "advanced_filter_header", + wagtail.blocks.static_block.StaticBlock( + admin_text="-------- ADVANCED FILTERS: OPTIONS TO DISPLAY FEWER, MORE TARGETED RESULTS. --------", + label=" ", + ), + ), + ( + "profile_type", + wagtail.blocks.CharBlock(default="", help_text="Example: Fellow.", required=False), + ), + ( + "program_type", + wagtail.blocks.CharBlock( + default="", help_text="Example: Tech Policy.", required=False + ), + ), + ("year", wagtail.blocks.CharBlock(default="", required=False)), + ( + "filter_values", + wagtail.blocks.CharBlock( + default="2019,2018,2017,2016,2015,2014,2013", + help_text="Example: 2019,2018,2017,2016,2015,2014,2013", + required=True, + ), + ), + ] + ), + ), + ( + "recent_blog_entries", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock(required=False)), + ( + "tag_filter", + wagtail.blocks.CharBlock( + help_text="Test this filter at foundation.mozilla.org/blog/tags/", + label="Filter by Tag", + required=False, + ), + ), + ( + "topic_filter", + wagtail.blocks.ChoiceBlock( + choices=networkapi.wagtailpages.pagemodels.blog.blog_topic.BlogPageTopic.get_topics, + help_text="Test this filter at foundation.mozilla.org/blog/topic/", + label="Filter by Topic", + required=False, + ), + ), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ] + ), + ), + ( + "blog_set", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock()), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ( + "blog_pages", + wagtail.blocks.ListBlock( + wagtail.blocks.PageChooserBlock(page_type=["wagtailpages.BlogPage"]) + ), + ), + ] + ), + ), + ( + "airtable", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="Copied from the Airtable embed code. The word 'embed' will be in the url" + ), + ), + ( + "height", + wagtail.blocks.IntegerBlock( + default=533, + help_text="The pixel height on desktop view, usually copied from the Airtable embed code", + ), + ), + ] + ), + ), + ( + "typeform", + wagtail.blocks.StructBlock( + [ + ( + "embed_id", + wagtail.blocks.CharBlock( + help_text="The embed id of your Typeform page (e.g. if the form is on admin.typeform.com/form/e8zScc6t, the id will be: e8zScc6t)", + required=True, + ), + ), + ( + "button_type", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ( + "button_text", + wagtail.blocks.CharBlock( + help_text="This is a text prompt for users to open the typeform content", + required=True, + ), + ), + ] + ), + ), + ( + "datawrapper", + wagtail.embeds.blocks.EmbedBlock( + help_text='Enter the "visualization only" link of the Datawrapper chart. It looks something like this: https://datawrapper.dwcdn.net/KwSKp/1/', + icon="image", + template="wagtailpages/blocks/datawrapper_block.html", + ), + ), + ( + "listing", + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock(help_text="Heading for the block.", required=False), + ), + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ( + "highlighted_metadata", + wagtail.blocks.CharBlock( + help_text="Metadata to highlight on the card.", required=False + ), + ), + ( + "metadata", + wagtail.blocks.CharBlock( + help_text="Generic metadata.", required=False + ), + ), + ( + "body", + wagtail.blocks.RichTextBlock( + features=["bold"], + help_text="Body text of the card.", + required=False, + ), + ), + ( + "link_page", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to.", required=False + ), + ), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that the header should link out to.", + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + min_num=2, + ), + ), + ( + "cards_per_row", + wagtail.blocks.ChoiceBlock( + choices=[(2, "2"), (3, "3")], + help_text="Number of cards per row. Note: this is a max and fewer might be used if is less space is available.", + required=False, + ), + ), + ] + ), + ), + ( + "profiles", + wagtail.blocks.StructBlock( + [ + ( + "profiles", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "profile", + wagtail.snippets.blocks.SnippetChooserBlock( + networkapi.wagtailpages.pagemodels.profiles.Profile + ), + ) + ] + ), + min_num=1, + ), + ) + ] + ), + ), + ( + "article_teaser_block", + wagtail.blocks.StructBlock( + [ + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "article", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to.", + page_type=["wagtailpages.ArticlePage"], + required=False, + ), + ) + ] + ), + help_text="Please use a minimum of 3 cards.", + min_num=3, + ), + ) + ] + ), + ), + ( + "group_listing_block", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the group of cards.", required=False + ), + ), + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ( + "meta_data", + wagtail.blocks.CharBlock( + help_text="Optional meta data information for the card.", + required=False, + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ( + "body", + wagtail.blocks.RichTextBlock( + features=["bold", "link"], help_text="Body text of the card." + ), + ), + ( + "url", + wagtail.blocks.CharBlock( + help_text="The URL this card should link to.", required=False + ), + ), + ] + ) + ), + ), + ] + ), + ), + ( + "image_feature", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock(help_text="Image description (for screen readers)."), + ), + ("metadata", wagtail.blocks.CharBlock(required=False)), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ( + "title_link", + wagtail.blocks.PageChooserBlock( + help_text="Page that the title should link out to.", required=False + ), + ), + ("body", wagtail.blocks.CharBlock(required=False)), + ] + ), + ), + ( + "image_teaser_block", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ("text", wagtail.blocks.RichTextBlock(features=["bold"])), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ("url_label", wagtail.blocks.CharBlock(required=False)), + ("url", wagtail.blocks.CharBlock(required=False)), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ] + ), + ), + ( + "text_only_teaser", + wagtail.blocks.StructBlock( + [ + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock(help_text="Heading for the card."), + ), + ( + "link_page", + wagtail.blocks.PageChooserBlock( + help_text="Page that the header should link out to.", + required=False, + ), + ), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that the header should link out to.", + required=False, + ), + ), + ("meta_data", wagtail.blocks.CharBlock(max_length=500)), + ( + "body", + wagtail.blocks.TextBlock( + help_text="Body text of the card.", + max_length=200, + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 3 cards.", + min_num=3, + ), + ) + ] + ), + ), + ( + "block_with_aside", + wagtail.blocks.StructBlock( + [ + ( + "content", + wagtail.blocks.StreamBlock( + [ + ( + "listing", + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock( + help_text="Heading for the block.", required=False + ), + ), + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "image", + wagtail.images.blocks.ImageChooserBlock(), + ), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", + required=False, + ), + ), + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the card." + ), + ), + ( + "highlighted_metadata", + wagtail.blocks.CharBlock( + help_text="Metadata to highlight on the card.", + required=False, + ), + ), + ( + "metadata", + wagtail.blocks.CharBlock( + help_text="Generic metadata.", + required=False, + ), + ), + ( + "body", + wagtail.blocks.RichTextBlock( + features=["bold"], + help_text="Body text of the card.", + required=False, + ), + ), + ( + "link_page", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to.", + required=False, + ), + ), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that the header should link out to.", + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + min_num=2, + ), + ), + ( + "cards_per_row", + wagtail.blocks.ChoiceBlock( + choices=[(2, "2"), (3, "3")], + help_text="Number of cards per row. Note: this is a max and fewer might be used if is less space is available.", + required=False, + ), + ), + ] + ), + ), + ( + "paragraph", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + ] + ), + ), + ], + help_text="The wider block that appears on the left on desktop", + icon="doc-full", + max_num=1, + ), + ), + ( + "aside", + wagtail.blocks.StreamBlock( + [ + ( + "aside_content", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the card.", required=False + ), + ), + ( + "body", + wagtail.blocks.TextBlock( + help_text="Body text of the card.", required=False + ), + ), + ] + ), + ), + ( + "linkbutton", + 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"', + 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 + ), + ), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ] + ), + ), + ( + "spacer", + wagtail.blocks.StructBlock( + [ + ( + "size", + wagtail.blocks.ChoiceBlock( + choices=[ + ("1", "quarter spacing"), + ("2", "half spacing"), + ("3", "single spacing"), + ("4", "one and a half spacing"), + ("5", "triple spacing"), + ] + ), + ) + ] + ), + ), + ], + help_text="Elements here will appear in the column on the right side of the page on desktop. This can be left blank if you would just like a 2/3 column on the left", + icon="doc-full", + required=False, + ), + ), + ] + ), + ), + ( + "accordion", + wagtail.blocks.StructBlock( + [ + ( + "accordion_items", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the Accordion Item" + ), + ), + ( + "content", + wagtail.blocks.StreamBlock( + [ + ( + "rich_text", + wagtail.blocks.RichTextBlock( + blank=True, + features=[ + "bold", + "italic", + "link", + "ul", + "ol", + "document-link", + ], + ), + ), + ( + "datawrapper", + wagtail.embeds.blocks.EmbedBlock( + help_text='Enter the "visualization only" link of the Datawrapper chart. It looks something like this: https://datawrapper.dwcdn.net/KwSKp/1/', + icon="image", + template="wagtailpages/blocks/datawrapper_block.html", + ), + ), + ( + "image", + wagtail.blocks.StructBlock( + [ + ( + "image", + wagtail.images.blocks.ImageChooserBlock(), + ), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", + required=True, + ), + ), + ] + ), + ), + ( + "video", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="For YouTube: go to your YouTube video and click “Share,” then “Embed,” and then copy and paste the provided URL only. For example: https://www.youtube.com/embed/3FIVXBawyQw For Vimeo: follow similar steps to grab the embed URL. For example: https://player.vimeo.com/video/9004979", + label="Embed URL", + ), + ), + ( + "caption", + wagtail.blocks.CharBlock(required=False), + ), + ( + "captionURL", + wagtail.blocks.CharBlock( + help_text="Optional URL for caption to link to.", + required=False, + ), + ), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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, + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "video_width", + wagtail.blocks.ChoiceBlock( + choices=[ + ("normal", "Normal"), + ("wide", "Wide"), + ("full_width", "Full Width"), + ], + help_text="Wide videos are col-12, Full-Width videos reach both ends of the screen.", + ), + ), + ] + ), + ), + ] + ), + ), + ] + ) + ), + ) + ] + ), + ), + ], + use_json_field=True, + ), + ), + migrations.AlterField( + model_name="primarypage", + name="body", + field=wagtail.fields.StreamField( + [ + ( + "paragraph", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + "large", + ], + template="wagtailpages/blocks/rich_text_block.html", + ), + ), + ( + "card_grid", + wagtail.blocks.StructBlock( + [ + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ("body", wagtail.blocks.TextBlock(help_text="Body text of the card.")), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that this card should link out to. (Note: If left blank, link will not render.) ", + required=False, + ), + ), + ( + "link_label", + wagtail.blocks.CharBlock( + help_text="Optional Label for the URL link above. (Note: If left blank, link will not render.) ", + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + ), + ) + ] + ), + ), + ( + "image", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "image_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide images are col-12, Full-Width Images reach both ends of the screen (16:6 images recommended for full width)", + ), + ), + ] + ), + ), + ( + "image_text", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ( + "text", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + ] + ), + ), + ( + "url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this image should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ] + ), + ), + ( + "image_text_mini", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ("text", wagtail.blocks.RichTextBlock(features=["bold", "italic", "link"])), + ] + ), + ), + ( + "image_grid", + wagtail.blocks.StructBlock( + [ + ( + "grid_items", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for this image.", required=False + ), + ), + ( + "caption", + wagtail.blocks.CharBlock( + help_text="Please remember to properly attribute any images we use.", + required=False, + ), + ), + ( + "url", + wagtail.blocks.CharBlock( + help_text="Optional URL that this figure should link out to.", + required=False, + ), + ), + ( + "square_image", + wagtail.blocks.BooleanBlock( + default=True, + help_text="If left checked, the image will be cropped to be square.", + required=False, + ), + ), + ] + ) + ), + ) + ] + ), + ), + ( + "video", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="For YouTube: go to your YouTube video and click “Share,” then “Embed,” and then copy and paste the provided URL only. For example: https://www.youtube.com/embed/3FIVXBawyQw For Vimeo: follow similar steps to grab the embed URL. For example: https://player.vimeo.com/video/9004979", + label="Embed URL", + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "captionURL", + wagtail.blocks.CharBlock( + help_text="Optional URL for caption to link to.", required=False + ), + ), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "video_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide videos are col-12, Full-Width videos reach both ends of the screen.", + ), + ), + ] + ), + ), + ( + "iframe", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.CharBlock( + help_text="Please note that only URLs from allow-listed domains will work." + ), + ), + ( + "height", + wagtail.blocks.IntegerBlock( + help_text="Optional integer pixel value for custom iFrame height", + required=False, + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "iframe_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide iframes are col-12, Full-Width iframes reach both ends of the screen", + ), + ), + ( + "disable_scroll", + wagtail.blocks.BooleanBlock( + default=False, + help_text='Checking this will add "scrolling=no" to the iframe. Use this if your iframe is rendering an unnecessary scroll bar or whitespace below it.', + required=False, + ), + ), + ] + ), + ), + ( + "linkbutton", + 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"', + 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), + ), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ] + ), + ), + ( + "spacer", + wagtail.blocks.StructBlock( + [ + ( + "size", + wagtail.blocks.ChoiceBlock( + choices=[ + ("1", "quarter spacing"), + ("2", "half spacing"), + ("3", "single spacing"), + ("4", "one and a half spacing"), + ("5", "triple spacing"), + ] + ), + ) + ] + ), + ), + ( + "single_quote", + wagtail.blocks.StructBlock( + [ + ("quote", wagtail.blocks.RichTextBlock(features=["bold"])), + ("attribution", wagtail.blocks.CharBlock(required=False)), + ( + "attribution_info", + wagtail.blocks.RichTextBlock(features=["bold", "link", "large"], required=False), + ), + ] + ), + ), + ( + "pulse_listing", + wagtail.blocks.StructBlock( + [ + ( + "search_terms", + wagtail.blocks.CharBlock( + help_text="Test your search at mozillapulse.org/search", + label="Search", + required=False, + ), + ), + ( + "max_number_of_results", + wagtail.blocks.IntegerBlock( + default=6, + help_text="Choose 1-12. If you want visitors to see more, link to a search or tag on Pulse.", + max_value=12, + min_value=0, + required=True, + ), + ), + ( + "only_featured_entries", + wagtail.blocks.BooleanBlock( + default=False, + help_text="Featured items are selected by Pulse moderators.", + label="Display only featured entries", + required=False, + ), + ), + ( + "newest_first", + wagtail.blocks.ChoiceBlock( + choices=[ + ("True", "Show newer entries first"), + ("False", "Show older entries first"), + ], + label="Sort", + ), + ), + ( + "advanced_filter_header", + wagtail.blocks.static_block.StaticBlock( + admin_text="-------- ADVANCED FILTERS: OPTIONS TO DISPLAY FEWER, MORE TARGETED RESULTS. --------", + label=" ", + ), + ), + ( + "issues", + wagtail.blocks.ChoiceBlock( + choices=[ + ("all", "All"), + ("Decentralization", "Decentralization"), + ("Digital Inclusion", "Digital Inclusion"), + ("Online Privacy & Security", "Online Privacy & Security"), + ("Open Innovation", "Open Innovation"), + ("Web Literacy", "Web Literacy"), + ] + ), + ), + ( + "help", + wagtail.blocks.ChoiceBlock( + choices=[ + ("all", "All"), + ("Attend", "Attend"), + ("Create content", "Create content"), + ("Code", "Code"), + ("Design", "Design"), + ("Fundraise", "Fundraise"), + ("Join community", "Join community"), + ("Localize & translate", "Localize & translate"), + ("Mentor", "Mentor"), + ("Plan & organize", "Plan & organize"), + ("Promote", "Promote"), + ("Take action", "Take action"), + ("Test & feedback", "Test & feedback"), + ("Write documentation", "Write documentation"), + ], + label="Type of help needed", + ), + ), + ( + "direct_link", + wagtail.blocks.BooleanBlock( + default=False, + help_text="Checked: user goes to project link. Unchecked: user goes to pulse entry", + label="Direct link", + required=False, + ), + ), + ] + ), + ), + ( + "profile_listing", + wagtail.blocks.StructBlock( + [ + ( + "max_number_of_results", + wagtail.blocks.IntegerBlock( + default=12, + help_text="Pick up to 48 profiles.", + max_value=48, + min_value=1, + required=True, + ), + ), + ( + "advanced_filter_header", + wagtail.blocks.static_block.StaticBlock( + admin_text="-------- ADVANCED FILTERS: OPTIONS TO DISPLAY FEWER, MORE TARGETED RESULTS. --------", + label=" ", + ), + ), + ( + "profile_type", + wagtail.blocks.CharBlock(default="", help_text="Example: Fellow.", required=False), + ), + ( + "program_type", + wagtail.blocks.CharBlock( + default="", help_text="Example: Tech Policy.", required=False + ), + ), + ("year", wagtail.blocks.CharBlock(default="", required=False)), + ] + ), + ), + ( + "profile_by_id", + wagtail.blocks.StructBlock( + [ + ( + "ids", + wagtail.blocks.CharBlock( + help_text="Show profiles for pulse users with specific profile ids (mozillapulse.org/profile/[##]). For multiple profiles, specify a comma separated list (e.g. 85,105,332).", + label="Profile by ID", + ), + ) + ] + ), + ), + ( + "profile_directory", + wagtail.blocks.StructBlock( + [ + ( + "max_number_of_results", + wagtail.blocks.IntegerBlock( + default=12, + help_text="Pick up to 48 profiles.", + max_value=48, + min_value=1, + required=True, + ), + ), + ( + "advanced_filter_header", + wagtail.blocks.static_block.StaticBlock( + admin_text="-------- ADVANCED FILTERS: OPTIONS TO DISPLAY FEWER, MORE TARGETED RESULTS. --------", + label=" ", + ), + ), + ( + "profile_type", + wagtail.blocks.CharBlock(default="", help_text="Example: Fellow.", required=False), + ), + ( + "program_type", + wagtail.blocks.CharBlock( + default="", help_text="Example: Tech Policy.", required=False + ), + ), + ("year", wagtail.blocks.CharBlock(default="", required=False)), + ( + "filter_values", + wagtail.blocks.CharBlock( + default="2019,2018,2017,2016,2015,2014,2013", + help_text="Example: 2019,2018,2017,2016,2015,2014,2013", + required=True, + ), + ), + ] + ), + ), + ( + "recent_blog_entries", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock(required=False)), + ( + "tag_filter", + wagtail.blocks.CharBlock( + help_text="Test this filter at foundation.mozilla.org/blog/tags/", + label="Filter by Tag", + required=False, + ), + ), + ( + "topic_filter", + wagtail.blocks.ChoiceBlock( + choices=networkapi.wagtailpages.pagemodels.blog.blog_topic.BlogPageTopic.get_topics, + help_text="Test this filter at foundation.mozilla.org/blog/topic/", + label="Filter by Topic", + required=False, + ), + ), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ] + ), + ), + ( + "blog_set", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock()), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ( + "blog_pages", + wagtail.blocks.ListBlock( + wagtail.blocks.PageChooserBlock(page_type=["wagtailpages.BlogPage"]) + ), + ), + ] + ), + ), + ( + "airtable", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="Copied from the Airtable embed code. The word 'embed' will be in the url" + ), + ), + ( + "height", + wagtail.blocks.IntegerBlock( + default=533, + help_text="The pixel height on desktop view, usually copied from the Airtable embed code", + ), + ), + ] + ), + ), + ( + "typeform", + wagtail.blocks.StructBlock( + [ + ( + "embed_id", + wagtail.blocks.CharBlock( + help_text="The embed id of your Typeform page (e.g. if the form is on admin.typeform.com/form/e8zScc6t, the id will be: e8zScc6t)", + required=True, + ), + ), + ( + "button_type", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ( + "button_text", + wagtail.blocks.CharBlock( + help_text="This is a text prompt for users to open the typeform content", + required=True, + ), + ), + ] + ), + ), + ( + "datawrapper", + wagtail.embeds.blocks.EmbedBlock( + help_text='Enter the "visualization only" link of the Datawrapper chart. It looks something like this: https://datawrapper.dwcdn.net/KwSKp/1/', + icon="image", + template="wagtailpages/blocks/datawrapper_block.html", + ), + ), + ( + "listing", + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock(help_text="Heading for the block.", required=False), + ), + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ( + "highlighted_metadata", + wagtail.blocks.CharBlock( + help_text="Metadata to highlight on the card.", required=False + ), + ), + ( + "metadata", + wagtail.blocks.CharBlock( + help_text="Generic metadata.", required=False + ), + ), + ( + "body", + wagtail.blocks.RichTextBlock( + features=["bold"], + help_text="Body text of the card.", + required=False, + ), + ), + ( + "link_page", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to.", required=False + ), + ), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that the header should link out to.", + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + min_num=2, + ), + ), + ( + "cards_per_row", + wagtail.blocks.ChoiceBlock( + choices=[(2, "2"), (3, "3")], + help_text="Number of cards per row. Note: this is a max and fewer might be used if is less space is available.", + required=False, + ), + ), + ] + ), + ), + ( + "profiles", + wagtail.blocks.StructBlock( + [ + ( + "profiles", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "profile", + wagtail.snippets.blocks.SnippetChooserBlock( + networkapi.wagtailpages.pagemodels.profiles.Profile + ), + ) + ] + ), + min_num=1, + ), + ) + ] + ), + ), + ( + "article_teaser_block", + wagtail.blocks.StructBlock( + [ + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "article", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to.", + page_type=["wagtailpages.ArticlePage"], + required=False, + ), + ) + ] + ), + help_text="Please use a minimum of 3 cards.", + min_num=3, + ), + ) + ] + ), + ), + ( + "group_listing_block", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the group of cards.", required=False + ), + ), + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ( + "meta_data", + wagtail.blocks.CharBlock( + help_text="Optional meta data information for the card.", + required=False, + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ( + "body", + wagtail.blocks.RichTextBlock( + features=["bold", "link"], help_text="Body text of the card." + ), + ), + ( + "url", + wagtail.blocks.CharBlock( + help_text="The URL this card should link to.", required=False + ), + ), + ] + ) + ), + ), + ] + ), + ), + ( + "image_feature", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock(help_text="Image description (for screen readers)."), + ), + ("metadata", wagtail.blocks.CharBlock(required=False)), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ( + "title_link", + wagtail.blocks.PageChooserBlock( + help_text="Page that the title should link out to.", required=False + ), + ), + ("body", wagtail.blocks.CharBlock(required=False)), + ] + ), + ), + ( + "image_teaser_block", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ("text", wagtail.blocks.RichTextBlock(features=["bold"])), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ("url_label", wagtail.blocks.CharBlock(required=False)), + ("url", wagtail.blocks.CharBlock(required=False)), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ] + ), + ), + ( + "text_only_teaser", + wagtail.blocks.StructBlock( + [ + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock(help_text="Heading for the card."), + ), + ( + "link_page", + wagtail.blocks.PageChooserBlock( + help_text="Page that the header should link out to.", + required=False, + ), + ), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that the header should link out to.", + required=False, + ), + ), + ("meta_data", wagtail.blocks.CharBlock(max_length=500)), + ( + "body", + wagtail.blocks.TextBlock( + help_text="Body text of the card.", + max_length=200, + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 3 cards.", + min_num=3, + ), + ) + ] + ), + ), + ( + "block_with_aside", + wagtail.blocks.StructBlock( + [ + ( + "content", + wagtail.blocks.StreamBlock( + [ + ( + "listing", + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock( + help_text="Heading for the block.", required=False + ), + ), + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "image", + wagtail.images.blocks.ImageChooserBlock(), + ), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", + required=False, + ), + ), + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the card." + ), + ), + ( + "highlighted_metadata", + wagtail.blocks.CharBlock( + help_text="Metadata to highlight on the card.", + required=False, + ), + ), + ( + "metadata", + wagtail.blocks.CharBlock( + help_text="Generic metadata.", + required=False, + ), + ), + ( + "body", + wagtail.blocks.RichTextBlock( + features=["bold"], + help_text="Body text of the card.", + required=False, + ), + ), + ( + "link_page", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to.", + required=False, + ), + ), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that the header should link out to.", + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + min_num=2, + ), + ), + ( + "cards_per_row", + wagtail.blocks.ChoiceBlock( + choices=[(2, "2"), (3, "3")], + help_text="Number of cards per row. Note: this is a max and fewer might be used if is less space is available.", + required=False, + ), + ), + ] + ), + ), + ( + "paragraph", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + ] + ), + ), + ], + help_text="The wider block that appears on the left on desktop", + icon="doc-full", + max_num=1, + ), + ), + ( + "aside", + wagtail.blocks.StreamBlock( + [ + ( + "aside_content", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the card.", required=False + ), + ), + ( + "body", + wagtail.blocks.TextBlock( + help_text="Body text of the card.", required=False + ), + ), + ] + ), + ), + ( + "linkbutton", + 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"', + 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 + ), + ), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ] + ), + ), + ( + "spacer", + wagtail.blocks.StructBlock( + [ + ( + "size", + wagtail.blocks.ChoiceBlock( + choices=[ + ("1", "quarter spacing"), + ("2", "half spacing"), + ("3", "single spacing"), + ("4", "one and a half spacing"), + ("5", "triple spacing"), + ] + ), + ) + ] + ), + ), + ], + help_text="Elements here will appear in the column on the right side of the page on desktop. This can be left blank if you would just like a 2/3 column on the left", + icon="doc-full", + required=False, + ), + ), + ] + ), + ), + ( + "accordion", + wagtail.blocks.StructBlock( + [ + ( + "accordion_items", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the Accordion Item" + ), + ), + ( + "content", + wagtail.blocks.StreamBlock( + [ + ( + "rich_text", + wagtail.blocks.RichTextBlock( + blank=True, + features=[ + "bold", + "italic", + "link", + "ul", + "ol", + "document-link", + ], + ), + ), + ( + "datawrapper", + wagtail.embeds.blocks.EmbedBlock( + help_text='Enter the "visualization only" link of the Datawrapper chart. It looks something like this: https://datawrapper.dwcdn.net/KwSKp/1/', + icon="image", + template="wagtailpages/blocks/datawrapper_block.html", + ), + ), + ( + "image", + wagtail.blocks.StructBlock( + [ + ( + "image", + wagtail.images.blocks.ImageChooserBlock(), + ), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", + required=True, + ), + ), + ] + ), + ), + ( + "video", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="For YouTube: go to your YouTube video and click “Share,” then “Embed,” and then copy and paste the provided URL only. For example: https://www.youtube.com/embed/3FIVXBawyQw For Vimeo: follow similar steps to grab the embed URL. For example: https://player.vimeo.com/video/9004979", + label="Embed URL", + ), + ), + ( + "caption", + wagtail.blocks.CharBlock(required=False), + ), + ( + "captionURL", + wagtail.blocks.CharBlock( + help_text="Optional URL for caption to link to.", + required=False, + ), + ), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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, + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "video_width", + wagtail.blocks.ChoiceBlock( + choices=[ + ("normal", "Normal"), + ("wide", "Wide"), + ("full_width", "Full Width"), + ], + help_text="Wide videos are col-12, Full-Width videos reach both ends of the screen.", + ), + ), + ] + ), + ), + ] + ), + ), + ] + ) + ), + ) + ] + ), + ), + ], + use_json_field=True, + ), + ), + MigrateStreamData( + app_name="wagtailpages", + model_name="articlepage", + field_name="body", + operations_and_block_paths=[ + (AlterStreamChildBlockDataOperation(block="video", operation=migrate_video_block), ""), + ], + ), + MigrateStreamData( + app_name="wagtailpages", + model_name="blogpage", + field_name="body", + operations_and_block_paths=[ + (AlterStreamChildBlockDataOperation(block="video", operation=migrate_video_block), ""), + ], + ), + MigrateStreamData( + app_name="wagtailpages", + model_name="buyersguidearticlepage", + field_name="body", + operations_and_block_paths=[ + (AlterStreamChildBlockDataOperation(block="video", operation=migrate_video_block), ""), + ], + ), + MigrateStreamData( + app_name="wagtailpages", + model_name="buyersguidecampaignpage", + field_name="body", + operations_and_block_paths=[ + (AlterStreamChildBlockDataOperation(block="video", operation=migrate_video_block), ""), + ], + ), + MigrateStreamData( + app_name="wagtailpages", + model_name="modularpage", + field_name="body", + operations_and_block_paths=[ + (AlterStreamChildBlockDataOperation(block="video", operation=migrate_video_block), ""), + ], + ), + MigrateStreamData( + app_name="wagtailpages", + model_name="primarypage", + field_name="body", + operations_and_block_paths=[ + (AlterStreamChildBlockDataOperation(block="video", operation=migrate_video_block), ""), + ], + ), + migrations.AlterField( + model_name="articlepage", + name="body", + field=wagtail.fields.StreamField( + [ + ( + "accordion", + wagtail.blocks.StructBlock( + [ + ( + "accordion_items", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the Accordion Item" + ), + ), + ( + "content", + wagtail.blocks.StreamBlock( + [ + ( + "rich_text", + wagtail.blocks.RichTextBlock( + blank=True, + features=[ + "bold", + "italic", + "link", + "ul", + "ol", + "document-link", + ], + ), + ), + ( + "datawrapper", + wagtail.embeds.blocks.EmbedBlock( + help_text='Enter the "visualization only" link of the Datawrapper chart. It looks something like this: https://datawrapper.dwcdn.net/KwSKp/1/', + icon="image", + template="wagtailpages/blocks/datawrapper_block.html", + ), + ), + ( + "image", + wagtail.blocks.StructBlock( + [ + ( + "image", + wagtail.images.blocks.ImageChooserBlock(), + ), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", + required=True, + ), + ), + ] + ), + ), + ( + "video", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="For YouTube: go to your YouTube video and click “Share,” then “Embed,” and then copy and paste the provided URL only. For example: https://www.youtube.com/embed/3FIVXBawyQw For Vimeo: follow similar steps to grab the embed URL. For example: https://player.vimeo.com/video/9004979", + label="Embed URL", + ), + ), + ( + "caption", + wagtail.blocks.CharBlock(required=False), + ), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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, + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "video_width", + wagtail.blocks.ChoiceBlock( + choices=[ + ("normal", "Normal"), + ("wide", "Wide"), + ("full_width", "Full Width"), + ], + help_text="Wide videos are col-12, Full-Width videos reach both ends of the screen.", + ), + ), + ] + ), + ), + ] + ), + ), + ] + ) + ), + ) + ] + ), + ), + ( + "airtable", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="Copied from the Airtable embed code. The word 'embed' will be in the url" + ), + ), + ( + "height", + wagtail.blocks.IntegerBlock( + default=533, + help_text="The pixel height on desktop view, usually copied from the Airtable embed code", + ), + ), + ] + ), + ), + ( + "datawrapper", + wagtail.embeds.blocks.EmbedBlock( + help_text='Enter the "visualization only" link of the Datawrapper chart. It looks something like this: https://datawrapper.dwcdn.net/KwSKp/1/', + icon="image", + template="wagtailpages/blocks/datawrapper_block.html", + ), + ), + ( + "callout", + wagtail.blocks.RichTextBlock( + features=["bold", "italic", "link", "h2", "h3", "h4", "ul", "ol"], + template="wagtailpages/blocks/article_blockquote_block.html", + ), + ), + ( + "card_grid", + wagtail.blocks.StructBlock( + [ + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ("body", wagtail.blocks.TextBlock(help_text="Body text of the card.")), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that this card should link out to. (Note: If left blank, link will not render.) ", + required=False, + ), + ), + ( + "link_label", + wagtail.blocks.CharBlock( + help_text="Optional Label for the URL link above. (Note: If left blank, link will not render.) ", + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + ), + ) + ] + ), + ), + ( + "content", + networkapi.wagtailpages.pagemodels.customblocks.articles.ArticleRichText( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + "large", + "image", + "footnotes", + ] + ), + ), + ( + "image", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "caption", + wagtail.blocks.RichTextBlock( + features=["bold", "italic", "link"], label="Image caption", required=False + ), + ), + ("alt_text", wagtail.blocks.CharBlock(required=False)), + ( + "wide_image", + wagtail.blocks.BooleanBlock( + default=False, + help_text='Checking this will use a wider version of this image, but not full width. For an edge-to-edge image, use the "Wide Image" block.', + required=False, + ), + ), + ] + ), + ), + ( + "image_grid", + wagtail.blocks.StructBlock( + [ + ( + "grid_items", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for this image.", required=False + ), + ), + ( + "caption", + wagtail.blocks.CharBlock( + help_text="Please remember to properly attribute any images we use.", + required=False, + ), + ), + ( + "url", + wagtail.blocks.CharBlock( + help_text="Optional URL that this figure should link out to.", + required=False, + ), + ), + ( + "square_image", + wagtail.blocks.BooleanBlock( + default=True, + help_text="If left checked, the image will be cropped to be square.", + required=False, + ), + ), + ] + ) + ), + ) + ] + ), + ), + ( + "image_text", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ( + "text", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + ] + ), + ), + ( + "url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this image should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ] + ), + ), + ( + "double_image", + wagtail.blocks.StructBlock( + [ + ("image_1", wagtail.images.blocks.ImageChooserBlock()), + ( + "image_1_caption", + wagtail.blocks.RichTextBlock( + features=["bold", "italic", "link"], label="Image caption", required=False + ), + ), + ("image_2", wagtail.images.blocks.ImageChooserBlock()), + ( + "image_2_caption", + wagtail.blocks.RichTextBlock( + features=["bold", "italic", "link"], label="Image caption", required=False + ), + ), + ] + ), + ), + ( + "full_width_image", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "image_height", + wagtail.blocks.IntegerBlock( + default=410, + help_text="A custom height for this image. The image will be 1400px wide by this height. Note: This may cause images to look pixelated. If the browser is wider than 1400px the height will scale vertically while the width scales horizontally", + ), + ), + ( + "caption", + wagtail.blocks.RichTextBlock( + features=["bold", "italic", "link"], label="Image caption", required=False + ), + ), + ] + ), + ), + ( + "iframe", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.CharBlock( + help_text="Please note that only URLs from allow-listed domains will work." + ), + ), + ( + "height", + wagtail.blocks.IntegerBlock( + help_text="Optional integer pixel value for custom iFrame height", + required=False, + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "iframe_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide iframes are col-12, Full-Width iframes reach both ends of the screen", + ), + ), + ( + "disable_scroll", + wagtail.blocks.BooleanBlock( + default=False, + help_text='Checking this will add "scrolling=no" to the iframe. Use this if your iframe is rendering an unnecessary scroll bar or whitespace below it.', + required=False, + ), + ), + ] + ), + ), + ( + "linkbutton", + 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"', + 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), + ), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ] + ), + ), + ( + "single_quote", + wagtail.blocks.StructBlock( + [ + ("quote", wagtail.blocks.RichTextBlock(features=["bold"])), + ("attribution", wagtail.blocks.CharBlock(required=False)), + ( + "attribution_info", + wagtail.blocks.RichTextBlock(features=["bold", "link", "large"], required=False), + ), + ] + ), + ), + ( + "slider", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock(help_text="Heading for the slider.", required=False), + ), + ( + "slides", + wagtail.blocks.StreamBlock( + [ + ( + "slide", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading of the card.", required=False + ), + ), + ( + "image", + wagtail.images.blocks.ImageChooserBlock( + help_text="The image associated with this event." + ), + ), + ( + "caption", + wagtail.blocks.TextBlock( + help_text="Caption for slider image", required=False + ), + ), + ( + "body", + wagtail.blocks.RichTextBlock( + blank=True, + features=["bold", "italic", "link", "large"], + required=False, + ), + ), + ( + "buttons", + wagtail.blocks.StreamBlock( + [ + ( + "internal", + wagtail.blocks.StructBlock( + [ + ( + "label", + wagtail.blocks.CharBlock( + help_text="Label for this link." + ), + ), + ( + "link", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to." + ), + ), + ] + ), + ), + ( + "external", + wagtail.blocks.StructBlock( + [ + ( + "label", + wagtail.blocks.CharBlock( + help_text="Label for this link." + ), + ), + ( + "link", + wagtail.blocks.URLBlock( + help_text="URL that this should link out to." + ), + ), + ] + ), + ), + ( + "document", + wagtail.blocks.StructBlock( + [ + ( + "label", + wagtail.blocks.CharBlock( + help_text="Label for this link." + ), + ), + ( + "document", + wagtail.documents.blocks.DocumentChooserBlock( + help_text="Document that this should link out to." + ), + ), + ], + help_text='An iCal document can be attached here for an "Add to Calendar" button.', + ), + ), + ], + help_text="A list of buttons that will appear at the bottom of the card.", + max_num=2, + required=False, + ), + ), + ] + ), + ) + ], + help_text="A list of slides.", + ), + ), + ] + ), + ), + ( + "spacer", + wagtail.blocks.StructBlock( + [ + ( + "size", + wagtail.blocks.ChoiceBlock( + choices=[ + ("1", "quarter spacing"), + ("2", "half spacing"), + ("3", "single spacing"), + ("4", "one and a half spacing"), + ("5", "triple spacing"), + ] + ), + ) + ] + ), + ), + ( + "table", + wagtail.contrib.table_block.blocks.TableBlock( + template="wagtailpages/blocks/article_table_block.html" + ), + ), + ( + "video", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="For YouTube: go to your YouTube video and click “Share,” then “Embed,” and then copy and paste the provided URL only. For example: https://www.youtube.com/embed/3FIVXBawyQw For Vimeo: follow similar steps to grab the embed URL. For example: https://player.vimeo.com/video/9004979", + label="Embed URL", + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "video_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide videos are col-12, Full-Width videos reach both ends of the screen.", + ), + ), + ] + ), + ), + ( + "advanced_table", + wagtail.blocks.StructBlock( + [ + ( + "header", + wagtail.blocks.BooleanBlock( + help_text="Display the first row as a header.", required=False + ), + ), + ( + "column", + wagtail.blocks.BooleanBlock( + help_text="Display the first column as a header.", required=False + ), + ), + ( + "caption", + wagtail.blocks.CharBlock( + help_text="A heading that identifies the overall topic of the table, and is useful for screen reader users", + required=False, + ), + ), + ( + "wide", + wagtail.blocks.BooleanBlock( + default=True, + help_text="If this is checked, the table will render wider than the other page body content.", + required=False, + ), + ), + ( + "table", + wagtail.blocks.StreamBlock( + [ + ( + "row", + wagtail.blocks.StreamBlock( + [ + ( + "cell", + wagtail.blocks.StructBlock( + [ + ( + "centered_text", + wagtail.blocks.BooleanBlock(required=False), + ), + ( + "column_width", + wagtail.blocks.IntegerBlock( + default=1, + help_text="Enter the number of extra cell columns you want to merge together. Merging a cell column will expand a cell to the right. To merge two cells together, set the column width to 2. For 3, set 3. Default is 1. Min 1. Max 20.", + validators=[ + django.core.validators.MaxValueValidator( + 20 + ), + django.core.validators.MinValueValidator( + 1 + ), + ], + ), + ), + ( + "content", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "ul", + "ol", + ] + ), + ), + ] + ), + ) + ] + ), + ) + ] + ), + ), + ] + ), + ), + ], + use_json_field=True, + ), + ), + migrations.AlterField( + model_name="blogpage", + name="body", + field=wagtail.fields.StreamField( + [ + ( + "accordion", + wagtail.blocks.StructBlock( + [ + ( + "accordion_items", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the Accordion Item" + ), + ), + ( + "content", + wagtail.blocks.StreamBlock( + [ + ( + "rich_text", + wagtail.blocks.RichTextBlock( + blank=True, + features=[ + "bold", + "italic", + "link", + "ul", + "ol", + "document-link", + ], + ), + ), + ( + "datawrapper", + wagtail.embeds.blocks.EmbedBlock( + help_text='Enter the "visualization only" link of the Datawrapper chart. It looks something like this: https://datawrapper.dwcdn.net/KwSKp/1/', + icon="image", + template="wagtailpages/blocks/datawrapper_block.html", + ), + ), + ( + "image", + wagtail.blocks.StructBlock( + [ + ( + "image", + wagtail.images.blocks.ImageChooserBlock(), + ), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", + required=True, + ), + ), + ] + ), + ), + ( + "video", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="For YouTube: go to your YouTube video and click “Share,” then “Embed,” and then copy and paste the provided URL only. For example: https://www.youtube.com/embed/3FIVXBawyQw For Vimeo: follow similar steps to grab the embed URL. For example: https://player.vimeo.com/video/9004979", + label="Embed URL", + ), + ), + ( + "caption", + wagtail.blocks.CharBlock(required=False), + ), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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, + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "video_width", + wagtail.blocks.ChoiceBlock( + choices=[ + ("normal", "Normal"), + ("wide", "Wide"), + ("full_width", "Full Width"), + ], + help_text="Wide videos are col-12, Full-Width videos reach both ends of the screen.", + ), + ), + ] + ), + ), + ] + ), + ), + ] + ) + ), + ) + ] + ), + ), + ( + "paragraph", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + ], + template="wagtailpages/blocks/rich_text_block.html", + ), + ), + ( + "card_grid", + wagtail.blocks.StructBlock( + [ + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ("body", wagtail.blocks.TextBlock(help_text="Body text of the card.")), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that this card should link out to. (Note: If left blank, link will not render.) ", + required=False, + ), + ), + ( + "link_label", + wagtail.blocks.CharBlock( + help_text="Optional Label for the URL link above. (Note: If left blank, link will not render.) ", + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + ), + ) + ] + ), + ), + ( + "CTA_card", + wagtail.blocks.StructBlock( + [ + ( + "style", + wagtail.blocks.ChoiceBlock( + choices=[("pop", "Pop"), ("outline", "Outline"), ("filled", "Filled")] + ), + ), + ( + "title", + wagtail.blocks.CharBlock( + help_text="Optional title for the card.", max_length=100, required=False + ), + ), + ( + "body", + wagtail.blocks.RichTextBlock( + features=["bold", "italic", "link", "hr", "h4", "h5", "ul", "ol"], + help_text="Body text of the card.", + ), + ), + ( + "image", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", + required=True, + ), + ), + ] + ), + default=[], + max_num=1, + min_num=0, + ), + ), + ( + "button", + wagtail.blocks.ListBlock( + 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"', + 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 + ), + ), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ] + ), + default=[], + max_num=1, + min_num=0, + ), + ), + ] + ), + ), + ( + "CTA_card_with_text", + wagtail.blocks.StructBlock( + [ + ( + "alignment", + wagtail.blocks.ChoiceBlock( + choices=[("right", "Right"), ("left", "Left")], + help_text="For full-width cards, please use a regular Blog CTA Card block with a separate paragraph.", + ), + ), + ( + "card", + wagtail.blocks.StructBlock( + [ + ( + "style", + wagtail.blocks.ChoiceBlock( + choices=[ + ("pop", "Pop"), + ("outline", "Outline"), + ("filled", "Filled"), + ] + ), + ), + ( + "title", + wagtail.blocks.CharBlock( + help_text="Optional title for the card.", + max_length=100, + required=False, + ), + ), + ( + "body", + wagtail.blocks.RichTextBlock( + features=["bold", "italic", "link", "hr", "h4", "h5", "ul", "ol"], + help_text="Body text of the card.", + ), + ), + ( + "image", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", + required=True, + ), + ), + ] + ), + default=[], + max_num=1, + min_num=0, + ), + ), + ( + "button", + wagtail.blocks.ListBlock( + 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"', + 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 + ), + ), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ] + ), + default=[], + max_num=1, + min_num=0, + ), + ), + ], + required=True, + template="wagtailpages/blocks/blog_cta_card_block_regular.html", + ), + ), + ( + "paragraph", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + ], + help_text="Text to be displayed next to the card.", + template="wagtailpages/blocks/rich_text_block.html", + ), + ), + ] + ), + ), + ( + "image_grid", + wagtail.blocks.StructBlock( + [ + ( + "grid_items", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for this image.", required=False + ), + ), + ( + "caption", + wagtail.blocks.CharBlock( + help_text="Please remember to properly attribute any images we use.", + required=False, + ), + ), + ( + "url", + wagtail.blocks.CharBlock( + help_text="Optional URL that this figure should link out to.", + required=False, + ), + ), + ( + "square_image", + wagtail.blocks.BooleanBlock( + default=True, + help_text="If left checked, the image will be cropped to be square.", + required=False, + ), + ), + ] + ) + ), + ) + ] + ), + ), + ( + "iframe", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.CharBlock( + help_text="Please note that only URLs from allow-listed domains will work." + ), + ), + ( + "height", + wagtail.blocks.IntegerBlock( + help_text="Optional integer pixel value for custom iFrame height", + required=False, + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "iframe_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide iframes are col-12, Full-Width iframes reach both ends of the screen", + ), + ), + ( + "disable_scroll", + wagtail.blocks.BooleanBlock( + default=False, + help_text='Checking this will add "scrolling=no" to the iframe. Use this if your iframe is rendering an unnecessary scroll bar or whitespace below it.', + required=False, + ), + ), + ] + ), + ), + ( + "image", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "image_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide images are col-12, Full-Width Images reach both ends of the screen (16:6 images recommended for full width)", + ), + ), + ] + ), + ), + ( + "audio", + wagtail.blocks.StructBlock( + [ + ("audio", wagtailmedia.blocks.AudioChooserBlock()), + ("caption", wagtail.blocks.CharBlock(required=False)), + ] + ), + ), + ( + "image_text", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ( + "text", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + ] + ), + ), + ( + "url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this image should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ] + ), + ), + ( + "image_text_mini", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ("text", wagtail.blocks.RichTextBlock(features=["bold", "italic", "link"])), + ] + ), + ), + ( + "video", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="For YouTube: go to your YouTube video and click “Share,” then “Embed,” and then copy and paste the provided URL only. For example: https://www.youtube.com/embed/3FIVXBawyQw For Vimeo: follow similar steps to grab the embed URL. For example: https://player.vimeo.com/video/9004979", + label="Embed URL", + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "video_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide videos are col-12, Full-Width videos reach both ends of the screen.", + ), + ), + ] + ), + ), + ( + "linkbutton", + 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"', + 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), + ), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ] + ), + ), + ( + "looping_video", + wagtail.blocks.StructBlock( + [ + ( + "video_url", + wagtail.blocks.CharBlock( + help_text='Log into Vimeo using 1Password and upload the desired video. Then select the video and click "Advanced", "Distribution", and "Video File Links". Copy and paste the link here.', + label="Embed URL", + ), + ) + ] + ), + ), + ( + "pulse_listing", + wagtail.blocks.StructBlock( + [ + ( + "search_terms", + wagtail.blocks.CharBlock( + help_text="Test your search at mozillapulse.org/search", + label="Search", + required=False, + ), + ), + ( + "max_number_of_results", + wagtail.blocks.IntegerBlock( + default=6, + help_text="Choose 1-12. If you want visitors to see more, link to a search or tag on Pulse.", + max_value=12, + min_value=0, + required=True, + ), + ), + ( + "only_featured_entries", + wagtail.blocks.BooleanBlock( + default=False, + help_text="Featured items are selected by Pulse moderators.", + label="Display only featured entries", + required=False, + ), + ), + ( + "newest_first", + wagtail.blocks.ChoiceBlock( + choices=[ + ("True", "Show newer entries first"), + ("False", "Show older entries first"), + ], + label="Sort", + ), + ), + ( + "advanced_filter_header", + wagtail.blocks.static_block.StaticBlock( + admin_text="-------- ADVANCED FILTERS: OPTIONS TO DISPLAY FEWER, MORE TARGETED RESULTS. --------", + label=" ", + ), + ), + ( + "issues", + wagtail.blocks.ChoiceBlock( + choices=[ + ("all", "All"), + ("Decentralization", "Decentralization"), + ("Digital Inclusion", "Digital Inclusion"), + ("Online Privacy & Security", "Online Privacy & Security"), + ("Open Innovation", "Open Innovation"), + ("Web Literacy", "Web Literacy"), + ] + ), + ), + ( + "help", + wagtail.blocks.ChoiceBlock( + choices=[ + ("all", "All"), + ("Attend", "Attend"), + ("Create content", "Create content"), + ("Code", "Code"), + ("Design", "Design"), + ("Fundraise", "Fundraise"), + ("Join community", "Join community"), + ("Localize & translate", "Localize & translate"), + ("Mentor", "Mentor"), + ("Plan & organize", "Plan & organize"), + ("Promote", "Promote"), + ("Take action", "Take action"), + ("Test & feedback", "Test & feedback"), + ("Write documentation", "Write documentation"), + ], + label="Type of help needed", + ), + ), + ( + "direct_link", + wagtail.blocks.BooleanBlock( + default=False, + help_text="Checked: user goes to project link. Unchecked: user goes to pulse entry", + label="Direct link", + required=False, + ), + ), + ] + ), + ), + ( + "single_quote", + wagtail.blocks.StructBlock( + [ + ("quote", wagtail.blocks.RichTextBlock(features=["bold"])), + ("attribution", wagtail.blocks.CharBlock(required=False)), + ( + "attribution_info", + wagtail.blocks.RichTextBlock(features=["bold", "link", "large"], required=False), + ), + ] + ), + ), + ( + "slider", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock(help_text="Heading for the slider.", required=False), + ), + ( + "slides", + wagtail.blocks.StreamBlock( + [ + ( + "slide", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading of the card.", required=False + ), + ), + ( + "image", + wagtail.images.blocks.ImageChooserBlock( + help_text="The image associated with this event." + ), + ), + ( + "caption", + wagtail.blocks.TextBlock( + help_text="Caption for slider image", required=False + ), + ), + ( + "body", + wagtail.blocks.RichTextBlock( + blank=True, + features=["bold", "italic", "link", "large"], + required=False, + ), + ), + ( + "buttons", + wagtail.blocks.StreamBlock( + [ + ( + "internal", + wagtail.blocks.StructBlock( + [ + ( + "label", + wagtail.blocks.CharBlock( + help_text="Label for this link." + ), + ), + ( + "link", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to." + ), + ), + ] + ), + ), + ( + "external", + wagtail.blocks.StructBlock( + [ + ( + "label", + wagtail.blocks.CharBlock( + help_text="Label for this link." + ), + ), + ( + "link", + wagtail.blocks.URLBlock( + help_text="URL that this should link out to." + ), + ), + ] + ), + ), + ( + "document", + wagtail.blocks.StructBlock( + [ + ( + "label", + wagtail.blocks.CharBlock( + help_text="Label for this link." + ), + ), + ( + "document", + wagtail.documents.blocks.DocumentChooserBlock( + help_text="Document that this should link out to." + ), + ), + ], + help_text='An iCal document can be attached here for an "Add to Calendar" button.', + ), + ), + ], + help_text="A list of buttons that will appear at the bottom of the card.", + max_num=2, + required=False, + ), + ), + ] + ), + ) + ], + help_text="A list of slides.", + ), + ), + ] + ), + ), + ( + "spacer", + wagtail.blocks.StructBlock( + [ + ( + "size", + wagtail.blocks.ChoiceBlock( + choices=[ + ("1", "quarter spacing"), + ("2", "half spacing"), + ("3", "single spacing"), + ("4", "one and a half spacing"), + ("5", "triple spacing"), + ] + ), + ) + ] + ), + ), + ( + "airtable", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="Copied from the Airtable embed code. The word 'embed' will be in the url" + ), + ), + ( + "height", + wagtail.blocks.IntegerBlock( + default=533, + help_text="The pixel height on desktop view, usually copied from the Airtable embed code", + ), + ), + ] + ), + ), + ( + "datawrapper", + wagtail.embeds.blocks.EmbedBlock( + help_text='Enter the "visualization only" link of the Datawrapper chart. It looks something like this: https://datawrapper.dwcdn.net/KwSKp/1/', + icon="image", + template="wagtailpages/blocks/datawrapper_block.html", + ), + ), + ( + "typeform", + wagtail.blocks.StructBlock( + [ + ( + "embed_id", + wagtail.blocks.CharBlock( + help_text="The embed id of your Typeform page (e.g. if the form is on admin.typeform.com/form/e8zScc6t, the id will be: e8zScc6t)", + required=True, + ), + ), + ( + "button_type", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ( + "button_text", + wagtail.blocks.CharBlock( + help_text="This is a text prompt for users to open the typeform content", + required=True, + ), + ), + ] + ), + ), + ( + "newsletter_signup", + wagtail.blocks.StructBlock( + [("signup", wagtail.snippets.blocks.SnippetChooserBlock("wagtailpages.BlogSignup"))] + ), + ), + ], + use_json_field=True, + ), + ), + migrations.AlterField( + model_name="buyersguidearticlepage", + name="body", + field=wagtail.fields.StreamField( + [ + ( + "accordion", + wagtail.blocks.StructBlock( + [ + ( + "accordion_items", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the Accordion Item" + ), + ), + ( + "content", + wagtail.blocks.StreamBlock( + [ + ( + "rich_text", + wagtail.blocks.RichTextBlock( + blank=True, + features=[ + "bold", + "italic", + "link", + "ul", + "ol", + "document-link", + ], + ), + ), + ( + "datawrapper", + wagtail.embeds.blocks.EmbedBlock( + help_text='Enter the "visualization only" link of the Datawrapper chart. It looks something like this: https://datawrapper.dwcdn.net/KwSKp/1/', + icon="image", + template="wagtailpages/blocks/datawrapper_block.html", + ), + ), + ( + "image", + wagtail.blocks.StructBlock( + [ + ( + "image", + wagtail.images.blocks.ImageChooserBlock(), + ), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", + required=True, + ), + ), + ] + ), + ), + ( + "video", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="For YouTube: go to your YouTube video and click “Share,” then “Embed,” and then copy and paste the provided URL only. For example: https://www.youtube.com/embed/3FIVXBawyQw For Vimeo: follow similar steps to grab the embed URL. For example: https://player.vimeo.com/video/9004979", + label="Embed URL", + ), + ), + ( + "caption", + wagtail.blocks.CharBlock(required=False), + ), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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, + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "video_width", + wagtail.blocks.ChoiceBlock( + choices=[ + ("normal", "Normal"), + ("wide", "Wide"), + ("full_width", "Full Width"), + ], + help_text="Wide videos are col-12, Full-Width videos reach both ends of the screen.", + ), + ), + ] + ), + ), + ] + ), + ), + ] + ) + ), + ) + ] + ), + ), + ( + "paragraph", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + ], + template="wagtailpages/blocks/rich_text_block.html", + ), + ), + ( + "card_grid", + wagtail.blocks.StructBlock( + [ + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ("body", wagtail.blocks.TextBlock(help_text="Body text of the card.")), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that this card should link out to. (Note: If left blank, link will not render.) ", + required=False, + ), + ), + ( + "link_label", + wagtail.blocks.CharBlock( + help_text="Optional Label for the URL link above. (Note: If left blank, link will not render.) ", + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + ), + ) + ] + ), + ), + ( + "image_grid", + wagtail.blocks.StructBlock( + [ + ( + "grid_items", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for this image.", required=False + ), + ), + ( + "caption", + wagtail.blocks.CharBlock( + help_text="Please remember to properly attribute any images we use.", + required=False, + ), + ), + ( + "url", + wagtail.blocks.CharBlock( + help_text="Optional URL that this figure should link out to.", + required=False, + ), + ), + ( + "square_image", + wagtail.blocks.BooleanBlock( + default=True, + help_text="If left checked, the image will be cropped to be square.", + required=False, + ), + ), + ] + ) + ), + ) + ] + ), + ), + ( + "iframe", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.CharBlock( + help_text="Please note that only URLs from allow-listed domains will work." + ), + ), + ( + "height", + wagtail.blocks.IntegerBlock( + help_text="Optional integer pixel value for custom iFrame height", + required=False, + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "iframe_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide iframes are col-12, Full-Width iframes reach both ends of the screen", + ), + ), + ( + "disable_scroll", + wagtail.blocks.BooleanBlock( + default=False, + help_text='Checking this will add "scrolling=no" to the iframe. Use this if your iframe is rendering an unnecessary scroll bar or whitespace below it.', + required=False, + ), + ), + ] + ), + ), + ( + "image", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "image_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide images are col-12, Full-Width Images reach both ends of the screen (16:6 images recommended for full width)", + ), + ), + ] + ), + ), + ( + "audio", + wagtail.blocks.StructBlock( + [ + ("audio", wagtailmedia.blocks.AudioChooserBlock()), + ("caption", wagtail.blocks.CharBlock(required=False)), + ] + ), + ), + ( + "image_text", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ( + "text", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + ] + ), + ), + ( + "url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this image should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ] + ), + ), + ( + "image_text_mini", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ("text", wagtail.blocks.RichTextBlock(features=["bold", "italic", "link"])), + ] + ), + ), + ( + "video", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="For YouTube: go to your YouTube video and click “Share,” then “Embed,” and then copy and paste the provided URL only. For example: https://www.youtube.com/embed/3FIVXBawyQw For Vimeo: follow similar steps to grab the embed URL. For example: https://player.vimeo.com/video/9004979", + label="Embed URL", + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "video_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide videos are col-12, Full-Width videos reach both ends of the screen.", + ), + ), + ] + ), + ), + ( + "linkbutton", + 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"', + 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), + ), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ] + ), + ), + ( + "looping_video", + wagtail.blocks.StructBlock( + [ + ( + "video_url", + wagtail.blocks.CharBlock( + help_text='Log into Vimeo using 1Password and upload the desired video. Then select the video and click "Advanced", "Distribution", and "Video File Links". Copy and paste the link here.', + label="Embed URL", + ), + ) + ] + ), + ), + ( + "pulse_listing", + wagtail.blocks.StructBlock( + [ + ( + "search_terms", + wagtail.blocks.CharBlock( + help_text="Test your search at mozillapulse.org/search", + label="Search", + required=False, + ), + ), + ( + "max_number_of_results", + wagtail.blocks.IntegerBlock( + default=6, + help_text="Choose 1-12. If you want visitors to see more, link to a search or tag on Pulse.", + max_value=12, + min_value=0, + required=True, + ), + ), + ( + "only_featured_entries", + wagtail.blocks.BooleanBlock( + default=False, + help_text="Featured items are selected by Pulse moderators.", + label="Display only featured entries", + required=False, + ), + ), + ( + "newest_first", + wagtail.blocks.ChoiceBlock( + choices=[ + ("True", "Show newer entries first"), + ("False", "Show older entries first"), + ], + label="Sort", + ), + ), + ( + "advanced_filter_header", + wagtail.blocks.static_block.StaticBlock( + admin_text="-------- ADVANCED FILTERS: OPTIONS TO DISPLAY FEWER, MORE TARGETED RESULTS. --------", + label=" ", + ), + ), + ( + "issues", + wagtail.blocks.ChoiceBlock( + choices=[ + ("all", "All"), + ("Decentralization", "Decentralization"), + ("Digital Inclusion", "Digital Inclusion"), + ("Online Privacy & Security", "Online Privacy & Security"), + ("Open Innovation", "Open Innovation"), + ("Web Literacy", "Web Literacy"), + ] + ), + ), + ( + "help", + wagtail.blocks.ChoiceBlock( + choices=[ + ("all", "All"), + ("Attend", "Attend"), + ("Create content", "Create content"), + ("Code", "Code"), + ("Design", "Design"), + ("Fundraise", "Fundraise"), + ("Join community", "Join community"), + ("Localize & translate", "Localize & translate"), + ("Mentor", "Mentor"), + ("Plan & organize", "Plan & organize"), + ("Promote", "Promote"), + ("Take action", "Take action"), + ("Test & feedback", "Test & feedback"), + ("Write documentation", "Write documentation"), + ], + label="Type of help needed", + ), + ), + ( + "direct_link", + wagtail.blocks.BooleanBlock( + default=False, + help_text="Checked: user goes to project link. Unchecked: user goes to pulse entry", + label="Direct link", + required=False, + ), + ), + ] + ), + ), + ( + "single_quote", + wagtail.blocks.StructBlock( + [ + ("quote", wagtail.blocks.RichTextBlock(features=["bold"])), + ("attribution", wagtail.blocks.CharBlock(required=False)), + ( + "attribution_info", + wagtail.blocks.RichTextBlock(features=["bold", "link", "large"], required=False), + ), + ] + ), + ), + ( + "slider", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock(help_text="Heading for the slider.", required=False), + ), + ( + "slides", + wagtail.blocks.StreamBlock( + [ + ( + "slide", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading of the card.", required=False + ), + ), + ( + "image", + wagtail.images.blocks.ImageChooserBlock( + help_text="The image associated with this event." + ), + ), + ( + "caption", + wagtail.blocks.TextBlock( + help_text="Caption for slider image", required=False + ), + ), + ( + "body", + wagtail.blocks.RichTextBlock( + blank=True, + features=["bold", "italic", "link", "large"], + required=False, + ), + ), + ( + "buttons", + wagtail.blocks.StreamBlock( + [ + ( + "internal", + wagtail.blocks.StructBlock( + [ + ( + "label", + wagtail.blocks.CharBlock( + help_text="Label for this link." + ), + ), + ( + "link", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to." + ), + ), + ] + ), + ), + ( + "external", + wagtail.blocks.StructBlock( + [ + ( + "label", + wagtail.blocks.CharBlock( + help_text="Label for this link." + ), + ), + ( + "link", + wagtail.blocks.URLBlock( + help_text="URL that this should link out to." + ), + ), + ] + ), + ), + ( + "document", + wagtail.blocks.StructBlock( + [ + ( + "label", + wagtail.blocks.CharBlock( + help_text="Label for this link." + ), + ), + ( + "document", + wagtail.documents.blocks.DocumentChooserBlock( + help_text="Document that this should link out to." + ), + ), + ], + help_text='An iCal document can be attached here for an "Add to Calendar" button.', + ), + ), + ], + help_text="A list of buttons that will appear at the bottom of the card.", + max_num=2, + required=False, + ), + ), + ] + ), + ) + ], + help_text="A list of slides.", + ), + ), + ] + ), + ), + ( + "spacer", + wagtail.blocks.StructBlock( + [ + ( + "size", + wagtail.blocks.ChoiceBlock( + choices=[ + ("1", "quarter spacing"), + ("2", "half spacing"), + ("3", "single spacing"), + ("4", "one and a half spacing"), + ("5", "triple spacing"), + ] + ), + ) + ] + ), + ), + ( + "airtable", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="Copied from the Airtable embed code. The word 'embed' will be in the url" + ), + ), + ( + "height", + wagtail.blocks.IntegerBlock( + default=533, + help_text="The pixel height on desktop view, usually copied from the Airtable embed code", + ), + ), + ] + ), + ), + ( + "datawrapper", + wagtail.embeds.blocks.EmbedBlock( + help_text='Enter the "visualization only" link of the Datawrapper chart. It looks something like this: https://datawrapper.dwcdn.net/KwSKp/1/', + icon="image", + template="wagtailpages/blocks/datawrapper_block.html", + ), + ), + ( + "typeform", + wagtail.blocks.StructBlock( + [ + ( + "embed_id", + wagtail.blocks.CharBlock( + help_text="The embed id of your Typeform page (e.g. if the form is on admin.typeform.com/form/e8zScc6t, the id will be: e8zScc6t)", + required=True, + ), + ), + ( + "button_type", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ( + "button_text", + wagtail.blocks.CharBlock( + help_text="This is a text prompt for users to open the typeform content", + required=True, + ), + ), + ] + ), + ), + ], + null=True, + use_json_field=True, + ), + ), + migrations.AlterField( + model_name="buyersguidecampaignpage", + name="body", + field=wagtail.fields.StreamField( + [ + ( + "accordion", + wagtail.blocks.StructBlock( + [ + ( + "accordion_items", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the Accordion Item" + ), + ), + ( + "content", + wagtail.blocks.StreamBlock( + [ + ( + "rich_text", + wagtail.blocks.RichTextBlock( + blank=True, + features=[ + "bold", + "italic", + "link", + "ul", + "ol", + "document-link", + ], + ), + ), + ( + "datawrapper", + wagtail.embeds.blocks.EmbedBlock( + help_text='Enter the "visualization only" link of the Datawrapper chart. It looks something like this: https://datawrapper.dwcdn.net/KwSKp/1/', + icon="image", + template="wagtailpages/blocks/datawrapper_block.html", + ), + ), + ( + "image", + wagtail.blocks.StructBlock( + [ + ( + "image", + wagtail.images.blocks.ImageChooserBlock(), + ), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", + required=True, + ), + ), + ] + ), + ), + ( + "video", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="For YouTube: go to your YouTube video and click “Share,” then “Embed,” and then copy and paste the provided URL only. For example: https://www.youtube.com/embed/3FIVXBawyQw For Vimeo: follow similar steps to grab the embed URL. For example: https://player.vimeo.com/video/9004979", + label="Embed URL", + ), + ), + ( + "caption", + wagtail.blocks.CharBlock(required=False), + ), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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, + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "video_width", + wagtail.blocks.ChoiceBlock( + choices=[ + ("normal", "Normal"), + ("wide", "Wide"), + ("full_width", "Full Width"), + ], + help_text="Wide videos are col-12, Full-Width videos reach both ends of the screen.", + ), + ), + ] + ), + ), + ] + ), + ), + ] + ) + ), + ) + ] + ), + ), + ( + "paragraph", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + ], + template="wagtailpages/blocks/rich_text_block.html", + ), + ), + ( + "card_grid", + wagtail.blocks.StructBlock( + [ + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ("body", wagtail.blocks.TextBlock(help_text="Body text of the card.")), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that this card should link out to. (Note: If left blank, link will not render.) ", + required=False, + ), + ), + ( + "link_label", + wagtail.blocks.CharBlock( + help_text="Optional Label for the URL link above. (Note: If left blank, link will not render.) ", + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + ), + ) + ] + ), + ), + ( + "image_grid", + wagtail.blocks.StructBlock( + [ + ( + "grid_items", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for this image.", required=False + ), + ), + ( + "caption", + wagtail.blocks.CharBlock( + help_text="Please remember to properly attribute any images we use.", + required=False, + ), + ), + ( + "url", + wagtail.blocks.CharBlock( + help_text="Optional URL that this figure should link out to.", + required=False, + ), + ), + ( + "square_image", + wagtail.blocks.BooleanBlock( + default=True, + help_text="If left checked, the image will be cropped to be square.", + required=False, + ), + ), + ] + ) + ), + ) + ] + ), + ), + ( + "iframe", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.CharBlock( + help_text="Please note that only URLs from allow-listed domains will work." + ), + ), + ( + "height", + wagtail.blocks.IntegerBlock( + help_text="Optional integer pixel value for custom iFrame height", + required=False, + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "iframe_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide iframes are col-12, Full-Width iframes reach both ends of the screen", + ), + ), + ( + "disable_scroll", + wagtail.blocks.BooleanBlock( + default=False, + help_text='Checking this will add "scrolling=no" to the iframe. Use this if your iframe is rendering an unnecessary scroll bar or whitespace below it.', + required=False, + ), + ), + ] + ), + ), + ( + "image", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "image_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide images are col-12, Full-Width Images reach both ends of the screen (16:6 images recommended for full width)", + ), + ), + ] + ), + ), + ( + "audio", + wagtail.blocks.StructBlock( + [ + ("audio", wagtailmedia.blocks.AudioChooserBlock()), + ("caption", wagtail.blocks.CharBlock(required=False)), + ] + ), + ), + ( + "image_text", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ( + "text", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + ] + ), + ), + ( + "url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this image should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ] + ), + ), + ( + "image_text_mini", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ("text", wagtail.blocks.RichTextBlock(features=["bold", "italic", "link"])), + ] + ), + ), + ( + "video", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="For YouTube: go to your YouTube video and click “Share,” then “Embed,” and then copy and paste the provided URL only. For example: https://www.youtube.com/embed/3FIVXBawyQw For Vimeo: follow similar steps to grab the embed URL. For example: https://player.vimeo.com/video/9004979", + label="Embed URL", + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "video_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide videos are col-12, Full-Width videos reach both ends of the screen.", + ), + ), + ] + ), + ), + ( + "linkbutton", + 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"', + 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), + ), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ] + ), + ), + ( + "looping_video", + wagtail.blocks.StructBlock( + [ + ( + "video_url", + wagtail.blocks.CharBlock( + help_text='Log into Vimeo using 1Password and upload the desired video. Then select the video and click "Advanced", "Distribution", and "Video File Links". Copy and paste the link here.', + label="Embed URL", + ), + ) + ] + ), + ), + ( + "pulse_listing", + wagtail.blocks.StructBlock( + [ + ( + "search_terms", + wagtail.blocks.CharBlock( + help_text="Test your search at mozillapulse.org/search", + label="Search", + required=False, + ), + ), + ( + "max_number_of_results", + wagtail.blocks.IntegerBlock( + default=6, + help_text="Choose 1-12. If you want visitors to see more, link to a search or tag on Pulse.", + max_value=12, + min_value=0, + required=True, + ), + ), + ( + "only_featured_entries", + wagtail.blocks.BooleanBlock( + default=False, + help_text="Featured items are selected by Pulse moderators.", + label="Display only featured entries", + required=False, + ), + ), + ( + "newest_first", + wagtail.blocks.ChoiceBlock( + choices=[ + ("True", "Show newer entries first"), + ("False", "Show older entries first"), + ], + label="Sort", + ), + ), + ( + "advanced_filter_header", + wagtail.blocks.static_block.StaticBlock( + admin_text="-------- ADVANCED FILTERS: OPTIONS TO DISPLAY FEWER, MORE TARGETED RESULTS. --------", + label=" ", + ), + ), + ( + "issues", + wagtail.blocks.ChoiceBlock( + choices=[ + ("all", "All"), + ("Decentralization", "Decentralization"), + ("Digital Inclusion", "Digital Inclusion"), + ("Online Privacy & Security", "Online Privacy & Security"), + ("Open Innovation", "Open Innovation"), + ("Web Literacy", "Web Literacy"), + ] + ), + ), + ( + "help", + wagtail.blocks.ChoiceBlock( + choices=[ + ("all", "All"), + ("Attend", "Attend"), + ("Create content", "Create content"), + ("Code", "Code"), + ("Design", "Design"), + ("Fundraise", "Fundraise"), + ("Join community", "Join community"), + ("Localize & translate", "Localize & translate"), + ("Mentor", "Mentor"), + ("Plan & organize", "Plan & organize"), + ("Promote", "Promote"), + ("Take action", "Take action"), + ("Test & feedback", "Test & feedback"), + ("Write documentation", "Write documentation"), + ], + label="Type of help needed", + ), + ), + ( + "direct_link", + wagtail.blocks.BooleanBlock( + default=False, + help_text="Checked: user goes to project link. Unchecked: user goes to pulse entry", + label="Direct link", + required=False, + ), + ), + ] + ), + ), + ( + "single_quote", + wagtail.blocks.StructBlock( + [ + ("quote", wagtail.blocks.RichTextBlock(features=["bold"])), + ("attribution", wagtail.blocks.CharBlock(required=False)), + ( + "attribution_info", + wagtail.blocks.RichTextBlock(features=["bold", "link", "large"], required=False), + ), + ] + ), + ), + ( + "slider", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock(help_text="Heading for the slider.", required=False), + ), + ( + "slides", + wagtail.blocks.StreamBlock( + [ + ( + "slide", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading of the card.", required=False + ), + ), + ( + "image", + wagtail.images.blocks.ImageChooserBlock( + help_text="The image associated with this event." + ), + ), + ( + "caption", + wagtail.blocks.TextBlock( + help_text="Caption for slider image", required=False + ), + ), + ( + "body", + wagtail.blocks.RichTextBlock( + blank=True, + features=["bold", "italic", "link", "large"], + required=False, + ), + ), + ( + "buttons", + wagtail.blocks.StreamBlock( + [ + ( + "internal", + wagtail.blocks.StructBlock( + [ + ( + "label", + wagtail.blocks.CharBlock( + help_text="Label for this link." + ), + ), + ( + "link", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to." + ), + ), + ] + ), + ), + ( + "external", + wagtail.blocks.StructBlock( + [ + ( + "label", + wagtail.blocks.CharBlock( + help_text="Label for this link." + ), + ), + ( + "link", + wagtail.blocks.URLBlock( + help_text="URL that this should link out to." + ), + ), + ] + ), + ), + ( + "document", + wagtail.blocks.StructBlock( + [ + ( + "label", + wagtail.blocks.CharBlock( + help_text="Label for this link." + ), + ), + ( + "document", + wagtail.documents.blocks.DocumentChooserBlock( + help_text="Document that this should link out to." + ), + ), + ], + help_text='An iCal document can be attached here for an "Add to Calendar" button.', + ), + ), + ], + help_text="A list of buttons that will appear at the bottom of the card.", + max_num=2, + required=False, + ), + ), + ] + ), + ) + ], + help_text="A list of slides.", + ), + ), + ] + ), + ), + ( + "spacer", + wagtail.blocks.StructBlock( + [ + ( + "size", + wagtail.blocks.ChoiceBlock( + choices=[ + ("1", "quarter spacing"), + ("2", "half spacing"), + ("3", "single spacing"), + ("4", "one and a half spacing"), + ("5", "triple spacing"), + ] + ), + ) + ] + ), + ), + ( + "airtable", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="Copied from the Airtable embed code. The word 'embed' will be in the url" + ), + ), + ( + "height", + wagtail.blocks.IntegerBlock( + default=533, + help_text="The pixel height on desktop view, usually copied from the Airtable embed code", + ), + ), + ] + ), + ), + ( + "datawrapper", + wagtail.embeds.blocks.EmbedBlock( + help_text='Enter the "visualization only" link of the Datawrapper chart. It looks something like this: https://datawrapper.dwcdn.net/KwSKp/1/', + icon="image", + template="wagtailpages/blocks/datawrapper_block.html", + ), + ), + ( + "typeform", + wagtail.blocks.StructBlock( + [ + ( + "embed_id", + wagtail.blocks.CharBlock( + help_text="The embed id of your Typeform page (e.g. if the form is on admin.typeform.com/form/e8zScc6t, the id will be: e8zScc6t)", + required=True, + ), + ), + ( + "button_type", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ( + "button_text", + wagtail.blocks.CharBlock( + help_text="This is a text prompt for users to open the typeform content", + required=True, + ), + ), + ] + ), + ), + ], + use_json_field=True, + ), + ), + migrations.AlterField( + model_name="modularpage", + name="body", + field=wagtail.fields.StreamField( + [ + ( + "paragraph", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + "large", + ], + template="wagtailpages/blocks/rich_text_block.html", + ), + ), + ( + "card_grid", + wagtail.blocks.StructBlock( + [ + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ("body", wagtail.blocks.TextBlock(help_text="Body text of the card.")), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that this card should link out to. (Note: If left blank, link will not render.) ", + required=False, + ), + ), + ( + "link_label", + wagtail.blocks.CharBlock( + help_text="Optional Label for the URL link above. (Note: If left blank, link will not render.) ", + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + ), + ) + ] + ), + ), + ( + "image", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "image_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide images are col-12, Full-Width Images reach both ends of the screen (16:6 images recommended for full width)", + ), + ), + ] + ), + ), + ( + "image_text", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ( + "text", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + ] + ), + ), + ( + "url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this image should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ] + ), + ), + ( + "image_text_mini", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ("text", wagtail.blocks.RichTextBlock(features=["bold", "italic", "link"])), + ] + ), + ), + ( + "image_grid", + wagtail.blocks.StructBlock( + [ + ( + "grid_items", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for this image.", required=False + ), + ), + ( + "caption", + wagtail.blocks.CharBlock( + help_text="Please remember to properly attribute any images we use.", + required=False, + ), + ), + ( + "url", + wagtail.blocks.CharBlock( + help_text="Optional URL that this figure should link out to.", + required=False, + ), + ), + ( + "square_image", + wagtail.blocks.BooleanBlock( + default=True, + help_text="If left checked, the image will be cropped to be square.", + required=False, + ), + ), + ] + ) + ), + ) + ] + ), + ), + ( + "video", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="For YouTube: go to your YouTube video and click “Share,” then “Embed,” and then copy and paste the provided URL only. For example: https://www.youtube.com/embed/3FIVXBawyQw For Vimeo: follow similar steps to grab the embed URL. For example: https://player.vimeo.com/video/9004979", + label="Embed URL", + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "video_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide videos are col-12, Full-Width videos reach both ends of the screen.", + ), + ), + ] + ), + ), + ( + "iframe", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.CharBlock( + help_text="Please note that only URLs from allow-listed domains will work." + ), + ), + ( + "height", + wagtail.blocks.IntegerBlock( + help_text="Optional integer pixel value for custom iFrame height", + required=False, + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "iframe_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide iframes are col-12, Full-Width iframes reach both ends of the screen", + ), + ), + ( + "disable_scroll", + wagtail.blocks.BooleanBlock( + default=False, + help_text='Checking this will add "scrolling=no" to the iframe. Use this if your iframe is rendering an unnecessary scroll bar or whitespace below it.', + required=False, + ), + ), + ] + ), + ), + ( + "linkbutton", + 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"', + 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), + ), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ] + ), + ), + ( + "spacer", + wagtail.blocks.StructBlock( + [ + ( + "size", + wagtail.blocks.ChoiceBlock( + choices=[ + ("1", "quarter spacing"), + ("2", "half spacing"), + ("3", "single spacing"), + ("4", "one and a half spacing"), + ("5", "triple spacing"), + ] + ), + ) + ] + ), + ), + ( + "single_quote", + wagtail.blocks.StructBlock( + [ + ("quote", wagtail.blocks.RichTextBlock(features=["bold"])), + ("attribution", wagtail.blocks.CharBlock(required=False)), + ( + "attribution_info", + wagtail.blocks.RichTextBlock(features=["bold", "link", "large"], required=False), + ), + ] + ), + ), + ( + "pulse_listing", + wagtail.blocks.StructBlock( + [ + ( + "search_terms", + wagtail.blocks.CharBlock( + help_text="Test your search at mozillapulse.org/search", + label="Search", + required=False, + ), + ), + ( + "max_number_of_results", + wagtail.blocks.IntegerBlock( + default=6, + help_text="Choose 1-12. If you want visitors to see more, link to a search or tag on Pulse.", + max_value=12, + min_value=0, + required=True, + ), + ), + ( + "only_featured_entries", + wagtail.blocks.BooleanBlock( + default=False, + help_text="Featured items are selected by Pulse moderators.", + label="Display only featured entries", + required=False, + ), + ), + ( + "newest_first", + wagtail.blocks.ChoiceBlock( + choices=[ + ("True", "Show newer entries first"), + ("False", "Show older entries first"), + ], + label="Sort", + ), + ), + ( + "advanced_filter_header", + wagtail.blocks.static_block.StaticBlock( + admin_text="-------- ADVANCED FILTERS: OPTIONS TO DISPLAY FEWER, MORE TARGETED RESULTS. --------", + label=" ", + ), + ), + ( + "issues", + wagtail.blocks.ChoiceBlock( + choices=[ + ("all", "All"), + ("Decentralization", "Decentralization"), + ("Digital Inclusion", "Digital Inclusion"), + ("Online Privacy & Security", "Online Privacy & Security"), + ("Open Innovation", "Open Innovation"), + ("Web Literacy", "Web Literacy"), + ] + ), + ), + ( + "help", + wagtail.blocks.ChoiceBlock( + choices=[ + ("all", "All"), + ("Attend", "Attend"), + ("Create content", "Create content"), + ("Code", "Code"), + ("Design", "Design"), + ("Fundraise", "Fundraise"), + ("Join community", "Join community"), + ("Localize & translate", "Localize & translate"), + ("Mentor", "Mentor"), + ("Plan & organize", "Plan & organize"), + ("Promote", "Promote"), + ("Take action", "Take action"), + ("Test & feedback", "Test & feedback"), + ("Write documentation", "Write documentation"), + ], + label="Type of help needed", + ), + ), + ( + "direct_link", + wagtail.blocks.BooleanBlock( + default=False, + help_text="Checked: user goes to project link. Unchecked: user goes to pulse entry", + label="Direct link", + required=False, + ), + ), + ] + ), + ), + ( + "profile_listing", + wagtail.blocks.StructBlock( + [ + ( + "max_number_of_results", + wagtail.blocks.IntegerBlock( + default=12, + help_text="Pick up to 48 profiles.", + max_value=48, + min_value=1, + required=True, + ), + ), + ( + "advanced_filter_header", + wagtail.blocks.static_block.StaticBlock( + admin_text="-------- ADVANCED FILTERS: OPTIONS TO DISPLAY FEWER, MORE TARGETED RESULTS. --------", + label=" ", + ), + ), + ( + "profile_type", + wagtail.blocks.CharBlock(default="", help_text="Example: Fellow.", required=False), + ), + ( + "program_type", + wagtail.blocks.CharBlock( + default="", help_text="Example: Tech Policy.", required=False + ), + ), + ("year", wagtail.blocks.CharBlock(default="", required=False)), + ] + ), + ), + ( + "profile_by_id", + wagtail.blocks.StructBlock( + [ + ( + "ids", + wagtail.blocks.CharBlock( + help_text="Show profiles for pulse users with specific profile ids (mozillapulse.org/profile/[##]). For multiple profiles, specify a comma separated list (e.g. 85,105,332).", + label="Profile by ID", + ), + ) + ] + ), + ), + ( + "profile_directory", + wagtail.blocks.StructBlock( + [ + ( + "max_number_of_results", + wagtail.blocks.IntegerBlock( + default=12, + help_text="Pick up to 48 profiles.", + max_value=48, + min_value=1, + required=True, + ), + ), + ( + "advanced_filter_header", + wagtail.blocks.static_block.StaticBlock( + admin_text="-------- ADVANCED FILTERS: OPTIONS TO DISPLAY FEWER, MORE TARGETED RESULTS. --------", + label=" ", + ), + ), + ( + "profile_type", + wagtail.blocks.CharBlock(default="", help_text="Example: Fellow.", required=False), + ), + ( + "program_type", + wagtail.blocks.CharBlock( + default="", help_text="Example: Tech Policy.", required=False + ), + ), + ("year", wagtail.blocks.CharBlock(default="", required=False)), + ( + "filter_values", + wagtail.blocks.CharBlock( + default="2019,2018,2017,2016,2015,2014,2013", + help_text="Example: 2019,2018,2017,2016,2015,2014,2013", + required=True, + ), + ), + ] + ), + ), + ( + "recent_blog_entries", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock(required=False)), + ( + "tag_filter", + wagtail.blocks.CharBlock( + help_text="Test this filter at foundation.mozilla.org/blog/tags/", + label="Filter by Tag", + required=False, + ), + ), + ( + "topic_filter", + wagtail.blocks.ChoiceBlock( + choices=networkapi.wagtailpages.pagemodels.blog.blog_topic.BlogPageTopic.get_topics, + help_text="Test this filter at foundation.mozilla.org/blog/topic/", + label="Filter by Topic", + required=False, + ), + ), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ] + ), + ), + ( + "blog_set", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock()), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ( + "blog_pages", + wagtail.blocks.ListBlock( + wagtail.blocks.PageChooserBlock(page_type=["wagtailpages.BlogPage"]) + ), + ), + ] + ), + ), + ( + "airtable", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="Copied from the Airtable embed code. The word 'embed' will be in the url" + ), + ), + ( + "height", + wagtail.blocks.IntegerBlock( + default=533, + help_text="The pixel height on desktop view, usually copied from the Airtable embed code", + ), + ), + ] + ), + ), + ( + "typeform", + wagtail.blocks.StructBlock( + [ + ( + "embed_id", + wagtail.blocks.CharBlock( + help_text="The embed id of your Typeform page (e.g. if the form is on admin.typeform.com/form/e8zScc6t, the id will be: e8zScc6t)", + required=True, + ), + ), + ( + "button_type", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ( + "button_text", + wagtail.blocks.CharBlock( + help_text="This is a text prompt for users to open the typeform content", + required=True, + ), + ), + ] + ), + ), + ( + "datawrapper", + wagtail.embeds.blocks.EmbedBlock( + help_text='Enter the "visualization only" link of the Datawrapper chart. It looks something like this: https://datawrapper.dwcdn.net/KwSKp/1/', + icon="image", + template="wagtailpages/blocks/datawrapper_block.html", + ), + ), + ( + "listing", + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock(help_text="Heading for the block.", required=False), + ), + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ( + "highlighted_metadata", + wagtail.blocks.CharBlock( + help_text="Metadata to highlight on the card.", required=False + ), + ), + ( + "metadata", + wagtail.blocks.CharBlock( + help_text="Generic metadata.", required=False + ), + ), + ( + "body", + wagtail.blocks.RichTextBlock( + features=["bold"], + help_text="Body text of the card.", + required=False, + ), + ), + ( + "link_page", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to.", required=False + ), + ), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that the header should link out to.", + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + min_num=2, + ), + ), + ( + "cards_per_row", + wagtail.blocks.ChoiceBlock( + choices=[(2, "2"), (3, "3")], + help_text="Number of cards per row. Note: this is a max and fewer might be used if is less space is available.", + required=False, + ), + ), + ] + ), + ), + ( + "profiles", + wagtail.blocks.StructBlock( + [ + ( + "profiles", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "profile", + wagtail.snippets.blocks.SnippetChooserBlock( + networkapi.wagtailpages.pagemodels.profiles.Profile + ), + ) + ] + ), + min_num=1, + ), + ) + ] + ), + ), + ( + "article_teaser_block", + wagtail.blocks.StructBlock( + [ + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "article", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to.", + page_type=["wagtailpages.ArticlePage"], + required=False, + ), + ) + ] + ), + help_text="Please use a minimum of 3 cards.", + min_num=3, + ), + ) + ] + ), + ), + ( + "group_listing_block", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the group of cards.", required=False + ), + ), + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ( + "meta_data", + wagtail.blocks.CharBlock( + help_text="Optional meta data information for the card.", + required=False, + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ( + "body", + wagtail.blocks.RichTextBlock( + features=["bold", "link"], help_text="Body text of the card." + ), + ), + ( + "url", + wagtail.blocks.CharBlock( + help_text="The URL this card should link to.", required=False + ), + ), + ] + ) + ), + ), + ] + ), + ), + ( + "image_feature", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock(help_text="Image description (for screen readers)."), + ), + ("metadata", wagtail.blocks.CharBlock(required=False)), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ( + "title_link", + wagtail.blocks.PageChooserBlock( + help_text="Page that the title should link out to.", required=False + ), + ), + ("body", wagtail.blocks.CharBlock(required=False)), + ] + ), + ), + ( + "image_teaser_block", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ("text", wagtail.blocks.RichTextBlock(features=["bold"])), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ("url_label", wagtail.blocks.CharBlock(required=False)), + ("url", wagtail.blocks.CharBlock(required=False)), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ] + ), + ), + ( + "text_only_teaser", + wagtail.blocks.StructBlock( + [ + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock(help_text="Heading for the card."), + ), + ( + "link_page", + wagtail.blocks.PageChooserBlock( + help_text="Page that the header should link out to.", + required=False, + ), + ), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that the header should link out to.", + required=False, + ), + ), + ("meta_data", wagtail.blocks.CharBlock(max_length=500)), + ( + "body", + wagtail.blocks.TextBlock( + help_text="Body text of the card.", + max_length=200, + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 3 cards.", + min_num=3, + ), + ) + ] + ), + ), + ( + "block_with_aside", + wagtail.blocks.StructBlock( + [ + ( + "content", + wagtail.blocks.StreamBlock( + [ + ( + "listing", + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock( + help_text="Heading for the block.", required=False + ), + ), + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "image", + wagtail.images.blocks.ImageChooserBlock(), + ), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", + required=False, + ), + ), + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the card." + ), + ), + ( + "highlighted_metadata", + wagtail.blocks.CharBlock( + help_text="Metadata to highlight on the card.", + required=False, + ), + ), + ( + "metadata", + wagtail.blocks.CharBlock( + help_text="Generic metadata.", + required=False, + ), + ), + ( + "body", + wagtail.blocks.RichTextBlock( + features=["bold"], + help_text="Body text of the card.", + required=False, + ), + ), + ( + "link_page", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to.", + required=False, + ), + ), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that the header should link out to.", + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + min_num=2, + ), + ), + ( + "cards_per_row", + wagtail.blocks.ChoiceBlock( + choices=[(2, "2"), (3, "3")], + help_text="Number of cards per row. Note: this is a max and fewer might be used if is less space is available.", + required=False, + ), + ), + ] + ), + ), + ( + "paragraph", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + ] + ), + ), + ], + help_text="The wider block that appears on the left on desktop", + icon="doc-full", + max_num=1, + ), + ), + ( + "aside", + wagtail.blocks.StreamBlock( + [ + ( + "aside_content", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the card.", required=False + ), + ), + ( + "body", + wagtail.blocks.TextBlock( + help_text="Body text of the card.", required=False + ), + ), + ] + ), + ), + ( + "linkbutton", + 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"', + 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 + ), + ), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ] + ), + ), + ( + "spacer", + wagtail.blocks.StructBlock( + [ + ( + "size", + wagtail.blocks.ChoiceBlock( + choices=[ + ("1", "quarter spacing"), + ("2", "half spacing"), + ("3", "single spacing"), + ("4", "one and a half spacing"), + ("5", "triple spacing"), + ] + ), + ) + ] + ), + ), + ], + help_text="Elements here will appear in the column on the right side of the page on desktop. This can be left blank if you would just like a 2/3 column on the left", + icon="doc-full", + required=False, + ), + ), + ] + ), + ), + ( + "accordion", + wagtail.blocks.StructBlock( + [ + ( + "accordion_items", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the Accordion Item" + ), + ), + ( + "content", + wagtail.blocks.StreamBlock( + [ + ( + "rich_text", + wagtail.blocks.RichTextBlock( + blank=True, + features=[ + "bold", + "italic", + "link", + "ul", + "ol", + "document-link", + ], + ), + ), + ( + "datawrapper", + wagtail.embeds.blocks.EmbedBlock( + help_text='Enter the "visualization only" link of the Datawrapper chart. It looks something like this: https://datawrapper.dwcdn.net/KwSKp/1/', + icon="image", + template="wagtailpages/blocks/datawrapper_block.html", + ), + ), + ( + "image", + wagtail.blocks.StructBlock( + [ + ( + "image", + wagtail.images.blocks.ImageChooserBlock(), + ), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", + required=True, + ), + ), + ] + ), + ), + ( + "video", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="For YouTube: go to your YouTube video and click “Share,” then “Embed,” and then copy and paste the provided URL only. For example: https://www.youtube.com/embed/3FIVXBawyQw For Vimeo: follow similar steps to grab the embed URL. For example: https://player.vimeo.com/video/9004979", + label="Embed URL", + ), + ), + ( + "caption", + wagtail.blocks.CharBlock(required=False), + ), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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, + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "video_width", + wagtail.blocks.ChoiceBlock( + choices=[ + ("normal", "Normal"), + ("wide", "Wide"), + ("full_width", "Full Width"), + ], + help_text="Wide videos are col-12, Full-Width videos reach both ends of the screen.", + ), + ), + ] + ), + ), + ] + ), + ), + ] + ) + ), + ) + ] + ), + ), + ], + use_json_field=True, + ), + ), + migrations.AlterField( + model_name="primarypage", + name="body", + field=wagtail.fields.StreamField( + [ + ( + "paragraph", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + "large", + ], + template="wagtailpages/blocks/rich_text_block.html", + ), + ), + ( + "card_grid", + wagtail.blocks.StructBlock( + [ + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ("body", wagtail.blocks.TextBlock(help_text="Body text of the card.")), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that this card should link out to. (Note: If left blank, link will not render.) ", + required=False, + ), + ), + ( + "link_label", + wagtail.blocks.CharBlock( + help_text="Optional Label for the URL link above. (Note: If left blank, link will not render.) ", + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + ), + ) + ] + ), + ), + ( + "image", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "image_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide images are col-12, Full-Width Images reach both ends of the screen (16:6 images recommended for full width)", + ), + ), + ] + ), + ), + ( + "image_text", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ( + "text", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + ] + ), + ), + ( + "url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this image should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ] + ), + ), + ( + "image_text_mini", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ("text", wagtail.blocks.RichTextBlock(features=["bold", "italic", "link"])), + ] + ), + ), + ( + "image_grid", + wagtail.blocks.StructBlock( + [ + ( + "grid_items", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for this image.", required=False + ), + ), + ( + "caption", + wagtail.blocks.CharBlock( + help_text="Please remember to properly attribute any images we use.", + required=False, + ), + ), + ( + "url", + wagtail.blocks.CharBlock( + help_text="Optional URL that this figure should link out to.", + required=False, + ), + ), + ( + "square_image", + wagtail.blocks.BooleanBlock( + default=True, + help_text="If left checked, the image will be cropped to be square.", + required=False, + ), + ), + ] + ) + ), + ) + ] + ), + ), + ( + "video", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="For YouTube: go to your YouTube video and click “Share,” then “Embed,” and then copy and paste the provided URL only. For example: https://www.youtube.com/embed/3FIVXBawyQw For Vimeo: follow similar steps to grab the embed URL. For example: https://player.vimeo.com/video/9004979", + label="Embed URL", + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "video_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide videos are col-12, Full-Width videos reach both ends of the screen.", + ), + ), + ] + ), + ), + ( + "iframe", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.CharBlock( + help_text="Please note that only URLs from allow-listed domains will work." + ), + ), + ( + "height", + wagtail.blocks.IntegerBlock( + help_text="Optional integer pixel value for custom iFrame height", + required=False, + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "iframe_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide iframes are col-12, Full-Width iframes reach both ends of the screen", + ), + ), + ( + "disable_scroll", + wagtail.blocks.BooleanBlock( + default=False, + help_text='Checking this will add "scrolling=no" to the iframe. Use this if your iframe is rendering an unnecessary scroll bar or whitespace below it.', + required=False, + ), + ), + ] + ), + ), + ( + "linkbutton", + 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"', + 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), + ), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ] + ), + ), + ( + "spacer", + wagtail.blocks.StructBlock( + [ + ( + "size", + wagtail.blocks.ChoiceBlock( + choices=[ + ("1", "quarter spacing"), + ("2", "half spacing"), + ("3", "single spacing"), + ("4", "one and a half spacing"), + ("5", "triple spacing"), + ] + ), + ) + ] + ), + ), + ( + "single_quote", + wagtail.blocks.StructBlock( + [ + ("quote", wagtail.blocks.RichTextBlock(features=["bold"])), + ("attribution", wagtail.blocks.CharBlock(required=False)), + ( + "attribution_info", + wagtail.blocks.RichTextBlock(features=["bold", "link", "large"], required=False), + ), + ] + ), + ), + ( + "pulse_listing", + wagtail.blocks.StructBlock( + [ + ( + "search_terms", + wagtail.blocks.CharBlock( + help_text="Test your search at mozillapulse.org/search", + label="Search", + required=False, + ), + ), + ( + "max_number_of_results", + wagtail.blocks.IntegerBlock( + default=6, + help_text="Choose 1-12. If you want visitors to see more, link to a search or tag on Pulse.", + max_value=12, + min_value=0, + required=True, + ), + ), + ( + "only_featured_entries", + wagtail.blocks.BooleanBlock( + default=False, + help_text="Featured items are selected by Pulse moderators.", + label="Display only featured entries", + required=False, + ), + ), + ( + "newest_first", + wagtail.blocks.ChoiceBlock( + choices=[ + ("True", "Show newer entries first"), + ("False", "Show older entries first"), + ], + label="Sort", + ), + ), + ( + "advanced_filter_header", + wagtail.blocks.static_block.StaticBlock( + admin_text="-------- ADVANCED FILTERS: OPTIONS TO DISPLAY FEWER, MORE TARGETED RESULTS. --------", + label=" ", + ), + ), + ( + "issues", + wagtail.blocks.ChoiceBlock( + choices=[ + ("all", "All"), + ("Decentralization", "Decentralization"), + ("Digital Inclusion", "Digital Inclusion"), + ("Online Privacy & Security", "Online Privacy & Security"), + ("Open Innovation", "Open Innovation"), + ("Web Literacy", "Web Literacy"), + ] + ), + ), + ( + "help", + wagtail.blocks.ChoiceBlock( + choices=[ + ("all", "All"), + ("Attend", "Attend"), + ("Create content", "Create content"), + ("Code", "Code"), + ("Design", "Design"), + ("Fundraise", "Fundraise"), + ("Join community", "Join community"), + ("Localize & translate", "Localize & translate"), + ("Mentor", "Mentor"), + ("Plan & organize", "Plan & organize"), + ("Promote", "Promote"), + ("Take action", "Take action"), + ("Test & feedback", "Test & feedback"), + ("Write documentation", "Write documentation"), + ], + label="Type of help needed", + ), + ), + ( + "direct_link", + wagtail.blocks.BooleanBlock( + default=False, + help_text="Checked: user goes to project link. Unchecked: user goes to pulse entry", + label="Direct link", + required=False, + ), + ), + ] + ), + ), + ( + "profile_listing", + wagtail.blocks.StructBlock( + [ + ( + "max_number_of_results", + wagtail.blocks.IntegerBlock( + default=12, + help_text="Pick up to 48 profiles.", + max_value=48, + min_value=1, + required=True, + ), + ), + ( + "advanced_filter_header", + wagtail.blocks.static_block.StaticBlock( + admin_text="-------- ADVANCED FILTERS: OPTIONS TO DISPLAY FEWER, MORE TARGETED RESULTS. --------", + label=" ", + ), + ), + ( + "profile_type", + wagtail.blocks.CharBlock(default="", help_text="Example: Fellow.", required=False), + ), + ( + "program_type", + wagtail.blocks.CharBlock( + default="", help_text="Example: Tech Policy.", required=False + ), + ), + ("year", wagtail.blocks.CharBlock(default="", required=False)), + ] + ), + ), + ( + "profile_by_id", + wagtail.blocks.StructBlock( + [ + ( + "ids", + wagtail.blocks.CharBlock( + help_text="Show profiles for pulse users with specific profile ids (mozillapulse.org/profile/[##]). For multiple profiles, specify a comma separated list (e.g. 85,105,332).", + label="Profile by ID", + ), + ) + ] + ), + ), + ( + "profile_directory", + wagtail.blocks.StructBlock( + [ + ( + "max_number_of_results", + wagtail.blocks.IntegerBlock( + default=12, + help_text="Pick up to 48 profiles.", + max_value=48, + min_value=1, + required=True, + ), + ), + ( + "advanced_filter_header", + wagtail.blocks.static_block.StaticBlock( + admin_text="-------- ADVANCED FILTERS: OPTIONS TO DISPLAY FEWER, MORE TARGETED RESULTS. --------", + label=" ", + ), + ), + ( + "profile_type", + wagtail.blocks.CharBlock(default="", help_text="Example: Fellow.", required=False), + ), + ( + "program_type", + wagtail.blocks.CharBlock( + default="", help_text="Example: Tech Policy.", required=False + ), + ), + ("year", wagtail.blocks.CharBlock(default="", required=False)), + ( + "filter_values", + wagtail.blocks.CharBlock( + default="2019,2018,2017,2016,2015,2014,2013", + help_text="Example: 2019,2018,2017,2016,2015,2014,2013", + required=True, + ), + ), + ] + ), + ), + ( + "recent_blog_entries", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock(required=False)), + ( + "tag_filter", + wagtail.blocks.CharBlock( + help_text="Test this filter at foundation.mozilla.org/blog/tags/", + label="Filter by Tag", + required=False, + ), + ), + ( + "topic_filter", + wagtail.blocks.ChoiceBlock( + choices=networkapi.wagtailpages.pagemodels.blog.blog_topic.BlogPageTopic.get_topics, + help_text="Test this filter at foundation.mozilla.org/blog/topic/", + label="Filter by Topic", + required=False, + ), + ), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ] + ), + ), + ( + "blog_set", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock()), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ( + "blog_pages", + wagtail.blocks.ListBlock( + wagtail.blocks.PageChooserBlock(page_type=["wagtailpages.BlogPage"]) + ), + ), + ] + ), + ), + ( + "airtable", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="Copied from the Airtable embed code. The word 'embed' will be in the url" + ), + ), + ( + "height", + wagtail.blocks.IntegerBlock( + default=533, + help_text="The pixel height on desktop view, usually copied from the Airtable embed code", + ), + ), + ] + ), + ), + ( + "typeform", + wagtail.blocks.StructBlock( + [ + ( + "embed_id", + wagtail.blocks.CharBlock( + help_text="The embed id of your Typeform page (e.g. if the form is on admin.typeform.com/form/e8zScc6t, the id will be: e8zScc6t)", + required=True, + ), + ), + ( + "button_type", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ( + "button_text", + wagtail.blocks.CharBlock( + help_text="This is a text prompt for users to open the typeform content", + required=True, + ), + ), + ] + ), + ), + ( + "datawrapper", + wagtail.embeds.blocks.EmbedBlock( + help_text='Enter the "visualization only" link of the Datawrapper chart. It looks something like this: https://datawrapper.dwcdn.net/KwSKp/1/', + icon="image", + template="wagtailpages/blocks/datawrapper_block.html", + ), + ), + ( + "listing", + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock(help_text="Heading for the block.", required=False), + ), + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ( + "highlighted_metadata", + wagtail.blocks.CharBlock( + help_text="Metadata to highlight on the card.", required=False + ), + ), + ( + "metadata", + wagtail.blocks.CharBlock( + help_text="Generic metadata.", required=False + ), + ), + ( + "body", + wagtail.blocks.RichTextBlock( + features=["bold"], + help_text="Body text of the card.", + required=False, + ), + ), + ( + "link_page", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to.", required=False + ), + ), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that the header should link out to.", + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + min_num=2, + ), + ), + ( + "cards_per_row", + wagtail.blocks.ChoiceBlock( + choices=[(2, "2"), (3, "3")], + help_text="Number of cards per row. Note: this is a max and fewer might be used if is less space is available.", + required=False, + ), + ), + ] + ), + ), + ( + "profiles", + wagtail.blocks.StructBlock( + [ + ( + "profiles", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "profile", + wagtail.snippets.blocks.SnippetChooserBlock( + networkapi.wagtailpages.pagemodels.profiles.Profile + ), + ) + ] + ), + min_num=1, + ), + ) + ] + ), + ), + ( + "article_teaser_block", + wagtail.blocks.StructBlock( + [ + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "article", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to.", + page_type=["wagtailpages.ArticlePage"], + required=False, + ), + ) + ] + ), + help_text="Please use a minimum of 3 cards.", + min_num=3, + ), + ) + ] + ), + ), + ( + "group_listing_block", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the group of cards.", required=False + ), + ), + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ( + "meta_data", + wagtail.blocks.CharBlock( + help_text="Optional meta data information for the card.", + required=False, + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ( + "body", + wagtail.blocks.RichTextBlock( + features=["bold", "link"], help_text="Body text of the card." + ), + ), + ( + "url", + wagtail.blocks.CharBlock( + help_text="The URL this card should link to.", required=False + ), + ), + ] + ) + ), + ), + ] + ), + ), + ( + "image_feature", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock(help_text="Image description (for screen readers)."), + ), + ("metadata", wagtail.blocks.CharBlock(required=False)), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ( + "title_link", + wagtail.blocks.PageChooserBlock( + help_text="Page that the title should link out to.", required=False + ), + ), + ("body", wagtail.blocks.CharBlock(required=False)), + ] + ), + ), + ( + "image_teaser_block", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ("text", wagtail.blocks.RichTextBlock(features=["bold"])), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ("url_label", wagtail.blocks.CharBlock(required=False)), + ("url", wagtail.blocks.CharBlock(required=False)), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ] + ), + ), + ( + "text_only_teaser", + wagtail.blocks.StructBlock( + [ + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock(help_text="Heading for the card."), + ), + ( + "link_page", + wagtail.blocks.PageChooserBlock( + help_text="Page that the header should link out to.", + required=False, + ), + ), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that the header should link out to.", + required=False, + ), + ), + ("meta_data", wagtail.blocks.CharBlock(max_length=500)), + ( + "body", + wagtail.blocks.TextBlock( + help_text="Body text of the card.", + max_length=200, + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 3 cards.", + min_num=3, + ), + ) + ] + ), + ), + ( + "block_with_aside", + wagtail.blocks.StructBlock( + [ + ( + "content", + wagtail.blocks.StreamBlock( + [ + ( + "listing", + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock( + help_text="Heading for the block.", required=False + ), + ), + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "image", + wagtail.images.blocks.ImageChooserBlock(), + ), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", + required=False, + ), + ), + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the card." + ), + ), + ( + "highlighted_metadata", + wagtail.blocks.CharBlock( + help_text="Metadata to highlight on the card.", + required=False, + ), + ), + ( + "metadata", + wagtail.blocks.CharBlock( + help_text="Generic metadata.", + required=False, + ), + ), + ( + "body", + wagtail.blocks.RichTextBlock( + features=["bold"], + help_text="Body text of the card.", + required=False, + ), + ), + ( + "link_page", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to.", + required=False, + ), + ), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that the header should link out to.", + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + min_num=2, + ), + ), + ( + "cards_per_row", + wagtail.blocks.ChoiceBlock( + choices=[(2, "2"), (3, "3")], + help_text="Number of cards per row. Note: this is a max and fewer might be used if is less space is available.", + required=False, + ), + ), + ] + ), + ), + ( + "paragraph", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + ] + ), + ), + ], + help_text="The wider block that appears on the left on desktop", + icon="doc-full", + max_num=1, + ), + ), + ( + "aside", + wagtail.blocks.StreamBlock( + [ + ( + "aside_content", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the card.", required=False + ), + ), + ( + "body", + wagtail.blocks.TextBlock( + help_text="Body text of the card.", required=False + ), + ), + ] + ), + ), + ( + "linkbutton", + 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"', + 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 + ), + ), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ] + ), + ), + ( + "spacer", + wagtail.blocks.StructBlock( + [ + ( + "size", + wagtail.blocks.ChoiceBlock( + choices=[ + ("1", "quarter spacing"), + ("2", "half spacing"), + ("3", "single spacing"), + ("4", "one and a half spacing"), + ("5", "triple spacing"), + ] + ), + ) + ] + ), + ), + ], + help_text="Elements here will appear in the column on the right side of the page on desktop. This can be left blank if you would just like a 2/3 column on the left", + icon="doc-full", + required=False, + ), + ), + ] + ), + ), + ( + "accordion", + wagtail.blocks.StructBlock( + [ + ( + "accordion_items", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the Accordion Item" + ), + ), + ( + "content", + wagtail.blocks.StreamBlock( + [ + ( + "rich_text", + wagtail.blocks.RichTextBlock( + blank=True, + features=[ + "bold", + "italic", + "link", + "ul", + "ol", + "document-link", + ], + ), + ), + ( + "datawrapper", + wagtail.embeds.blocks.EmbedBlock( + help_text='Enter the "visualization only" link of the Datawrapper chart. It looks something like this: https://datawrapper.dwcdn.net/KwSKp/1/', + icon="image", + template="wagtailpages/blocks/datawrapper_block.html", + ), + ), + ( + "image", + wagtail.blocks.StructBlock( + [ + ( + "image", + wagtail.images.blocks.ImageChooserBlock(), + ), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", + required=True, + ), + ), + ] + ), + ), + ( + "video", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="For YouTube: go to your YouTube video and click “Share,” then “Embed,” and then copy and paste the provided URL only. For example: https://www.youtube.com/embed/3FIVXBawyQw For Vimeo: follow similar steps to grab the embed URL. For example: https://player.vimeo.com/video/9004979", + label="Embed URL", + ), + ), + ( + "caption", + wagtail.blocks.CharBlock(required=False), + ), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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, + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "video_width", + wagtail.blocks.ChoiceBlock( + choices=[ + ("normal", "Normal"), + ("wide", "Wide"), + ("full_width", "Full Width"), + ], + help_text="Wide videos are col-12, Full-Width videos reach both ends of the screen.", + ), + ), + ] + ), + ), + ] + ), + ), + ] + ) + ), + ) + ] + ), + ), + ], + use_json_field=True, + ), + ), + ] diff --git a/network-api/networkapi/wagtailpages/migrations/0146_update_imageteaserblock_with_linkblock.py b/network-api/networkapi/wagtailpages/migrations/0146_update_imageteaserblock_with_linkblock.py new file mode 100644 index 00000000000..6f361923af9 --- /dev/null +++ b/network-api/networkapi/wagtailpages/migrations/0146_update_imageteaserblock_with_linkblock.py @@ -0,0 +1,7341 @@ +# Generated by Django 4.2.14 on 2024-07-15 23:38 + +import wagtail.blocks +import wagtail.blocks.static_block +import wagtail.documents.blocks +import wagtail.embeds.blocks +import wagtail.fields +import wagtail.images.blocks +import wagtail.snippets.blocks +from django.db import migrations +from wagtail.blocks.migrations.migrate_operation import MigrateStreamData + +import networkapi.wagtailpages.pagemodels.blog.blog_topic +import networkapi.wagtailpages.pagemodels.profiles +import networkapi.wagtailpages.validators +from networkapi.utility.migration.operations import AlterStreamChildBlockDataOperation + + +def migrate_image_teaser_block(source_block): + new_value = { + "title": source_block["value"].get("title", ""), + "text": source_block["value"].get("text", ""), + "image": source_block["value"].get("image"), + "altText": source_block["value"].get("altText", ""), + "link": [], + "styling": source_block["value"].get("styling", "btn-primary"), + "top_divider": source_block["value"].get("top_divider", False), + "bottom_divider": source_block["value"].get("bottom_divider", False), + } + if "url" in source_block["value"] and source_block["value"]["url"]: + new_value["link_button"] = [ + { + "link_to": "external_url", + "external_url": source_block["value"]["url"], + "label": source_block["value"].get("url_label", ""), + "new_window": True, + "styling": source_block["value"].get("styling", "btn-primary"), + } + ] + return { + **source_block, + "value": new_value, + } + + +class Migration(migrations.Migration): + + dependencies = [ + ("wagtailpages", "0145_update_videoblock_with_linkblock"), + ] + + operations = [ + migrations.AlterField( + model_name="modularpage", + name="body", + field=wagtail.fields.StreamField( + [ + ( + "paragraph", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + "large", + ], + template="wagtailpages/blocks/rich_text_block.html", + ), + ), + ( + "card_grid", + wagtail.blocks.StructBlock( + [ + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ("body", wagtail.blocks.TextBlock(help_text="Body text of the card.")), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that this card should link out to. (Note: If left blank, link will not render.) ", + required=False, + ), + ), + ( + "link_label", + wagtail.blocks.CharBlock( + help_text="Optional Label for the URL link above. (Note: If left blank, link will not render.) ", + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + ), + ) + ] + ), + ), + ( + "image", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "image_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide images are col-12, Full-Width Images reach both ends of the screen (16:6 images recommended for full width)", + ), + ), + ] + ), + ), + ( + "image_text", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ( + "text", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + ] + ), + ), + ( + "url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this image should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ] + ), + ), + ( + "image_text_mini", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ("text", wagtail.blocks.RichTextBlock(features=["bold", "italic", "link"])), + ] + ), + ), + ( + "image_grid", + wagtail.blocks.StructBlock( + [ + ( + "grid_items", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for this image.", required=False + ), + ), + ( + "caption", + wagtail.blocks.CharBlock( + help_text="Please remember to properly attribute any images we use.", + required=False, + ), + ), + ( + "url", + wagtail.blocks.CharBlock( + help_text="Optional URL that this figure should link out to.", + required=False, + ), + ), + ( + "square_image", + wagtail.blocks.BooleanBlock( + default=True, + help_text="If left checked, the image will be cropped to be square.", + required=False, + ), + ), + ] + ) + ), + ) + ] + ), + ), + ( + "video", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="For YouTube: go to your YouTube video and click “Share,” then “Embed,” and then copy and paste the provided URL only. For example: https://www.youtube.com/embed/3FIVXBawyQw For Vimeo: follow similar steps to grab the embed URL. For example: https://player.vimeo.com/video/9004979", + label="Embed URL", + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "video_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide videos are col-12, Full-Width videos reach both ends of the screen.", + ), + ), + ] + ), + ), + ( + "iframe", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.CharBlock( + help_text="Please note that only URLs from allow-listed domains will work." + ), + ), + ( + "height", + wagtail.blocks.IntegerBlock( + help_text="Optional integer pixel value for custom iFrame height", + required=False, + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "iframe_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide iframes are col-12, Full-Width iframes reach both ends of the screen", + ), + ), + ( + "disable_scroll", + wagtail.blocks.BooleanBlock( + default=False, + help_text='Checking this will add "scrolling=no" to the iframe. Use this if your iframe is rendering an unnecessary scroll bar or whitespace below it.', + required=False, + ), + ), + ] + ), + ), + ( + "linkbutton", + 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"', + 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), + ), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ] + ), + ), + ( + "spacer", + wagtail.blocks.StructBlock( + [ + ( + "size", + wagtail.blocks.ChoiceBlock( + choices=[ + ("1", "quarter spacing"), + ("2", "half spacing"), + ("3", "single spacing"), + ("4", "one and a half spacing"), + ("5", "triple spacing"), + ] + ), + ) + ] + ), + ), + ( + "single_quote", + wagtail.blocks.StructBlock( + [ + ("quote", wagtail.blocks.RichTextBlock(features=["bold"])), + ("attribution", wagtail.blocks.CharBlock(required=False)), + ( + "attribution_info", + wagtail.blocks.RichTextBlock(features=["bold", "link", "large"], required=False), + ), + ] + ), + ), + ( + "pulse_listing", + wagtail.blocks.StructBlock( + [ + ( + "search_terms", + wagtail.blocks.CharBlock( + help_text="Test your search at mozillapulse.org/search", + label="Search", + required=False, + ), + ), + ( + "max_number_of_results", + wagtail.blocks.IntegerBlock( + default=6, + help_text="Choose 1-12. If you want visitors to see more, link to a search or tag on Pulse.", + max_value=12, + min_value=0, + required=True, + ), + ), + ( + "only_featured_entries", + wagtail.blocks.BooleanBlock( + default=False, + help_text="Featured items are selected by Pulse moderators.", + label="Display only featured entries", + required=False, + ), + ), + ( + "newest_first", + wagtail.blocks.ChoiceBlock( + choices=[ + ("True", "Show newer entries first"), + ("False", "Show older entries first"), + ], + label="Sort", + ), + ), + ( + "advanced_filter_header", + wagtail.blocks.static_block.StaticBlock( + admin_text="-------- ADVANCED FILTERS: OPTIONS TO DISPLAY FEWER, MORE TARGETED RESULTS. --------", + label=" ", + ), + ), + ( + "issues", + wagtail.blocks.ChoiceBlock( + choices=[ + ("all", "All"), + ("Decentralization", "Decentralization"), + ("Digital Inclusion", "Digital Inclusion"), + ("Online Privacy & Security", "Online Privacy & Security"), + ("Open Innovation", "Open Innovation"), + ("Web Literacy", "Web Literacy"), + ] + ), + ), + ( + "help", + wagtail.blocks.ChoiceBlock( + choices=[ + ("all", "All"), + ("Attend", "Attend"), + ("Create content", "Create content"), + ("Code", "Code"), + ("Design", "Design"), + ("Fundraise", "Fundraise"), + ("Join community", "Join community"), + ("Localize & translate", "Localize & translate"), + ("Mentor", "Mentor"), + ("Plan & organize", "Plan & organize"), + ("Promote", "Promote"), + ("Take action", "Take action"), + ("Test & feedback", "Test & feedback"), + ("Write documentation", "Write documentation"), + ], + label="Type of help needed", + ), + ), + ( + "direct_link", + wagtail.blocks.BooleanBlock( + default=False, + help_text="Checked: user goes to project link. Unchecked: user goes to pulse entry", + label="Direct link", + required=False, + ), + ), + ] + ), + ), + ( + "profile_listing", + wagtail.blocks.StructBlock( + [ + ( + "max_number_of_results", + wagtail.blocks.IntegerBlock( + default=12, + help_text="Pick up to 48 profiles.", + max_value=48, + min_value=1, + required=True, + ), + ), + ( + "advanced_filter_header", + wagtail.blocks.static_block.StaticBlock( + admin_text="-------- ADVANCED FILTERS: OPTIONS TO DISPLAY FEWER, MORE TARGETED RESULTS. --------", + label=" ", + ), + ), + ( + "profile_type", + wagtail.blocks.CharBlock(default="", help_text="Example: Fellow.", required=False), + ), + ( + "program_type", + wagtail.blocks.CharBlock( + default="", help_text="Example: Tech Policy.", required=False + ), + ), + ("year", wagtail.blocks.CharBlock(default="", required=False)), + ] + ), + ), + ( + "profile_by_id", + wagtail.blocks.StructBlock( + [ + ( + "ids", + wagtail.blocks.CharBlock( + help_text="Show profiles for pulse users with specific profile ids (mozillapulse.org/profile/[##]). For multiple profiles, specify a comma separated list (e.g. 85,105,332).", + label="Profile by ID", + ), + ) + ] + ), + ), + ( + "profile_directory", + wagtail.blocks.StructBlock( + [ + ( + "max_number_of_results", + wagtail.blocks.IntegerBlock( + default=12, + help_text="Pick up to 48 profiles.", + max_value=48, + min_value=1, + required=True, + ), + ), + ( + "advanced_filter_header", + wagtail.blocks.static_block.StaticBlock( + admin_text="-------- ADVANCED FILTERS: OPTIONS TO DISPLAY FEWER, MORE TARGETED RESULTS. --------", + label=" ", + ), + ), + ( + "profile_type", + wagtail.blocks.CharBlock(default="", help_text="Example: Fellow.", required=False), + ), + ( + "program_type", + wagtail.blocks.CharBlock( + default="", help_text="Example: Tech Policy.", required=False + ), + ), + ("year", wagtail.blocks.CharBlock(default="", required=False)), + ( + "filter_values", + wagtail.blocks.CharBlock( + default="2019,2018,2017,2016,2015,2014,2013", + help_text="Example: 2019,2018,2017,2016,2015,2014,2013", + required=True, + ), + ), + ] + ), + ), + ( + "recent_blog_entries", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock(required=False)), + ( + "tag_filter", + wagtail.blocks.CharBlock( + help_text="Test this filter at foundation.mozilla.org/blog/tags/", + label="Filter by Tag", + required=False, + ), + ), + ( + "topic_filter", + wagtail.blocks.ChoiceBlock( + choices=networkapi.wagtailpages.pagemodels.blog.blog_topic.BlogPageTopic.get_topics, + help_text="Test this filter at foundation.mozilla.org/blog/topic/", + label="Filter by Topic", + required=False, + ), + ), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ] + ), + ), + ( + "blog_set", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock()), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ( + "blog_pages", + wagtail.blocks.ListBlock( + wagtail.blocks.PageChooserBlock(page_type=["wagtailpages.BlogPage"]) + ), + ), + ] + ), + ), + ( + "airtable", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="Copied from the Airtable embed code. The word 'embed' will be in the url" + ), + ), + ( + "height", + wagtail.blocks.IntegerBlock( + default=533, + help_text="The pixel height on desktop view, usually copied from the Airtable embed code", + ), + ), + ] + ), + ), + ( + "typeform", + wagtail.blocks.StructBlock( + [ + ( + "embed_id", + wagtail.blocks.CharBlock( + help_text="The embed id of your Typeform page (e.g. if the form is on admin.typeform.com/form/e8zScc6t, the id will be: e8zScc6t)", + required=True, + ), + ), + ( + "button_type", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ( + "button_text", + wagtail.blocks.CharBlock( + help_text="This is a text prompt for users to open the typeform content", + required=True, + ), + ), + ] + ), + ), + ( + "datawrapper", + wagtail.embeds.blocks.EmbedBlock( + help_text='Enter the "visualization only" link of the Datawrapper chart. It looks something like this: https://datawrapper.dwcdn.net/KwSKp/1/', + icon="image", + template="wagtailpages/blocks/datawrapper_block.html", + ), + ), + ( + "listing", + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock(help_text="Heading for the block.", required=False), + ), + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ( + "highlighted_metadata", + wagtail.blocks.CharBlock( + help_text="Metadata to highlight on the card.", required=False + ), + ), + ( + "metadata", + wagtail.blocks.CharBlock( + help_text="Generic metadata.", required=False + ), + ), + ( + "body", + wagtail.blocks.RichTextBlock( + features=["bold"], + help_text="Body text of the card.", + required=False, + ), + ), + ( + "link_page", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to.", required=False + ), + ), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that the header should link out to.", + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + min_num=2, + ), + ), + ( + "cards_per_row", + wagtail.blocks.ChoiceBlock( + choices=[(2, "2"), (3, "3")], + help_text="Number of cards per row. Note: this is a max and fewer might be used if is less space is available.", + required=False, + ), + ), + ] + ), + ), + ( + "profiles", + wagtail.blocks.StructBlock( + [ + ( + "profiles", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "profile", + wagtail.snippets.blocks.SnippetChooserBlock( + networkapi.wagtailpages.pagemodels.profiles.Profile + ), + ) + ] + ), + min_num=1, + ), + ) + ] + ), + ), + ( + "article_teaser_block", + wagtail.blocks.StructBlock( + [ + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "article", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to.", + page_type=["wagtailpages.ArticlePage"], + required=False, + ), + ) + ] + ), + help_text="Please use a minimum of 3 cards.", + min_num=3, + ), + ) + ] + ), + ), + ( + "group_listing_block", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the group of cards.", required=False + ), + ), + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ( + "meta_data", + wagtail.blocks.CharBlock( + help_text="Optional meta data information for the card.", + required=False, + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ( + "body", + wagtail.blocks.RichTextBlock( + features=["bold", "link"], help_text="Body text of the card." + ), + ), + ( + "url", + wagtail.blocks.CharBlock( + help_text="The URL this card should link to.", required=False + ), + ), + ] + ) + ), + ), + ] + ), + ), + ( + "image_feature", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock(help_text="Image description (for screen readers)."), + ), + ("metadata", wagtail.blocks.CharBlock(required=False)), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ( + "title_link", + wagtail.blocks.PageChooserBlock( + help_text="Page that the title should link out to.", required=False + ), + ), + ("body", wagtail.blocks.CharBlock(required=False)), + ] + ), + ), + ( + "image_teaser_block", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ("text", wagtail.blocks.RichTextBlock(features=["bold"])), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ("url_label", wagtail.blocks.CharBlock(required=False)), + ("url", wagtail.blocks.CharBlock(required=False)), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ( + "link_button", + wagtail.blocks.ListBlock( + 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"', + 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 + ), + ), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ] + ), + help_text="Optional link button", + max_num=1, + min_num=0, + ), + ), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ] + ), + ), + ( + "text_only_teaser", + wagtail.blocks.StructBlock( + [ + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock(help_text="Heading for the card."), + ), + ( + "link_page", + wagtail.blocks.PageChooserBlock( + help_text="Page that the header should link out to.", + required=False, + ), + ), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that the header should link out to.", + required=False, + ), + ), + ("meta_data", wagtail.blocks.CharBlock(max_length=500)), + ( + "body", + wagtail.blocks.TextBlock( + help_text="Body text of the card.", + max_length=200, + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 3 cards.", + min_num=3, + ), + ) + ] + ), + ), + ( + "block_with_aside", + wagtail.blocks.StructBlock( + [ + ( + "content", + wagtail.blocks.StreamBlock( + [ + ( + "listing", + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock( + help_text="Heading for the block.", required=False + ), + ), + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "image", + wagtail.images.blocks.ImageChooserBlock(), + ), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", + required=False, + ), + ), + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the card." + ), + ), + ( + "highlighted_metadata", + wagtail.blocks.CharBlock( + help_text="Metadata to highlight on the card.", + required=False, + ), + ), + ( + "metadata", + wagtail.blocks.CharBlock( + help_text="Generic metadata.", + required=False, + ), + ), + ( + "body", + wagtail.blocks.RichTextBlock( + features=["bold"], + help_text="Body text of the card.", + required=False, + ), + ), + ( + "link_page", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to.", + required=False, + ), + ), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that the header should link out to.", + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + min_num=2, + ), + ), + ( + "cards_per_row", + wagtail.blocks.ChoiceBlock( + choices=[(2, "2"), (3, "3")], + help_text="Number of cards per row. Note: this is a max and fewer might be used if is less space is available.", + required=False, + ), + ), + ] + ), + ), + ( + "paragraph", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + ] + ), + ), + ], + help_text="The wider block that appears on the left on desktop", + icon="doc-full", + max_num=1, + ), + ), + ( + "aside", + wagtail.blocks.StreamBlock( + [ + ( + "aside_content", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the card.", required=False + ), + ), + ( + "body", + wagtail.blocks.TextBlock( + help_text="Body text of the card.", required=False + ), + ), + ] + ), + ), + ( + "linkbutton", + 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"', + 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 + ), + ), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ] + ), + ), + ( + "spacer", + wagtail.blocks.StructBlock( + [ + ( + "size", + wagtail.blocks.ChoiceBlock( + choices=[ + ("1", "quarter spacing"), + ("2", "half spacing"), + ("3", "single spacing"), + ("4", "one and a half spacing"), + ("5", "triple spacing"), + ] + ), + ) + ] + ), + ), + ], + help_text="Elements here will appear in the column on the right side of the page on desktop. This can be left blank if you would just like a 2/3 column on the left", + icon="doc-full", + required=False, + ), + ), + ] + ), + ), + ( + "accordion", + wagtail.blocks.StructBlock( + [ + ( + "accordion_items", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the Accordion Item" + ), + ), + ( + "content", + wagtail.blocks.StreamBlock( + [ + ( + "rich_text", + wagtail.blocks.RichTextBlock( + blank=True, + features=[ + "bold", + "italic", + "link", + "ul", + "ol", + "document-link", + ], + ), + ), + ( + "datawrapper", + wagtail.embeds.blocks.EmbedBlock( + help_text='Enter the "visualization only" link of the Datawrapper chart. It looks something like this: https://datawrapper.dwcdn.net/KwSKp/1/', + icon="image", + template="wagtailpages/blocks/datawrapper_block.html", + ), + ), + ( + "image", + wagtail.blocks.StructBlock( + [ + ( + "image", + wagtail.images.blocks.ImageChooserBlock(), + ), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", + required=True, + ), + ), + ] + ), + ), + ( + "video", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="For YouTube: go to your YouTube video and click “Share,” then “Embed,” and then copy and paste the provided URL only. For example: https://www.youtube.com/embed/3FIVXBawyQw For Vimeo: follow similar steps to grab the embed URL. For example: https://player.vimeo.com/video/9004979", + label="Embed URL", + ), + ), + ( + "caption", + wagtail.blocks.CharBlock(required=False), + ), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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, + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "video_width", + wagtail.blocks.ChoiceBlock( + choices=[ + ("normal", "Normal"), + ("wide", "Wide"), + ("full_width", "Full Width"), + ], + help_text="Wide videos are col-12, Full-Width videos reach both ends of the screen.", + ), + ), + ] + ), + ), + ] + ), + ), + ] + ) + ), + ) + ] + ), + ), + ], + use_json_field=True, + ), + ), + migrations.AlterField( + model_name="primarypage", + name="body", + field=wagtail.fields.StreamField( + [ + ( + "paragraph", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + "large", + ], + template="wagtailpages/blocks/rich_text_block.html", + ), + ), + ( + "card_grid", + wagtail.blocks.StructBlock( + [ + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ("body", wagtail.blocks.TextBlock(help_text="Body text of the card.")), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that this card should link out to. (Note: If left blank, link will not render.) ", + required=False, + ), + ), + ( + "link_label", + wagtail.blocks.CharBlock( + help_text="Optional Label for the URL link above. (Note: If left blank, link will not render.) ", + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + ), + ) + ] + ), + ), + ( + "image", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "image_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide images are col-12, Full-Width Images reach both ends of the screen (16:6 images recommended for full width)", + ), + ), + ] + ), + ), + ( + "image_text", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ( + "text", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + ] + ), + ), + ( + "url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this image should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ] + ), + ), + ( + "image_text_mini", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ("text", wagtail.blocks.RichTextBlock(features=["bold", "italic", "link"])), + ] + ), + ), + ( + "image_grid", + wagtail.blocks.StructBlock( + [ + ( + "grid_items", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for this image.", required=False + ), + ), + ( + "caption", + wagtail.blocks.CharBlock( + help_text="Please remember to properly attribute any images we use.", + required=False, + ), + ), + ( + "url", + wagtail.blocks.CharBlock( + help_text="Optional URL that this figure should link out to.", + required=False, + ), + ), + ( + "square_image", + wagtail.blocks.BooleanBlock( + default=True, + help_text="If left checked, the image will be cropped to be square.", + required=False, + ), + ), + ] + ) + ), + ) + ] + ), + ), + ( + "video", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="For YouTube: go to your YouTube video and click “Share,” then “Embed,” and then copy and paste the provided URL only. For example: https://www.youtube.com/embed/3FIVXBawyQw For Vimeo: follow similar steps to grab the embed URL. For example: https://player.vimeo.com/video/9004979", + label="Embed URL", + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "video_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide videos are col-12, Full-Width videos reach both ends of the screen.", + ), + ), + ] + ), + ), + ( + "iframe", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.CharBlock( + help_text="Please note that only URLs from allow-listed domains will work." + ), + ), + ( + "height", + wagtail.blocks.IntegerBlock( + help_text="Optional integer pixel value for custom iFrame height", + required=False, + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "iframe_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide iframes are col-12, Full-Width iframes reach both ends of the screen", + ), + ), + ( + "disable_scroll", + wagtail.blocks.BooleanBlock( + default=False, + help_text='Checking this will add "scrolling=no" to the iframe. Use this if your iframe is rendering an unnecessary scroll bar or whitespace below it.', + required=False, + ), + ), + ] + ), + ), + ( + "linkbutton", + 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"', + 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), + ), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ] + ), + ), + ( + "spacer", + wagtail.blocks.StructBlock( + [ + ( + "size", + wagtail.blocks.ChoiceBlock( + choices=[ + ("1", "quarter spacing"), + ("2", "half spacing"), + ("3", "single spacing"), + ("4", "one and a half spacing"), + ("5", "triple spacing"), + ] + ), + ) + ] + ), + ), + ( + "single_quote", + wagtail.blocks.StructBlock( + [ + ("quote", wagtail.blocks.RichTextBlock(features=["bold"])), + ("attribution", wagtail.blocks.CharBlock(required=False)), + ( + "attribution_info", + wagtail.blocks.RichTextBlock(features=["bold", "link", "large"], required=False), + ), + ] + ), + ), + ( + "pulse_listing", + wagtail.blocks.StructBlock( + [ + ( + "search_terms", + wagtail.blocks.CharBlock( + help_text="Test your search at mozillapulse.org/search", + label="Search", + required=False, + ), + ), + ( + "max_number_of_results", + wagtail.blocks.IntegerBlock( + default=6, + help_text="Choose 1-12. If you want visitors to see more, link to a search or tag on Pulse.", + max_value=12, + min_value=0, + required=True, + ), + ), + ( + "only_featured_entries", + wagtail.blocks.BooleanBlock( + default=False, + help_text="Featured items are selected by Pulse moderators.", + label="Display only featured entries", + required=False, + ), + ), + ( + "newest_first", + wagtail.blocks.ChoiceBlock( + choices=[ + ("True", "Show newer entries first"), + ("False", "Show older entries first"), + ], + label="Sort", + ), + ), + ( + "advanced_filter_header", + wagtail.blocks.static_block.StaticBlock( + admin_text="-------- ADVANCED FILTERS: OPTIONS TO DISPLAY FEWER, MORE TARGETED RESULTS. --------", + label=" ", + ), + ), + ( + "issues", + wagtail.blocks.ChoiceBlock( + choices=[ + ("all", "All"), + ("Decentralization", "Decentralization"), + ("Digital Inclusion", "Digital Inclusion"), + ("Online Privacy & Security", "Online Privacy & Security"), + ("Open Innovation", "Open Innovation"), + ("Web Literacy", "Web Literacy"), + ] + ), + ), + ( + "help", + wagtail.blocks.ChoiceBlock( + choices=[ + ("all", "All"), + ("Attend", "Attend"), + ("Create content", "Create content"), + ("Code", "Code"), + ("Design", "Design"), + ("Fundraise", "Fundraise"), + ("Join community", "Join community"), + ("Localize & translate", "Localize & translate"), + ("Mentor", "Mentor"), + ("Plan & organize", "Plan & organize"), + ("Promote", "Promote"), + ("Take action", "Take action"), + ("Test & feedback", "Test & feedback"), + ("Write documentation", "Write documentation"), + ], + label="Type of help needed", + ), + ), + ( + "direct_link", + wagtail.blocks.BooleanBlock( + default=False, + help_text="Checked: user goes to project link. Unchecked: user goes to pulse entry", + label="Direct link", + required=False, + ), + ), + ] + ), + ), + ( + "profile_listing", + wagtail.blocks.StructBlock( + [ + ( + "max_number_of_results", + wagtail.blocks.IntegerBlock( + default=12, + help_text="Pick up to 48 profiles.", + max_value=48, + min_value=1, + required=True, + ), + ), + ( + "advanced_filter_header", + wagtail.blocks.static_block.StaticBlock( + admin_text="-------- ADVANCED FILTERS: OPTIONS TO DISPLAY FEWER, MORE TARGETED RESULTS. --------", + label=" ", + ), + ), + ( + "profile_type", + wagtail.blocks.CharBlock(default="", help_text="Example: Fellow.", required=False), + ), + ( + "program_type", + wagtail.blocks.CharBlock( + default="", help_text="Example: Tech Policy.", required=False + ), + ), + ("year", wagtail.blocks.CharBlock(default="", required=False)), + ] + ), + ), + ( + "profile_by_id", + wagtail.blocks.StructBlock( + [ + ( + "ids", + wagtail.blocks.CharBlock( + help_text="Show profiles for pulse users with specific profile ids (mozillapulse.org/profile/[##]). For multiple profiles, specify a comma separated list (e.g. 85,105,332).", + label="Profile by ID", + ), + ) + ] + ), + ), + ( + "profile_directory", + wagtail.blocks.StructBlock( + [ + ( + "max_number_of_results", + wagtail.blocks.IntegerBlock( + default=12, + help_text="Pick up to 48 profiles.", + max_value=48, + min_value=1, + required=True, + ), + ), + ( + "advanced_filter_header", + wagtail.blocks.static_block.StaticBlock( + admin_text="-------- ADVANCED FILTERS: OPTIONS TO DISPLAY FEWER, MORE TARGETED RESULTS. --------", + label=" ", + ), + ), + ( + "profile_type", + wagtail.blocks.CharBlock(default="", help_text="Example: Fellow.", required=False), + ), + ( + "program_type", + wagtail.blocks.CharBlock( + default="", help_text="Example: Tech Policy.", required=False + ), + ), + ("year", wagtail.blocks.CharBlock(default="", required=False)), + ( + "filter_values", + wagtail.blocks.CharBlock( + default="2019,2018,2017,2016,2015,2014,2013", + help_text="Example: 2019,2018,2017,2016,2015,2014,2013", + required=True, + ), + ), + ] + ), + ), + ( + "recent_blog_entries", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock(required=False)), + ( + "tag_filter", + wagtail.blocks.CharBlock( + help_text="Test this filter at foundation.mozilla.org/blog/tags/", + label="Filter by Tag", + required=False, + ), + ), + ( + "topic_filter", + wagtail.blocks.ChoiceBlock( + choices=networkapi.wagtailpages.pagemodels.blog.blog_topic.BlogPageTopic.get_topics, + help_text="Test this filter at foundation.mozilla.org/blog/topic/", + label="Filter by Topic", + required=False, + ), + ), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ] + ), + ), + ( + "blog_set", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock()), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ( + "blog_pages", + wagtail.blocks.ListBlock( + wagtail.blocks.PageChooserBlock(page_type=["wagtailpages.BlogPage"]) + ), + ), + ] + ), + ), + ( + "airtable", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="Copied from the Airtable embed code. The word 'embed' will be in the url" + ), + ), + ( + "height", + wagtail.blocks.IntegerBlock( + default=533, + help_text="The pixel height on desktop view, usually copied from the Airtable embed code", + ), + ), + ] + ), + ), + ( + "typeform", + wagtail.blocks.StructBlock( + [ + ( + "embed_id", + wagtail.blocks.CharBlock( + help_text="The embed id of your Typeform page (e.g. if the form is on admin.typeform.com/form/e8zScc6t, the id will be: e8zScc6t)", + required=True, + ), + ), + ( + "button_type", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ( + "button_text", + wagtail.blocks.CharBlock( + help_text="This is a text prompt for users to open the typeform content", + required=True, + ), + ), + ] + ), + ), + ( + "datawrapper", + wagtail.embeds.blocks.EmbedBlock( + help_text='Enter the "visualization only" link of the Datawrapper chart. It looks something like this: https://datawrapper.dwcdn.net/KwSKp/1/', + icon="image", + template="wagtailpages/blocks/datawrapper_block.html", + ), + ), + ( + "listing", + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock(help_text="Heading for the block.", required=False), + ), + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ( + "highlighted_metadata", + wagtail.blocks.CharBlock( + help_text="Metadata to highlight on the card.", required=False + ), + ), + ( + "metadata", + wagtail.blocks.CharBlock( + help_text="Generic metadata.", required=False + ), + ), + ( + "body", + wagtail.blocks.RichTextBlock( + features=["bold"], + help_text="Body text of the card.", + required=False, + ), + ), + ( + "link_page", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to.", required=False + ), + ), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that the header should link out to.", + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + min_num=2, + ), + ), + ( + "cards_per_row", + wagtail.blocks.ChoiceBlock( + choices=[(2, "2"), (3, "3")], + help_text="Number of cards per row. Note: this is a max and fewer might be used if is less space is available.", + required=False, + ), + ), + ] + ), + ), + ( + "profiles", + wagtail.blocks.StructBlock( + [ + ( + "profiles", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "profile", + wagtail.snippets.blocks.SnippetChooserBlock( + networkapi.wagtailpages.pagemodels.profiles.Profile + ), + ) + ] + ), + min_num=1, + ), + ) + ] + ), + ), + ( + "article_teaser_block", + wagtail.blocks.StructBlock( + [ + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "article", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to.", + page_type=["wagtailpages.ArticlePage"], + required=False, + ), + ) + ] + ), + help_text="Please use a minimum of 3 cards.", + min_num=3, + ), + ) + ] + ), + ), + ( + "group_listing_block", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the group of cards.", required=False + ), + ), + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ( + "meta_data", + wagtail.blocks.CharBlock( + help_text="Optional meta data information for the card.", + required=False, + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ( + "body", + wagtail.blocks.RichTextBlock( + features=["bold", "link"], help_text="Body text of the card." + ), + ), + ( + "url", + wagtail.blocks.CharBlock( + help_text="The URL this card should link to.", required=False + ), + ), + ] + ) + ), + ), + ] + ), + ), + ( + "image_feature", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock(help_text="Image description (for screen readers)."), + ), + ("metadata", wagtail.blocks.CharBlock(required=False)), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ( + "title_link", + wagtail.blocks.PageChooserBlock( + help_text="Page that the title should link out to.", required=False + ), + ), + ("body", wagtail.blocks.CharBlock(required=False)), + ] + ), + ), + ( + "image_teaser_block", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ("text", wagtail.blocks.RichTextBlock(features=["bold"])), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ("url_label", wagtail.blocks.CharBlock(required=False)), + ("url", wagtail.blocks.CharBlock(required=False)), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ( + "link_button", + wagtail.blocks.ListBlock( + 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"', + 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 + ), + ), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ] + ), + help_text="Optional link button", + max_num=1, + min_num=0, + ), + ), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ] + ), + ), + ( + "text_only_teaser", + wagtail.blocks.StructBlock( + [ + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock(help_text="Heading for the card."), + ), + ( + "link_page", + wagtail.blocks.PageChooserBlock( + help_text="Page that the header should link out to.", + required=False, + ), + ), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that the header should link out to.", + required=False, + ), + ), + ("meta_data", wagtail.blocks.CharBlock(max_length=500)), + ( + "body", + wagtail.blocks.TextBlock( + help_text="Body text of the card.", + max_length=200, + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 3 cards.", + min_num=3, + ), + ) + ] + ), + ), + ( + "block_with_aside", + wagtail.blocks.StructBlock( + [ + ( + "content", + wagtail.blocks.StreamBlock( + [ + ( + "listing", + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock( + help_text="Heading for the block.", required=False + ), + ), + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "image", + wagtail.images.blocks.ImageChooserBlock(), + ), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", + required=False, + ), + ), + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the card." + ), + ), + ( + "highlighted_metadata", + wagtail.blocks.CharBlock( + help_text="Metadata to highlight on the card.", + required=False, + ), + ), + ( + "metadata", + wagtail.blocks.CharBlock( + help_text="Generic metadata.", + required=False, + ), + ), + ( + "body", + wagtail.blocks.RichTextBlock( + features=["bold"], + help_text="Body text of the card.", + required=False, + ), + ), + ( + "link_page", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to.", + required=False, + ), + ), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that the header should link out to.", + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + min_num=2, + ), + ), + ( + "cards_per_row", + wagtail.blocks.ChoiceBlock( + choices=[(2, "2"), (3, "3")], + help_text="Number of cards per row. Note: this is a max and fewer might be used if is less space is available.", + required=False, + ), + ), + ] + ), + ), + ( + "paragraph", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + ] + ), + ), + ], + help_text="The wider block that appears on the left on desktop", + icon="doc-full", + max_num=1, + ), + ), + ( + "aside", + wagtail.blocks.StreamBlock( + [ + ( + "aside_content", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the card.", required=False + ), + ), + ( + "body", + wagtail.blocks.TextBlock( + help_text="Body text of the card.", required=False + ), + ), + ] + ), + ), + ( + "linkbutton", + 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"', + 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 + ), + ), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ] + ), + ), + ( + "spacer", + wagtail.blocks.StructBlock( + [ + ( + "size", + wagtail.blocks.ChoiceBlock( + choices=[ + ("1", "quarter spacing"), + ("2", "half spacing"), + ("3", "single spacing"), + ("4", "one and a half spacing"), + ("5", "triple spacing"), + ] + ), + ) + ] + ), + ), + ], + help_text="Elements here will appear in the column on the right side of the page on desktop. This can be left blank if you would just like a 2/3 column on the left", + icon="doc-full", + required=False, + ), + ), + ] + ), + ), + ( + "accordion", + wagtail.blocks.StructBlock( + [ + ( + "accordion_items", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the Accordion Item" + ), + ), + ( + "content", + wagtail.blocks.StreamBlock( + [ + ( + "rich_text", + wagtail.blocks.RichTextBlock( + blank=True, + features=[ + "bold", + "italic", + "link", + "ul", + "ol", + "document-link", + ], + ), + ), + ( + "datawrapper", + wagtail.embeds.blocks.EmbedBlock( + help_text='Enter the "visualization only" link of the Datawrapper chart. It looks something like this: https://datawrapper.dwcdn.net/KwSKp/1/', + icon="image", + template="wagtailpages/blocks/datawrapper_block.html", + ), + ), + ( + "image", + wagtail.blocks.StructBlock( + [ + ( + "image", + wagtail.images.blocks.ImageChooserBlock(), + ), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", + required=True, + ), + ), + ] + ), + ), + ( + "video", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="For YouTube: go to your YouTube video and click “Share,” then “Embed,” and then copy and paste the provided URL only. For example: https://www.youtube.com/embed/3FIVXBawyQw For Vimeo: follow similar steps to grab the embed URL. For example: https://player.vimeo.com/video/9004979", + label="Embed URL", + ), + ), + ( + "caption", + wagtail.blocks.CharBlock(required=False), + ), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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, + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "video_width", + wagtail.blocks.ChoiceBlock( + choices=[ + ("normal", "Normal"), + ("wide", "Wide"), + ("full_width", "Full Width"), + ], + help_text="Wide videos are col-12, Full-Width videos reach both ends of the screen.", + ), + ), + ] + ), + ), + ] + ), + ), + ] + ) + ), + ) + ] + ), + ), + ], + use_json_field=True, + ), + ), + MigrateStreamData( + app_name="wagtailpages", + model_name="modularpage", + field_name="body", + operations_and_block_paths=[ + ( + AlterStreamChildBlockDataOperation( + block="image_teaser_block", operation=migrate_image_teaser_block + ), + "", + ), + ], + ), + MigrateStreamData( + app_name="wagtailpages", + model_name="primarypage", + field_name="body", + operations_and_block_paths=[ + ( + AlterStreamChildBlockDataOperation( + block="image_teaser_block", operation=migrate_image_teaser_block + ), + "", + ), + ], + ), + migrations.AlterField( + model_name="modularpage", + name="body", + field=wagtail.fields.StreamField( + [ + ( + "paragraph", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + "large", + ], + template="wagtailpages/blocks/rich_text_block.html", + ), + ), + ( + "card_grid", + wagtail.blocks.StructBlock( + [ + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ("body", wagtail.blocks.TextBlock(help_text="Body text of the card.")), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that this card should link out to. (Note: If left blank, link will not render.) ", + required=False, + ), + ), + ( + "link_label", + wagtail.blocks.CharBlock( + help_text="Optional Label for the URL link above. (Note: If left blank, link will not render.) ", + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + ), + ) + ] + ), + ), + ( + "image", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "image_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide images are col-12, Full-Width Images reach both ends of the screen (16:6 images recommended for full width)", + ), + ), + ] + ), + ), + ( + "image_text", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ( + "text", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + ] + ), + ), + ( + "url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this image should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ] + ), + ), + ( + "image_text_mini", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ("text", wagtail.blocks.RichTextBlock(features=["bold", "italic", "link"])), + ] + ), + ), + ( + "image_grid", + wagtail.blocks.StructBlock( + [ + ( + "grid_items", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for this image.", required=False + ), + ), + ( + "caption", + wagtail.blocks.CharBlock( + help_text="Please remember to properly attribute any images we use.", + required=False, + ), + ), + ( + "url", + wagtail.blocks.CharBlock( + help_text="Optional URL that this figure should link out to.", + required=False, + ), + ), + ( + "square_image", + wagtail.blocks.BooleanBlock( + default=True, + help_text="If left checked, the image will be cropped to be square.", + required=False, + ), + ), + ] + ) + ), + ) + ] + ), + ), + ( + "video", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="For YouTube: go to your YouTube video and click “Share,” then “Embed,” and then copy and paste the provided URL only. For example: https://www.youtube.com/embed/3FIVXBawyQw For Vimeo: follow similar steps to grab the embed URL. For example: https://player.vimeo.com/video/9004979", + label="Embed URL", + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "video_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide videos are col-12, Full-Width videos reach both ends of the screen.", + ), + ), + ] + ), + ), + ( + "iframe", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.CharBlock( + help_text="Please note that only URLs from allow-listed domains will work." + ), + ), + ( + "height", + wagtail.blocks.IntegerBlock( + help_text="Optional integer pixel value for custom iFrame height", + required=False, + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "iframe_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide iframes are col-12, Full-Width iframes reach both ends of the screen", + ), + ), + ( + "disable_scroll", + wagtail.blocks.BooleanBlock( + default=False, + help_text='Checking this will add "scrolling=no" to the iframe. Use this if your iframe is rendering an unnecessary scroll bar or whitespace below it.', + required=False, + ), + ), + ] + ), + ), + ( + "linkbutton", + 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"', + 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), + ), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ] + ), + ), + ( + "spacer", + wagtail.blocks.StructBlock( + [ + ( + "size", + wagtail.blocks.ChoiceBlock( + choices=[ + ("1", "quarter spacing"), + ("2", "half spacing"), + ("3", "single spacing"), + ("4", "one and a half spacing"), + ("5", "triple spacing"), + ] + ), + ) + ] + ), + ), + ( + "single_quote", + wagtail.blocks.StructBlock( + [ + ("quote", wagtail.blocks.RichTextBlock(features=["bold"])), + ("attribution", wagtail.blocks.CharBlock(required=False)), + ( + "attribution_info", + wagtail.blocks.RichTextBlock(features=["bold", "link", "large"], required=False), + ), + ] + ), + ), + ( + "pulse_listing", + wagtail.blocks.StructBlock( + [ + ( + "search_terms", + wagtail.blocks.CharBlock( + help_text="Test your search at mozillapulse.org/search", + label="Search", + required=False, + ), + ), + ( + "max_number_of_results", + wagtail.blocks.IntegerBlock( + default=6, + help_text="Choose 1-12. If you want visitors to see more, link to a search or tag on Pulse.", + max_value=12, + min_value=0, + required=True, + ), + ), + ( + "only_featured_entries", + wagtail.blocks.BooleanBlock( + default=False, + help_text="Featured items are selected by Pulse moderators.", + label="Display only featured entries", + required=False, + ), + ), + ( + "newest_first", + wagtail.blocks.ChoiceBlock( + choices=[ + ("True", "Show newer entries first"), + ("False", "Show older entries first"), + ], + label="Sort", + ), + ), + ( + "advanced_filter_header", + wagtail.blocks.static_block.StaticBlock( + admin_text="-------- ADVANCED FILTERS: OPTIONS TO DISPLAY FEWER, MORE TARGETED RESULTS. --------", + label=" ", + ), + ), + ( + "issues", + wagtail.blocks.ChoiceBlock( + choices=[ + ("all", "All"), + ("Decentralization", "Decentralization"), + ("Digital Inclusion", "Digital Inclusion"), + ("Online Privacy & Security", "Online Privacy & Security"), + ("Open Innovation", "Open Innovation"), + ("Web Literacy", "Web Literacy"), + ] + ), + ), + ( + "help", + wagtail.blocks.ChoiceBlock( + choices=[ + ("all", "All"), + ("Attend", "Attend"), + ("Create content", "Create content"), + ("Code", "Code"), + ("Design", "Design"), + ("Fundraise", "Fundraise"), + ("Join community", "Join community"), + ("Localize & translate", "Localize & translate"), + ("Mentor", "Mentor"), + ("Plan & organize", "Plan & organize"), + ("Promote", "Promote"), + ("Take action", "Take action"), + ("Test & feedback", "Test & feedback"), + ("Write documentation", "Write documentation"), + ], + label="Type of help needed", + ), + ), + ( + "direct_link", + wagtail.blocks.BooleanBlock( + default=False, + help_text="Checked: user goes to project link. Unchecked: user goes to pulse entry", + label="Direct link", + required=False, + ), + ), + ] + ), + ), + ( + "profile_listing", + wagtail.blocks.StructBlock( + [ + ( + "max_number_of_results", + wagtail.blocks.IntegerBlock( + default=12, + help_text="Pick up to 48 profiles.", + max_value=48, + min_value=1, + required=True, + ), + ), + ( + "advanced_filter_header", + wagtail.blocks.static_block.StaticBlock( + admin_text="-------- ADVANCED FILTERS: OPTIONS TO DISPLAY FEWER, MORE TARGETED RESULTS. --------", + label=" ", + ), + ), + ( + "profile_type", + wagtail.blocks.CharBlock(default="", help_text="Example: Fellow.", required=False), + ), + ( + "program_type", + wagtail.blocks.CharBlock( + default="", help_text="Example: Tech Policy.", required=False + ), + ), + ("year", wagtail.blocks.CharBlock(default="", required=False)), + ] + ), + ), + ( + "profile_by_id", + wagtail.blocks.StructBlock( + [ + ( + "ids", + wagtail.blocks.CharBlock( + help_text="Show profiles for pulse users with specific profile ids (mozillapulse.org/profile/[##]). For multiple profiles, specify a comma separated list (e.g. 85,105,332).", + label="Profile by ID", + ), + ) + ] + ), + ), + ( + "profile_directory", + wagtail.blocks.StructBlock( + [ + ( + "max_number_of_results", + wagtail.blocks.IntegerBlock( + default=12, + help_text="Pick up to 48 profiles.", + max_value=48, + min_value=1, + required=True, + ), + ), + ( + "advanced_filter_header", + wagtail.blocks.static_block.StaticBlock( + admin_text="-------- ADVANCED FILTERS: OPTIONS TO DISPLAY FEWER, MORE TARGETED RESULTS. --------", + label=" ", + ), + ), + ( + "profile_type", + wagtail.blocks.CharBlock(default="", help_text="Example: Fellow.", required=False), + ), + ( + "program_type", + wagtail.blocks.CharBlock( + default="", help_text="Example: Tech Policy.", required=False + ), + ), + ("year", wagtail.blocks.CharBlock(default="", required=False)), + ( + "filter_values", + wagtail.blocks.CharBlock( + default="2019,2018,2017,2016,2015,2014,2013", + help_text="Example: 2019,2018,2017,2016,2015,2014,2013", + required=True, + ), + ), + ] + ), + ), + ( + "recent_blog_entries", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock(required=False)), + ( + "tag_filter", + wagtail.blocks.CharBlock( + help_text="Test this filter at foundation.mozilla.org/blog/tags/", + label="Filter by Tag", + required=False, + ), + ), + ( + "topic_filter", + wagtail.blocks.ChoiceBlock( + choices=networkapi.wagtailpages.pagemodels.blog.blog_topic.BlogPageTopic.get_topics, + help_text="Test this filter at foundation.mozilla.org/blog/topic/", + label="Filter by Topic", + required=False, + ), + ), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ] + ), + ), + ( + "blog_set", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock()), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ( + "blog_pages", + wagtail.blocks.ListBlock( + wagtail.blocks.PageChooserBlock(page_type=["wagtailpages.BlogPage"]) + ), + ), + ] + ), + ), + ( + "airtable", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="Copied from the Airtable embed code. The word 'embed' will be in the url" + ), + ), + ( + "height", + wagtail.blocks.IntegerBlock( + default=533, + help_text="The pixel height on desktop view, usually copied from the Airtable embed code", + ), + ), + ] + ), + ), + ( + "typeform", + wagtail.blocks.StructBlock( + [ + ( + "embed_id", + wagtail.blocks.CharBlock( + help_text="The embed id of your Typeform page (e.g. if the form is on admin.typeform.com/form/e8zScc6t, the id will be: e8zScc6t)", + required=True, + ), + ), + ( + "button_type", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ( + "button_text", + wagtail.blocks.CharBlock( + help_text="This is a text prompt for users to open the typeform content", + required=True, + ), + ), + ] + ), + ), + ( + "datawrapper", + wagtail.embeds.blocks.EmbedBlock( + help_text='Enter the "visualization only" link of the Datawrapper chart. It looks something like this: https://datawrapper.dwcdn.net/KwSKp/1/', + icon="image", + template="wagtailpages/blocks/datawrapper_block.html", + ), + ), + ( + "listing", + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock(help_text="Heading for the block.", required=False), + ), + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ( + "highlighted_metadata", + wagtail.blocks.CharBlock( + help_text="Metadata to highlight on the card.", required=False + ), + ), + ( + "metadata", + wagtail.blocks.CharBlock( + help_text="Generic metadata.", required=False + ), + ), + ( + "body", + wagtail.blocks.RichTextBlock( + features=["bold"], + help_text="Body text of the card.", + required=False, + ), + ), + ( + "link_page", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to.", required=False + ), + ), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that the header should link out to.", + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + min_num=2, + ), + ), + ( + "cards_per_row", + wagtail.blocks.ChoiceBlock( + choices=[(2, "2"), (3, "3")], + help_text="Number of cards per row. Note: this is a max and fewer might be used if is less space is available.", + required=False, + ), + ), + ] + ), + ), + ( + "profiles", + wagtail.blocks.StructBlock( + [ + ( + "profiles", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "profile", + wagtail.snippets.blocks.SnippetChooserBlock( + networkapi.wagtailpages.pagemodels.profiles.Profile + ), + ) + ] + ), + min_num=1, + ), + ) + ] + ), + ), + ( + "article_teaser_block", + wagtail.blocks.StructBlock( + [ + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "article", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to.", + page_type=["wagtailpages.ArticlePage"], + required=False, + ), + ) + ] + ), + help_text="Please use a minimum of 3 cards.", + min_num=3, + ), + ) + ] + ), + ), + ( + "group_listing_block", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the group of cards.", required=False + ), + ), + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ( + "meta_data", + wagtail.blocks.CharBlock( + help_text="Optional meta data information for the card.", + required=False, + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ( + "body", + wagtail.blocks.RichTextBlock( + features=["bold", "link"], help_text="Body text of the card." + ), + ), + ( + "url", + wagtail.blocks.CharBlock( + help_text="The URL this card should link to.", required=False + ), + ), + ] + ) + ), + ), + ] + ), + ), + ( + "image_feature", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock(help_text="Image description (for screen readers)."), + ), + ("metadata", wagtail.blocks.CharBlock(required=False)), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ( + "title_link", + wagtail.blocks.PageChooserBlock( + help_text="Page that the title should link out to.", required=False + ), + ), + ("body", wagtail.blocks.CharBlock(required=False)), + ] + ), + ), + ( + "image_teaser_block", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ("text", wagtail.blocks.RichTextBlock(features=["bold"])), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ( + "link_button", + wagtail.blocks.ListBlock( + 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"', + 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 + ), + ), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ] + ), + help_text="Optional link button", + max_num=1, + min_num=0, + ), + ), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ] + ), + ), + ( + "text_only_teaser", + wagtail.blocks.StructBlock( + [ + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock(help_text="Heading for the card."), + ), + ( + "link_page", + wagtail.blocks.PageChooserBlock( + help_text="Page that the header should link out to.", + required=False, + ), + ), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that the header should link out to.", + required=False, + ), + ), + ("meta_data", wagtail.blocks.CharBlock(max_length=500)), + ( + "body", + wagtail.blocks.TextBlock( + help_text="Body text of the card.", + max_length=200, + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 3 cards.", + min_num=3, + ), + ) + ] + ), + ), + ( + "block_with_aside", + wagtail.blocks.StructBlock( + [ + ( + "content", + wagtail.blocks.StreamBlock( + [ + ( + "listing", + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock( + help_text="Heading for the block.", required=False + ), + ), + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "image", + wagtail.images.blocks.ImageChooserBlock(), + ), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", + required=False, + ), + ), + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the card." + ), + ), + ( + "highlighted_metadata", + wagtail.blocks.CharBlock( + help_text="Metadata to highlight on the card.", + required=False, + ), + ), + ( + "metadata", + wagtail.blocks.CharBlock( + help_text="Generic metadata.", + required=False, + ), + ), + ( + "body", + wagtail.blocks.RichTextBlock( + features=["bold"], + help_text="Body text of the card.", + required=False, + ), + ), + ( + "link_page", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to.", + required=False, + ), + ), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that the header should link out to.", + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + min_num=2, + ), + ), + ( + "cards_per_row", + wagtail.blocks.ChoiceBlock( + choices=[(2, "2"), (3, "3")], + help_text="Number of cards per row. Note: this is a max and fewer might be used if is less space is available.", + required=False, + ), + ), + ] + ), + ), + ( + "paragraph", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + ] + ), + ), + ], + help_text="The wider block that appears on the left on desktop", + icon="doc-full", + max_num=1, + ), + ), + ( + "aside", + wagtail.blocks.StreamBlock( + [ + ( + "aside_content", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the card.", required=False + ), + ), + ( + "body", + wagtail.blocks.TextBlock( + help_text="Body text of the card.", required=False + ), + ), + ] + ), + ), + ( + "linkbutton", + 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"', + 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 + ), + ), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ] + ), + ), + ( + "spacer", + wagtail.blocks.StructBlock( + [ + ( + "size", + wagtail.blocks.ChoiceBlock( + choices=[ + ("1", "quarter spacing"), + ("2", "half spacing"), + ("3", "single spacing"), + ("4", "one and a half spacing"), + ("5", "triple spacing"), + ] + ), + ) + ] + ), + ), + ], + help_text="Elements here will appear in the column on the right side of the page on desktop. This can be left blank if you would just like a 2/3 column on the left", + icon="doc-full", + required=False, + ), + ), + ] + ), + ), + ( + "accordion", + wagtail.blocks.StructBlock( + [ + ( + "accordion_items", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the Accordion Item" + ), + ), + ( + "content", + wagtail.blocks.StreamBlock( + [ + ( + "rich_text", + wagtail.blocks.RichTextBlock( + blank=True, + features=[ + "bold", + "italic", + "link", + "ul", + "ol", + "document-link", + ], + ), + ), + ( + "datawrapper", + wagtail.embeds.blocks.EmbedBlock( + help_text='Enter the "visualization only" link of the Datawrapper chart. It looks something like this: https://datawrapper.dwcdn.net/KwSKp/1/', + icon="image", + template="wagtailpages/blocks/datawrapper_block.html", + ), + ), + ( + "image", + wagtail.blocks.StructBlock( + [ + ( + "image", + wagtail.images.blocks.ImageChooserBlock(), + ), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", + required=True, + ), + ), + ] + ), + ), + ( + "video", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="For YouTube: go to your YouTube video and click “Share,” then “Embed,” and then copy and paste the provided URL only. For example: https://www.youtube.com/embed/3FIVXBawyQw For Vimeo: follow similar steps to grab the embed URL. For example: https://player.vimeo.com/video/9004979", + label="Embed URL", + ), + ), + ( + "caption", + wagtail.blocks.CharBlock(required=False), + ), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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, + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "video_width", + wagtail.blocks.ChoiceBlock( + choices=[ + ("normal", "Normal"), + ("wide", "Wide"), + ("full_width", "Full Width"), + ], + help_text="Wide videos are col-12, Full-Width videos reach both ends of the screen.", + ), + ), + ] + ), + ), + ] + ), + ), + ] + ) + ), + ) + ] + ), + ), + ], + use_json_field=True, + ), + ), + migrations.AlterField( + model_name="primarypage", + name="body", + field=wagtail.fields.StreamField( + [ + ( + "paragraph", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + "large", + ], + template="wagtailpages/blocks/rich_text_block.html", + ), + ), + ( + "card_grid", + wagtail.blocks.StructBlock( + [ + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ("body", wagtail.blocks.TextBlock(help_text="Body text of the card.")), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that this card should link out to. (Note: If left blank, link will not render.) ", + required=False, + ), + ), + ( + "link_label", + wagtail.blocks.CharBlock( + help_text="Optional Label for the URL link above. (Note: If left blank, link will not render.) ", + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + ), + ) + ] + ), + ), + ( + "image", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "image_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide images are col-12, Full-Width Images reach both ends of the screen (16:6 images recommended for full width)", + ), + ), + ] + ), + ), + ( + "image_text", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ( + "text", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + ] + ), + ), + ( + "url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this image should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ] + ), + ), + ( + "image_text_mini", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ("text", wagtail.blocks.RichTextBlock(features=["bold", "italic", "link"])), + ] + ), + ), + ( + "image_grid", + wagtail.blocks.StructBlock( + [ + ( + "grid_items", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for this image.", required=False + ), + ), + ( + "caption", + wagtail.blocks.CharBlock( + help_text="Please remember to properly attribute any images we use.", + required=False, + ), + ), + ( + "url", + wagtail.blocks.CharBlock( + help_text="Optional URL that this figure should link out to.", + required=False, + ), + ), + ( + "square_image", + wagtail.blocks.BooleanBlock( + default=True, + help_text="If left checked, the image will be cropped to be square.", + required=False, + ), + ), + ] + ) + ), + ) + ] + ), + ), + ( + "video", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="For YouTube: go to your YouTube video and click “Share,” then “Embed,” and then copy and paste the provided URL only. For example: https://www.youtube.com/embed/3FIVXBawyQw For Vimeo: follow similar steps to grab the embed URL. For example: https://player.vimeo.com/video/9004979", + label="Embed URL", + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "video_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide videos are col-12, Full-Width videos reach both ends of the screen.", + ), + ), + ] + ), + ), + ( + "iframe", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.CharBlock( + help_text="Please note that only URLs from allow-listed domains will work." + ), + ), + ( + "height", + wagtail.blocks.IntegerBlock( + help_text="Optional integer pixel value for custom iFrame height", + required=False, + ), + ), + ("caption", wagtail.blocks.CharBlock(required=False)), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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 + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "iframe_width", + wagtail.blocks.ChoiceBlock( + choices=[("normal", "Normal"), ("wide", "Wide"), ("full_width", "Full Width")], + help_text="Wide iframes are col-12, Full-Width iframes reach both ends of the screen", + ), + ), + ( + "disable_scroll", + wagtail.blocks.BooleanBlock( + default=False, + help_text='Checking this will add "scrolling=no" to the iframe. Use this if your iframe is rendering an unnecessary scroll bar or whitespace below it.', + required=False, + ), + ), + ] + ), + ), + ( + "linkbutton", + 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"', + 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), + ), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ] + ), + ), + ( + "spacer", + wagtail.blocks.StructBlock( + [ + ( + "size", + wagtail.blocks.ChoiceBlock( + choices=[ + ("1", "quarter spacing"), + ("2", "half spacing"), + ("3", "single spacing"), + ("4", "one and a half spacing"), + ("5", "triple spacing"), + ] + ), + ) + ] + ), + ), + ( + "single_quote", + wagtail.blocks.StructBlock( + [ + ("quote", wagtail.blocks.RichTextBlock(features=["bold"])), + ("attribution", wagtail.blocks.CharBlock(required=False)), + ( + "attribution_info", + wagtail.blocks.RichTextBlock(features=["bold", "link", "large"], required=False), + ), + ] + ), + ), + ( + "pulse_listing", + wagtail.blocks.StructBlock( + [ + ( + "search_terms", + wagtail.blocks.CharBlock( + help_text="Test your search at mozillapulse.org/search", + label="Search", + required=False, + ), + ), + ( + "max_number_of_results", + wagtail.blocks.IntegerBlock( + default=6, + help_text="Choose 1-12. If you want visitors to see more, link to a search or tag on Pulse.", + max_value=12, + min_value=0, + required=True, + ), + ), + ( + "only_featured_entries", + wagtail.blocks.BooleanBlock( + default=False, + help_text="Featured items are selected by Pulse moderators.", + label="Display only featured entries", + required=False, + ), + ), + ( + "newest_first", + wagtail.blocks.ChoiceBlock( + choices=[ + ("True", "Show newer entries first"), + ("False", "Show older entries first"), + ], + label="Sort", + ), + ), + ( + "advanced_filter_header", + wagtail.blocks.static_block.StaticBlock( + admin_text="-------- ADVANCED FILTERS: OPTIONS TO DISPLAY FEWER, MORE TARGETED RESULTS. --------", + label=" ", + ), + ), + ( + "issues", + wagtail.blocks.ChoiceBlock( + choices=[ + ("all", "All"), + ("Decentralization", "Decentralization"), + ("Digital Inclusion", "Digital Inclusion"), + ("Online Privacy & Security", "Online Privacy & Security"), + ("Open Innovation", "Open Innovation"), + ("Web Literacy", "Web Literacy"), + ] + ), + ), + ( + "help", + wagtail.blocks.ChoiceBlock( + choices=[ + ("all", "All"), + ("Attend", "Attend"), + ("Create content", "Create content"), + ("Code", "Code"), + ("Design", "Design"), + ("Fundraise", "Fundraise"), + ("Join community", "Join community"), + ("Localize & translate", "Localize & translate"), + ("Mentor", "Mentor"), + ("Plan & organize", "Plan & organize"), + ("Promote", "Promote"), + ("Take action", "Take action"), + ("Test & feedback", "Test & feedback"), + ("Write documentation", "Write documentation"), + ], + label="Type of help needed", + ), + ), + ( + "direct_link", + wagtail.blocks.BooleanBlock( + default=False, + help_text="Checked: user goes to project link. Unchecked: user goes to pulse entry", + label="Direct link", + required=False, + ), + ), + ] + ), + ), + ( + "profile_listing", + wagtail.blocks.StructBlock( + [ + ( + "max_number_of_results", + wagtail.blocks.IntegerBlock( + default=12, + help_text="Pick up to 48 profiles.", + max_value=48, + min_value=1, + required=True, + ), + ), + ( + "advanced_filter_header", + wagtail.blocks.static_block.StaticBlock( + admin_text="-------- ADVANCED FILTERS: OPTIONS TO DISPLAY FEWER, MORE TARGETED RESULTS. --------", + label=" ", + ), + ), + ( + "profile_type", + wagtail.blocks.CharBlock(default="", help_text="Example: Fellow.", required=False), + ), + ( + "program_type", + wagtail.blocks.CharBlock( + default="", help_text="Example: Tech Policy.", required=False + ), + ), + ("year", wagtail.blocks.CharBlock(default="", required=False)), + ] + ), + ), + ( + "profile_by_id", + wagtail.blocks.StructBlock( + [ + ( + "ids", + wagtail.blocks.CharBlock( + help_text="Show profiles for pulse users with specific profile ids (mozillapulse.org/profile/[##]). For multiple profiles, specify a comma separated list (e.g. 85,105,332).", + label="Profile by ID", + ), + ) + ] + ), + ), + ( + "profile_directory", + wagtail.blocks.StructBlock( + [ + ( + "max_number_of_results", + wagtail.blocks.IntegerBlock( + default=12, + help_text="Pick up to 48 profiles.", + max_value=48, + min_value=1, + required=True, + ), + ), + ( + "advanced_filter_header", + wagtail.blocks.static_block.StaticBlock( + admin_text="-------- ADVANCED FILTERS: OPTIONS TO DISPLAY FEWER, MORE TARGETED RESULTS. --------", + label=" ", + ), + ), + ( + "profile_type", + wagtail.blocks.CharBlock(default="", help_text="Example: Fellow.", required=False), + ), + ( + "program_type", + wagtail.blocks.CharBlock( + default="", help_text="Example: Tech Policy.", required=False + ), + ), + ("year", wagtail.blocks.CharBlock(default="", required=False)), + ( + "filter_values", + wagtail.blocks.CharBlock( + default="2019,2018,2017,2016,2015,2014,2013", + help_text="Example: 2019,2018,2017,2016,2015,2014,2013", + required=True, + ), + ), + ] + ), + ), + ( + "recent_blog_entries", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock(required=False)), + ( + "tag_filter", + wagtail.blocks.CharBlock( + help_text="Test this filter at foundation.mozilla.org/blog/tags/", + label="Filter by Tag", + required=False, + ), + ), + ( + "topic_filter", + wagtail.blocks.ChoiceBlock( + choices=networkapi.wagtailpages.pagemodels.blog.blog_topic.BlogPageTopic.get_topics, + help_text="Test this filter at foundation.mozilla.org/blog/topic/", + label="Filter by Topic", + required=False, + ), + ), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ] + ), + ), + ( + "blog_set", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock()), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ( + "blog_pages", + wagtail.blocks.ListBlock( + wagtail.blocks.PageChooserBlock(page_type=["wagtailpages.BlogPage"]) + ), + ), + ] + ), + ), + ( + "airtable", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="Copied from the Airtable embed code. The word 'embed' will be in the url" + ), + ), + ( + "height", + wagtail.blocks.IntegerBlock( + default=533, + help_text="The pixel height on desktop view, usually copied from the Airtable embed code", + ), + ), + ] + ), + ), + ( + "typeform", + wagtail.blocks.StructBlock( + [ + ( + "embed_id", + wagtail.blocks.CharBlock( + help_text="The embed id of your Typeform page (e.g. if the form is on admin.typeform.com/form/e8zScc6t, the id will be: e8zScc6t)", + required=True, + ), + ), + ( + "button_type", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ( + "button_text", + wagtail.blocks.CharBlock( + help_text="This is a text prompt for users to open the typeform content", + required=True, + ), + ), + ] + ), + ), + ( + "datawrapper", + wagtail.embeds.blocks.EmbedBlock( + help_text='Enter the "visualization only" link of the Datawrapper chart. It looks something like this: https://datawrapper.dwcdn.net/KwSKp/1/', + icon="image", + template="wagtailpages/blocks/datawrapper_block.html", + ), + ), + ( + "listing", + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock(help_text="Heading for the block.", required=False), + ), + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ( + "highlighted_metadata", + wagtail.blocks.CharBlock( + help_text="Metadata to highlight on the card.", required=False + ), + ), + ( + "metadata", + wagtail.blocks.CharBlock( + help_text="Generic metadata.", required=False + ), + ), + ( + "body", + wagtail.blocks.RichTextBlock( + features=["bold"], + help_text="Body text of the card.", + required=False, + ), + ), + ( + "link_page", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to.", required=False + ), + ), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that the header should link out to.", + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + min_num=2, + ), + ), + ( + "cards_per_row", + wagtail.blocks.ChoiceBlock( + choices=[(2, "2"), (3, "3")], + help_text="Number of cards per row. Note: this is a max and fewer might be used if is less space is available.", + required=False, + ), + ), + ] + ), + ), + ( + "profiles", + wagtail.blocks.StructBlock( + [ + ( + "profiles", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "profile", + wagtail.snippets.blocks.SnippetChooserBlock( + networkapi.wagtailpages.pagemodels.profiles.Profile + ), + ) + ] + ), + min_num=1, + ), + ) + ] + ), + ), + ( + "article_teaser_block", + wagtail.blocks.StructBlock( + [ + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "article", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to.", + page_type=["wagtailpages.ArticlePage"], + required=False, + ), + ) + ] + ), + help_text="Please use a minimum of 3 cards.", + min_num=3, + ), + ) + ] + ), + ), + ( + "group_listing_block", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the group of cards.", required=False + ), + ), + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", required=False + ), + ), + ( + "meta_data", + wagtail.blocks.CharBlock( + help_text="Optional meta data information for the card.", + required=False, + ), + ), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ( + "body", + wagtail.blocks.RichTextBlock( + features=["bold", "link"], help_text="Body text of the card." + ), + ), + ( + "url", + wagtail.blocks.CharBlock( + help_text="The URL this card should link to.", required=False + ), + ), + ] + ) + ), + ), + ] + ), + ), + ( + "image_feature", + wagtail.blocks.StructBlock( + [ + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "alt_text", + wagtail.blocks.CharBlock(help_text="Image description (for screen readers)."), + ), + ("metadata", wagtail.blocks.CharBlock(required=False)), + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ( + "title_link", + wagtail.blocks.PageChooserBlock( + help_text="Page that the title should link out to.", required=False + ), + ), + ("body", wagtail.blocks.CharBlock(required=False)), + ] + ), + ), + ( + "image_teaser_block", + wagtail.blocks.StructBlock( + [ + ("title", wagtail.blocks.CharBlock(help_text="Heading for the card.")), + ("text", wagtail.blocks.RichTextBlock(features=["bold"])), + ("image", wagtail.images.blocks.ImageChooserBlock()), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", required=True + ), + ), + ( + "link_button", + wagtail.blocks.ListBlock( + 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"', + 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 + ), + ), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ] + ), + help_text="Optional link button", + max_num=1, + min_num=0, + ), + ), + ( + "top_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider above content block.", required=False + ), + ), + ( + "bottom_divider", + wagtail.blocks.BooleanBlock( + help_text="Optional divider below content block.", required=False + ), + ), + ] + ), + ), + ( + "text_only_teaser", + wagtail.blocks.StructBlock( + [ + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock(help_text="Heading for the card."), + ), + ( + "link_page", + wagtail.blocks.PageChooserBlock( + help_text="Page that the header should link out to.", + required=False, + ), + ), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that the header should link out to.", + required=False, + ), + ), + ("meta_data", wagtail.blocks.CharBlock(max_length=500)), + ( + "body", + wagtail.blocks.TextBlock( + help_text="Body text of the card.", + max_length=200, + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 3 cards.", + min_num=3, + ), + ) + ] + ), + ), + ( + "block_with_aside", + wagtail.blocks.StructBlock( + [ + ( + "content", + wagtail.blocks.StreamBlock( + [ + ( + "listing", + wagtail.blocks.StructBlock( + [ + ( + "heading", + wagtail.blocks.CharBlock( + help_text="Heading for the block.", required=False + ), + ), + ( + "cards", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "image", + wagtail.images.blocks.ImageChooserBlock(), + ), + ( + "alt_text", + wagtail.blocks.CharBlock( + help_text="Alt text for card's image.", + required=False, + ), + ), + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the card." + ), + ), + ( + "highlighted_metadata", + wagtail.blocks.CharBlock( + help_text="Metadata to highlight on the card.", + required=False, + ), + ), + ( + "metadata", + wagtail.blocks.CharBlock( + help_text="Generic metadata.", + required=False, + ), + ), + ( + "body", + wagtail.blocks.RichTextBlock( + features=["bold"], + help_text="Body text of the card.", + required=False, + ), + ), + ( + "link_page", + wagtail.blocks.PageChooserBlock( + help_text="Page that this should link out to.", + required=False, + ), + ), + ( + "link_url", + wagtail.blocks.CharBlock( + help_text="Optional URL that the header should link out to.", + required=False, + ), + ), + ] + ), + help_text="Please use a minimum of 2 cards.", + min_num=2, + ), + ), + ( + "cards_per_row", + wagtail.blocks.ChoiceBlock( + choices=[(2, "2"), (3, "3")], + help_text="Number of cards per row. Note: this is a max and fewer might be used if is less space is available.", + required=False, + ), + ), + ] + ), + ), + ( + "paragraph", + wagtail.blocks.RichTextBlock( + features=[ + "bold", + "italic", + "link", + "h2", + "h3", + "h4", + "h5", + "ol", + "ul", + "hr", + "document-link", + ] + ), + ), + ], + help_text="The wider block that appears on the left on desktop", + icon="doc-full", + max_num=1, + ), + ), + ( + "aside", + wagtail.blocks.StreamBlock( + [ + ( + "aside_content", + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the card.", required=False + ), + ), + ( + "body", + wagtail.blocks.TextBlock( + help_text="Body text of the card.", required=False + ), + ), + ] + ), + ), + ( + "linkbutton", + 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"', + 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 + ), + ), + ( + "styling", + wagtail.blocks.ChoiceBlock( + choices=[ + ("btn-primary", "Primary button"), + ("btn-secondary", "Secondary button"), + ] + ), + ), + ] + ), + ), + ( + "spacer", + wagtail.blocks.StructBlock( + [ + ( + "size", + wagtail.blocks.ChoiceBlock( + choices=[ + ("1", "quarter spacing"), + ("2", "half spacing"), + ("3", "single spacing"), + ("4", "one and a half spacing"), + ("5", "triple spacing"), + ] + ), + ) + ] + ), + ), + ], + help_text="Elements here will appear in the column on the right side of the page on desktop. This can be left blank if you would just like a 2/3 column on the left", + icon="doc-full", + required=False, + ), + ), + ] + ), + ), + ( + "accordion", + wagtail.blocks.StructBlock( + [ + ( + "accordion_items", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "title", + wagtail.blocks.CharBlock( + help_text="Heading for the Accordion Item" + ), + ), + ( + "content", + wagtail.blocks.StreamBlock( + [ + ( + "rich_text", + wagtail.blocks.RichTextBlock( + blank=True, + features=[ + "bold", + "italic", + "link", + "ul", + "ol", + "document-link", + ], + ), + ), + ( + "datawrapper", + wagtail.embeds.blocks.EmbedBlock( + help_text='Enter the "visualization only" link of the Datawrapper chart. It looks something like this: https://datawrapper.dwcdn.net/KwSKp/1/', + icon="image", + template="wagtailpages/blocks/datawrapper_block.html", + ), + ), + ( + "image", + wagtail.blocks.StructBlock( + [ + ( + "image", + wagtail.images.blocks.ImageChooserBlock(), + ), + ( + "altText", + wagtail.blocks.CharBlock( + help_text="Image description (for screen readers).", + required=True, + ), + ), + ] + ), + ), + ( + "video", + wagtail.blocks.StructBlock( + [ + ( + "url", + wagtail.blocks.URLBlock( + help_text="For YouTube: go to your YouTube video and click “Share,” then “Embed,” and then copy and paste the provided URL only. For example: https://www.youtube.com/embed/3FIVXBawyQw For Vimeo: follow similar steps to grab the embed URL. For example: https://player.vimeo.com/video/9004979", + label="Embed URL", + ), + ), + ( + "caption", + wagtail.blocks.CharBlock(required=False), + ), + ( + "caption_url", + wagtail.blocks.ListBlock( + wagtail.blocks.StructBlock( + [ + ( + "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"', + 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, + ), + ), + ] + ), + help_text="Optional URL that this caption should link out to.", + max_num=1, + min_num=0, + ), + ), + ( + "video_width", + wagtail.blocks.ChoiceBlock( + choices=[ + ("normal", "Normal"), + ("wide", "Wide"), + ("full_width", "Full Width"), + ], + help_text="Wide videos are col-12, Full-Width videos reach both ends of the screen.", + ), + ), + ] + ), + ), + ] + ), + ), + ] + ) + ), + ) + ] + ), + ), + ], + use_json_field=True, + ), + ), + ] diff --git a/network-api/networkapi/wagtailpages/pagemodels/app_install.py b/network-api/networkapi/wagtailpages/pagemodels/app_install.py index 85e2ee6d6e5..acdab3a4e76 100644 --- a/network-api/networkapi/wagtailpages/pagemodels/app_install.py +++ b/network-api/networkapi/wagtailpages/pagemodels/app_install.py @@ -3,6 +3,8 @@ from wagtail.fields import StreamField from wagtail_localize.fields import SynchronizedField, TranslatableField +from networkapi.wagtailpages.utils import CharCountWidget + from .campaigns import CampaignPage from .customblocks.app_install_download_button_block import ( AppInstallDownloadButtonBlock, @@ -12,11 +14,11 @@ class AppInstallPage(CampaignPage): hero_heading = models.CharField( - max_length=80, + max_length=250, help_text="Hero story headline", ) hero_subheading = models.CharField( - max_length=80, + max_length=250, blank=True, help_text="Hero story subheadline", ) @@ -46,8 +48,16 @@ class AppInstallPage(CampaignPage): MultiFieldPanel( [ FieldPanel("hero_background"), - FieldPanel("hero_heading"), - FieldPanel("hero_subheading"), + FieldPanel( + "hero_heading", + classname="full title", + widget=CharCountWidget(attrs={"class": "max-length-warning", "data-max-length": 80}), + ), + FieldPanel( + "hero_subheading", + classname="full title", + widget=CharCountWidget(attrs={"class": "max-length-warning", "data-max-length": 80}), + ), FieldPanel("download_buttons"), FieldPanel("hero_video"), ], diff --git a/network-api/networkapi/wagtailpages/pagemodels/base.py b/network-api/networkapi/wagtailpages/pagemodels/base.py index cdd1bb4c14a..9a9c6b86272 100644 --- a/network-api/networkapi/wagtailpages/pagemodels/base.py +++ b/network-api/networkapi/wagtailpages/pagemodels/base.py @@ -11,7 +11,7 @@ # TODO: https://github.com/mozilla/foundation.mozilla.org/issues/2362 from ..donation_modal import DonationModals # noqa: F401 -from ..utils import TitleWidget, get_page_tree_information +from ..utils import CharCountWidget, get_page_tree_information from .customblocks.base_fields import base_fields from .customblocks.base_rich_text_options import base_rich_text_options from .mixin.foundation_banner_inheritance import FoundationBannerInheritanceMixin @@ -838,7 +838,7 @@ def get_banner(self): [ FieldPanel( "hero_headline", - widget=TitleWidget(attrs={"class": "max-length-warning", "data-max-length": 60}), + widget=CharCountWidget(attrs={"class": "max-length-warning", "data-max-length": 60}), ), FieldPanel("hero_button_text"), FieldPanel("hero_button_url"), diff --git a/network-api/networkapi/wagtailpages/pagemodels/blog/blog.py b/network-api/networkapi/wagtailpages/pagemodels/blog/blog.py index 725511b07f9..7f8c446ccb4 100644 --- a/network-api/networkapi/wagtailpages/pagemodels/blog/blog.py +++ b/network-api/networkapi/wagtailpages/pagemodels/blog/blog.py @@ -24,7 +24,7 @@ from networkapi.wagtailpages.forms import BlogPageForm from networkapi.wagtailpages.pagemodels.profiles import Profile -from ...utils import TitleWidget, get_content_related_by_tag +from ...utils import CharCountWidget, get_content_related_by_tag from .. import customblocks from ..base import BasePage from ..customblocks.full_content_rich_text_options import full_content_rich_text_options @@ -167,7 +167,7 @@ class BlogPage(BasePage): TitleFieldPanel( "title", classname="full title", - widget=TitleWidget(attrs={"class": "max-length-warning", "data-max-length": 60}), + widget=CharCountWidget(attrs={"class": "max-length-warning", "data-max-length": 60}), ), MultiFieldPanel([InlinePanel("authors", label="Author", min_num=1)], heading="Author(s)"), FieldPanel("topics", widget=CheckboxSelectMultiple), diff --git a/network-api/networkapi/wagtailpages/pagemodels/buyersguide/categories.py b/network-api/networkapi/wagtailpages/pagemodels/buyersguide/categories.py index 5e301c21890..d4171cc4b2e 100644 --- a/network-api/networkapi/wagtailpages/pagemodels/buyersguide/categories.py +++ b/network-api/networkapi/wagtailpages/pagemodels/buyersguide/categories.py @@ -20,7 +20,7 @@ from networkapi.wagtailpages.pagemodels.buyersguide.forms import ( BuyersGuideProductCategoryForm, ) -from networkapi.wagtailpages.utils import TitleWidget +from networkapi.wagtailpages.utils import CharCountWidget if typing.TYPE_CHECKING: from networkapi.wagtailpages.models import BuyersGuideArticlePage @@ -103,7 +103,7 @@ class BuyersGuideProductCategory( panels = [ FieldPanel( "name", - widget=TitleWidget(attrs={"class": "max-length-warning", "data-max-length": 50}), + widget=CharCountWidget(attrs={"class": "max-length-warning", "data-max-length": 50}), ), FieldPanel("description"), FieldPanel("parent"), diff --git a/network-api/networkapi/wagtailpages/pagemodels/customblocks/image_teaser_block.py b/network-api/networkapi/wagtailpages/pagemodels/customblocks/image_teaser_block.py index 7652237d2df..951b55315d5 100644 --- a/network-api/networkapi/wagtailpages/pagemodels/customblocks/image_teaser_block.py +++ b/network-api/networkapi/wagtailpages/pagemodels/customblocks/image_teaser_block.py @@ -1,10 +1,12 @@ -from django.forms.utils import ErrorList from django.utils import functional as func_utils from django.utils import text as text_utils from wagtail import blocks -from wagtail.blocks.struct_block import StructBlockValidationError from wagtail.images.blocks import ImageChooserBlock +from networkapi.wagtailpages.pagemodels.customblocks.link_button_block import ( + LinkButtonBlock, +) + class ImageTeaserValue(blocks.StructValue): @func_utils.cached_property @@ -19,15 +21,7 @@ class ImageTeaserBlock(blocks.StructBlock): altText = blocks.CharBlock(required=True, help_text="Image description (for screen readers).") - url_label = blocks.CharBlock(required=False) - url = blocks.CharBlock(required=False) - styling = blocks.ChoiceBlock( - choices=[ - ("btn-primary", "Primary button"), - ("btn-secondary", "Secondary button"), - ], - default="btn-primary", - ) + link_button = blocks.ListBlock(LinkButtonBlock(), min_num=0, max_num=1, help_text="Optional link button") top_divider = blocks.BooleanBlock( required=False, help_text="Optional divider above content block.", @@ -51,19 +45,6 @@ def get_context(self, value, parent_context=None): context["divider_styles"] = " ".join(divider_styles) return context - def clean(self, value): - result = super().clean(value) - errors = {} - - if value["url"] and not value["url_label"]: - errors["url_label"] = ErrorList(["Please add a label value for the URL."]) - if value["url_label"] and not value["url"]: - errors["url"] = ErrorList(["Please add a URL value for the link."]) - if errors: - raise StructBlockValidationError(block_errors=errors) - - return result - class Meta: label = "Image teaser" icon = "doc-full" diff --git a/network-api/networkapi/wagtailpages/pagemodels/customblocks/video_block.py b/network-api/networkapi/wagtailpages/pagemodels/customblocks/video_block.py index 180afb792d6..ccb1bf5ec92 100644 --- a/network-api/networkapi/wagtailpages/pagemodels/customblocks/video_block.py +++ b/network-api/networkapi/wagtailpages/pagemodels/customblocks/video_block.py @@ -3,6 +3,10 @@ from wagtail.images.blocks import ImageChooserBlock from wagtailmedia import blocks as wagtailmedia_blocks +from networkapi.wagtailpages.pagemodels.customblocks.link_block import ( + LinkWithoutLabelBlock, +) + class RadioSelectBlock(blocks.ChoiceBlock): def __init__(self, *args, **kwargs): @@ -25,7 +29,7 @@ class Meta: class VideoBlock(blocks.StructBlock): - url = blocks.CharBlock( + url = blocks.URLBlock( label="Embed URL", help_text="For YouTube: go to your YouTube video and click “Share,” " "then “Embed,” and then copy and paste the provided URL only. " @@ -36,7 +40,9 @@ class VideoBlock(blocks.StructBlock): caption = blocks.CharBlock( required=False, ) - captionURL = blocks.CharBlock(required=False, help_text="Optional URL for caption to link to.") + caption_url = blocks.ListBlock( + LinkWithoutLabelBlock(), min_num=0, max_num=1, help_text="Optional URL that this caption should link out to." + ) video_width = RadioSelectBlock( choices=( ("normal", "Normal"), diff --git a/network-api/networkapi/wagtailpages/pagemodels/publications/article.py b/network-api/networkapi/wagtailpages/pagemodels/publications/article.py index 43987bd8c5a..9fc776d5f1c 100644 --- a/network-api/networkapi/wagtailpages/pagemodels/publications/article.py +++ b/network-api/networkapi/wagtailpages/pagemodels/publications/article.py @@ -15,7 +15,7 @@ from networkapi.wagtailpages.pagemodels.profiles import Profile from networkapi.wagtailpages.pagemodels.publications.publication import PublicationPage -from networkapi.wagtailpages.utils import TitleWidget, get_plaintext_titles +from networkapi.wagtailpages.utils import CharCountWidget, get_plaintext_titles from ..article_fields import article_fields from ..base import BasePage @@ -182,7 +182,7 @@ class ArticlePage(BasePage): TitleFieldPanel( "title", classname="full title", - widget=TitleWidget(attrs={"class": "max-length-warning", "data-max-length": 60}), + widget=CharCountWidget(attrs={"class": "max-length-warning", "data-max-length": 60}), ), MultiFieldPanel([InlinePanel("authors", label="Author", min_num=0)], heading="Author(s)"), MultiFieldPanel( diff --git a/network-api/networkapi/wagtailpages/templates/wagtailpages/bannered_campaign_page.html b/network-api/networkapi/wagtailpages/templates/wagtailpages/bannered_campaign_page.html index 806fc93ad00..389ae8e244b 100644 --- a/network-api/networkapi/wagtailpages/templates/wagtailpages/bannered_campaign_page.html +++ b/network-api/networkapi/wagtailpages/templates/wagtailpages/bannered_campaign_page.html @@ -19,7 +19,7 @@