class ListingBlock(blocks.StructBlock): title = blocks.CharBlock(required=False, max_length=128) display_meta_info = blocks.BooleanBlock(required=False) featured_pages = blocks.ListBlock(blocks.PageChooserBlock()) pages = blocks.ListBlock(blocks.PageChooserBlock()) class Meta: icon = 'list-ul' template = "home/blocks/listing_block.html"
def test_clean(self): required_block = blocks.PageChooserBlock() nonrequired_block = blocks.PageChooserBlock(required=False) christmas_page = Page.objects.get(slug='christmas') self.assertEqual(required_block.clean(christmas_page), christmas_page) with self.assertRaises(ValidationError): required_block.clean(None) self.assertEqual(nonrequired_block.clean(christmas_page), christmas_page) self.assertEqual(nonrequired_block.clean(None), None)
class PageCardBlock(blocks.StructBlock): """ Represents the card for a page. Has a link, text and some """ """ image. """ image = ImageChooserBlock() link = blocks.PageChooserBlock() caption = blocks.CharBlock() text = blocks.RichTextBlock()
class LinkBlock(blocks.StructBlock): page = blocks.PageChooserBlock() title = blocks.CharBlock( help_text="Leave blank to use the page's own title", required=False) class Meta: template = 'navigation/blocks/menu_item.html',
class LinkBlock(blocks.StructBlock): text = blocks.CharBlock(required=False) page = blocks.PageChooserBlock(required=False) absolute_url = blocks.CharBlock(label="Url", required=False) class Meta: template = 'wagtail_extensions/blocks/link.html' def clean(self, value): if value.get('page') and value.get('absolute_url'): errors = { 'page': ErrorList([ ValidationError('Either a page or url must be defined'), ]), } raise ValidationError('There is a problem with this link', params=errors) return super().clean(value) def to_python(self, value): value = super().to_python(value) if value.get('page'): value['url'] = value['page'].url elif value.get('absolute_url'): value['url'] = value.get('absolute_url') return value def get_context(self, value, parent_context=None): ctx = super().get_context(value, parent_context=parent_context) ctx['has_url'] = 'url' in value return ctx
class CallToActionBlock(blocks.StructBlock): call_to_action = blocks.CharBlock(max_length=32) page = blocks.PageChooserBlock() class Meta: label = 'Call to action' template = 'blocks/call_to_action.html'
class ResourcePage(Page): """Class for pages that include a side nav, multiple sections and citations""" intro = StreamField([('paragraph', blocks.RichTextBlock())], null=True) sections = StreamField([('sections', ResourceBlock())], null=True) citations = StreamField( [('citations', blocks.ListBlock(CitationsBlock()))], null=True) related_topics = StreamField( [('related_topics', blocks.ListBlock(blocks.PageChooserBlock(label="Related topic")))], null=True) breadcrumb_style = models.CharField(max_length=255, choices=[('primary', 'Blue'), ('secondary', 'Red')], default='primary') content_panels = Page.content_panels + [ StreamFieldPanel('intro'), StreamFieldPanel('sections'), StreamFieldPanel('citations'), StreamFieldPanel('related_topics') ] promote_panels = Page.promote_panels + [ FieldPanel('breadcrumb_style'), ]
class RegulationsList(organisms.ModelBlock): model = 'regulations3k.RegulationPage' ordering = 'title' heading = blocks.CharBlock(required=False, help_text='Regulations list heading') more_regs_page = blocks.PageChooserBlock( help_text='Link to more regulations') more_regs_text = blocks.CharBlock( required=False, help_text='Text to show on link to more regulations') def filter_queryset(self, qs, value): return qs.live() def get_queryset(self, value): qs = super(RegulationsList, self).get_queryset(value) future_versions_qs = EffectiveVersion.objects.filter( draft=False, effective_date__gte=date.today()) qs = qs.prefetch_related( Prefetch('regulation__versions', queryset=future_versions_qs, to_attr='future_versions')) return qs def get_context(self, value, parent_context=None): context = super(RegulationsList, self).get_context(value, parent_context=parent_context) context['regulations'] = self.get_queryset(value) return context class Meta: icon = 'list-ul' template = 'regulations3k/regulations-listing.html'
class ResourceBlock(blocks.StructBlock): """A section of a ResourcePage""" title = blocks.CharBlock(required=True) hide_title = blocks.BooleanBlock(required=False, help_text='Should the section title be displayed?') content = blocks.StreamBlock([ ('text', blocks.RichTextBlock(blank=False, null=False, required=False, icon='pilcrow')), ('documents', blocks.ListBlock(ThumbnailBlock(), template='blocks/section-documents.html', icon='doc-empty')), ('contact_info', ContactInfoBlock()), ('internal_button', InternalButtonBlock()), ('external_button', ExternalButtonBlock()), ('page', blocks.PageChooserBlock(template='blocks/page-links.html')), ('disabled_page', blocks.CharBlock(blank=False, null=False, required=False, template='blocks/disabled-page-links.html', icon='placeholder', help_text='Name of a disabled link')), ('document_list', blocks.ListBlock(FeedDocumentBlock(), template='blocks/document-list.html', icon='doc-empty')), ('current_commissioners', CurrentCommissionersBlock()), ('fec_jobs', CareersBlock()), ('mur_search', MURSearchBlock()), ('table', TableBlock()), ('html', blocks.RawHTMLBlock()), ('reporting_example_cards', ReportingExampleCards()), ('contribution_limits_table', SnippetChooserBlock('home.EmbedTableSnippet', template = 'blocks/embed-table.html', icon='table')), ]) aside = blocks.StreamBlock([ ('title', blocks.CharBlock(required=False, icon='title')), ('document', ThumbnailBlock()), ('link', AsideLinkBlock()), ], template='blocks/section-aside.html', icon='placeholder') class Meta: template = 'blocks/section.html'
class Link(blocks.StructBlock): link_text = blocks.CharBlock( required=True, label='Text' ) page_link = blocks.PageChooserBlock( required=False, help_text='Link to a page in Wagtail.', label='Page' ) external_link = blocks.CharBlock( required=False, max_length=1000, label='Direct URL (rare)', help_text='Enter url for page outside Wagtail. This will only ' 'be used if there is no page selected.' ) def clean(self, value): cleaned = super(Link, self).clean(value) if not cleaned.get('page_link') and not cleaned.get('external_link'): raise ValidationError( 'Validation error in link', params={ 'page_link': [ 'Either page or external link is required.' ], 'external_link': [ 'Either page or external link is required.' ] } ) return cleaned
class FeaturedContent(blocks.StructBlock): heading = blocks.CharBlock(required=False) body = blocks.RichTextBlock(required=False) category = blocks.ChoiceBlock(choices=ref.fcm_types, required=False) post = blocks.PageChooserBlock(required=False) show_post_link = blocks.BooleanBlock(required=False, label="Render post link?") post_link_text = blocks.CharBlock(required=False) image = atoms.ImageBasic(required=False) links = blocks.ListBlock(atoms.Hyperlink(required=False), label='Additional Links') video = blocks.StructBlock([ ('id', blocks.CharBlock( required=False, help_text= 'e.g In \"https://www.youtube.com/watch?v=en0Iq8II4fA\", the ID is everything after the \"?v=\"' )), ('url', blocks.CharBlock(default='/', required=False)), ('height', blocks.CharBlock(default='320', required=False)), ('width', blocks.CharBlock(default='568', required=False)), ]) class Meta: template = '_includes/molecules/featured-content.html' icon = 'doc-full-inverse' label = 'Featured Content' classname = 'block__flush'
class JobListingList(OpenJobListingsMixin, organisms.ModelList): model = 'jobmanager.JobListingPage' ordering = ('close_date', 'title') heading = blocks.CharBlock(required=False, help_text='List heading') more_jobs_page = blocks.PageChooserBlock( help_text='Link to full list of jobs' ) more_jobs_text = blocks.CharBlock( required=False, help_text='Text to show on link to full list of jobs' ) hide_closed = blocks.BooleanBlock( required=False, default=True, help_text=( 'Whether to hide jobs that are not currently open ' '(jobs will automatically update)' ) ) def render(self, value, context=None): value['careers'] = self.get_queryset(value) value.update(context or {}) template = '_includes/organisms/job-listing-list.html' return render_to_string(template, value)
class RegulationsList(organisms.ModelBlock): model = 'regulations3k.RegulationPage' ordering = 'title' heading = blocks.CharBlock( required=False, help_text='Regulations list heading' ) more_regs_page = blocks.PageChooserBlock( help_text='Link to more regulations' ) more_regs_text = blocks.CharBlock( required=False, help_text='Text to show on link to more regulations' ) def filter_queryset(self, qs, value): return qs.live() def get_context(self, value, parent_context=None): context = super(RegulationsList, self).get_context( value, parent_context=parent_context ) context['regulations'] = self.get_queryset(value) return context class Meta: icon = 'list-ul' template = 'regulations3k/regulations-listing.html'
class CollectionPage(Page): body = stream_factory(null=True, blank=True) sidebar_title = models.CharField(max_length=255, null=True, blank=True) related_pages = StreamField( [('related_pages', blocks.ListBlock(blocks.PageChooserBlock()))], null=True, blank=True) sections = StreamField([('section', CollectionBlock())]) show_search = models.BooleanField(max_length=255, default=False, null=False, blank=False, choices=[ (True, 'Show committee search box'), (False, 'Do not show committee search box') ]) content_panels = Page.content_panels + [ StreamFieldPanel('body'), FieldPanel('sidebar_title'), FieldPanel('show_search'), StreamFieldPanel('related_pages'), StreamFieldPanel('sections'), ]
class EmailSignUp(blocks.StructBlock): heading = blocks.CharBlock(required=False, default='Stay informed') default_heading = blocks.BooleanBlock( required=False, default=True, label='Default heading style', help_text=('If selected, heading will be styled as an H5 ' 'with green top rule. Deselect to style header as H3.') ) text = blocks.CharBlock( required=False, help_text=('Write a sentence or two about what kinds of emails the ' 'user is signing up for, how frequently they will be sent, ' 'etc.') ) gd_code = blocks.CharBlock( required=False, label='GovDelivery code', help_text=('Code for the topic (i.e., mailing list) you want people ' 'who submit this form to subscribe to. Format: USCFPB_###') ) disclaimer_page = blocks.PageChooserBlock( required=False, label='Privacy Act statement', help_text=('Choose the page that the "See Privacy Act statement" link ' 'should go to. If in doubt, use "Generic Email Sign-Up ' 'Privacy Act Statement".') ) class Meta: icon = 'mail' template = '_includes/organisms/email-signup.html' class Media: js = ['email-signup.js']
class ResourceBlock(blocks.StructBlock): """A section of a ResourcePage""" title = blocks.CharBlock(required=True) hide_title = blocks.BooleanBlock( required=False, help_text='Should the section title be displayed?') content = blocks.StreamBlock([ ('text', blocks.RichTextBlock(blank=False, null=False, required=False, icon='pilcrow')), ('documents', blocks.ListBlock(ThumbnailBlock(), template='blocks/section-documents.html', icon='doc-empty')), ('contact_info', ContactInfoBlock()), ('internal_button', InternalButtonBlock()), ('external_button', ExternalButtonBlock()), ('page', blocks.PageChooserBlock(template='blocks/page-links.html')), ('document_list', blocks.ListBlock(FeedDocumentBlock(), template='blocks/document-list.html', icon='doc-empty')), ('current_commissioners', CurrentCommissionersBlock()), ('fec_jobs', CareersBlock()), ('table', TableBlock()) ]) aside = blocks.StreamBlock( [('title', blocks.CharBlock(required=False, icon='title')), ('document', ThumbnailBlock()), ('link', AsideLinkBlock())], template='blocks/section-aside.html', icon='placeholder') class Meta: template = 'blocks/section.html'
class LinkButtonBlock(ColBlock): title = blocks.CharBlock() page = blocks.PageChooserBlock(required=False) document = DocumentChooserBlock(required=False) class Meta: template = 'blocks/link_button_block.html'
class Navigation(models.Model): title = models.CharField(max_length=255) slug = models.SlugField(max_length=255) navigation = StreamField([ ('menu_block', blocks.StructBlock([('title', blocks.CharBlock()), ('menu_items', blocks.ListBlock( blocks.StreamBlock([ ('link_external', blocks.StructBlock([ ('caption', blocks.CharBlock()), ('url', blocks.CharBlock()), ('mega_menu', blocks.BooleanBlock( label="Show_in_mega_menu", default=False, blank=True, required=False)), ])), ('link_page', blocks.PageChooserBlock()), ])))])), ], blank=True) panels = [ FieldPanel('title'), FieldPanel('slug'), StreamFieldPanel('navigation'), ] def __unicode__(self): return self.title
class URLOrPageBlock(blocks.StructBlock): page = blocks.PageChooserBlock(required=False) url = blocks.URLBlock(required=False) class Meta: icon = 'link' template = "pages/blocks/url_or_page.html"
class InternalButtonBlock(blocks.StructBlock): """A block that makes a button to an internal page""" internal_page = blocks.PageChooserBlock() text = blocks.CharBlock() class Meta: template = 'blocks/button.html' icon = 'link'
class PageLinkBlock(BaseLinkBlock): """ Block that holds a page. """ page = blocks.PageChooserBlock() class Meta: icon = 'fa fa-file-o'
class CarouselBlock(blocks.StructBlock): """ Single Carousel slide""" image = ImageChooserBlock() caption = blocks.CharBlock() text = blocks.RichTextBlock() link = blocks.PageChooserBlock() class Meta: template = 'home/carousel_block.html'
class RelatedItemsBlock(blocks.StructBlock): heading = blocks.CharBlock(default="Related") items = blocks.ListBlock(blocks.PageChooserBlock(label="item")) def __init__(self, **kwargs): super(RelatedItemsBlock, self).__init__(icon="list-ul", **kwargs) class Meta: template = "articles/blocks/related_items_block.html"
def test_form_response(self): block = blocks.PageChooserBlock() christmas_page = Page.objects.get(slug='christmas') value = block.value_from_datadict({'page': str(christmas_page.id)}, {}, 'page') self.assertEqual(value, christmas_page) empty_value = block.value_from_datadict({'page': ''}, {}, 'page') self.assertEqual(empty_value, None)
class FeaturedLibraryExpertBaseBlock(blocks.StructBlock): """ Base treamfield block for "Featured Library Experts". """ library_expert = blocks.PageChooserBlock( # In the future Wagtail plans to allow the limiting of PageChooserBlock by page type. This will improve when we have that. required=False, help_text='Be sure to select a StaffPage (not a StaffPublicPage)', ) libguides = blocks.ListBlock(LinkBlock(), icon='link')
def test_deserialize(self): """The serialized value of a PageChooserBlock (an ID) should deserialize to a Page object""" block = blocks.PageChooserBlock() christmas_page = Page.objects.get(slug='christmas') self.assertEqual(block.to_python(christmas_page.id), christmas_page) # None should deserialize to None self.assertEqual(block.to_python(None), None)
def test_serialize(self): """The value of a PageChooserBlock (a Page object) should serialize to an ID""" block = blocks.PageChooserBlock() christmas_page = Page.objects.get(slug='christmas') self.assertEqual(block.get_prep_value(christmas_page), christmas_page.id) # None should serialize to None self.assertEqual(block.get_prep_value(None), None)
class InternalPageBlock(AbstractPageBlock): page = blocks.PageChooserBlock() def get_serializable_data(self, obj): page = obj['page'] result = obj result['page'] = page.serializable_data() result['page']['url'] = page.url return result
class FullWidthImageBlock(blocks.StructBlock): image = ImageChooserBlock() title = blocks.CharBlock(required=False) description = blocks.TextBlock(required=False) page = blocks.PageChooserBlock(required=False) link = blocks.URLBlock(required=False) class Meta: template = 'blocks/full_width_image_block.html'
def test_form_render(self): block = blocks.PageChooserBlock() empty_form_html = block.render_form(None, 'page') self.assertIn('<input id="page" name="page" placeholder="" type="hidden" />', empty_form_html) christmas_page = Page.objects.get(slug='christmas') christmas_form_html = block.render_form(christmas_page, 'page') expected_html = '<input id="page" name="page" placeholder="" type="hidden" value="%d" />' % christmas_page.id self.assertIn(expected_html, christmas_form_html)