class ArticlePage(Page): body = StreamField( [ ('heading', CharBlock(classname="full title")), ('paragraph', RichTextBlock()), ('reference_page', PageChooserBlock()), # this is single StructBlock ('struct_data', StructBlock([ ('heading', CharBlock(classname="full title")), ('paragraph', RichTextBlock()), ('reference_page', PageChooserBlock()), ])), # this is StreamBlock ('stream_data', StreamBlock([ ('sub_struct_data', StructBlock([ ('heading', CharBlock(classname="full title")), ('paragraph', RichTextBlock()), ('reference_page', PageChooserBlock()), ])), ])), ('column_struct_data', ColumnStructBlock()), ('column_stream_data', ColumnStreamBlock()) ], null=True, blank=True) # Editor panels configuration content_panels = Page.content_panels + [ StreamFieldPanel('body'), ]
class HeroSectionBlock(SectionBlock): heading = CharBlock(required=False, max_length=100, label='Hero title', default='We are heroes') description = TextBlock( required=False, max_length=400, label='Hero subtitle', default= 'The thing we do is better than any other similar thing and this hero panel will convince you of that, just by having a glorious background image.' ) image = ImageChooserBlock(required=False, label='Hero image') content = StreamBlock( [('button', StructBlock( [ ('text', CharBlock(required=False, max_length=80, label='Label')), ('url', URLBlock(required=False, label='URL')), ], required=False, label='Call to action', help_text='A "call-to-action" button, like "Sign Up Now!"')), ('video', EmbedBlock(required=False, label='Video')), ('quote', StructBlock( [ ('text', TextBlock()), ('author', CharBlock(required=False)), ], required=False, label='Quote', help_text ='An inspiring quotation, optionally attributed to someone'))], required=False, block_counts={ 'button': { 'max_num': 1 }, 'video': { 'max_num': 1 }, 'quote': { 'max_num': 1 } }) class Meta: icon = 'placeholder' label = 'Hero Section'
class ExpertiseBlock(StructBlock): """ Renders the 'our expertise' section """ heading = CharBlock(icon='fa-heading', required=False, default='Our expertise') description = RichTextBlock(icon='fa-paragraph', template='blocks/paragraph_block.html', features=RICHTEXT_FEATURES_NO_FOOTNOTES, required=False) expertise_list = ListBlock(StructBlock([ ('name', TextBlock(icon='fa-text')), ('description', RichTextBlock(icon='fa-paragraph', template='blocks/paragraph_block.html', features=RICHTEXT_FEATURES_NO_FOOTNOTES, required=False)) ]), required=False) light = BooleanBlock( default=False, required=False, help_text='Applies a lighter background to the section') class Meta(): template = 'blocks/expertise.html'
class StreamPage(Page): body = StreamField([ ("text", CharBlock()), ("rich_text", RichTextBlock()), ("image", ExtendedImageChooserBlock()), ( "product", StructBlock([ ("name", CharBlock()), ("price", CharBlock()), ]), ), ("raw_html", RawHTMLBlock()), ( "books", StreamBlock([ ("title", CharBlock()), ("author", CharBlock()), ]), ), ]) api_fields = ("body", ) content_panels = [ FieldPanel("title"), FieldPanel("body"), ] preview_modes = []
class LinkListBlock(StructBlock): footer_links = ListBlock( StructBlock([ ('text', CharBlock()), ('page', PageChooserBlock()), ('external_link', URLBlock()), ]))
class StreamPage(Page): body = StreamField([ ('text', CharBlock()), ('rich_text', RichTextBlock()), ('image', ExtendedImageChooserBlock()), ('product', StructBlock([ ('name', CharBlock()), ('price', CharBlock()), ])), ('raw_html', RawHTMLBlock()), ('books', StreamBlock([ ('title', CharBlock()), ('author', CharBlock()), ])), ]) api_fields = ('body', ) content_panels = [ FieldPanel('title'), StreamFieldPanel('body'), ] preview_modes = []
class PageWithSidebar(Page): page_type = CharField(max_length=100, choices=PAGE_CHOICES, default='none') show_in_sitemap = BooleanField(default=True) reference_title = TextField(null=True, blank=True) subtitle = TextField(null=True, blank=True) menu_title = TextField(blank=True) is_nav_root = BooleanField(default=False) is_selectable = BooleanField(default=True) body = StreamField([('advertisement', AdvertisementInline()), ('paragraph', RichTextBlock()), ('image', ImageChooserBlock()), ('document', DocumentViewerBlock()), ('html', RawHTMLBlock()), ('audio', AudioBlock()), ('video', VideoPlayerBlock()), ('tabs', TabsBlock()), ('translations', ListBlock(StructBlock( [('word', RichTextBlock(required=True)), ('translation', RichTextBlock(required=True))]), template="blocks/transcriptions.html")), ('post', PostBlock()), ('choosen_reviews', ChoosenReviews())], blank=True) def get_nav_root(self) -> Page: return get_nav_root(self)
class HistoryDateBlock(StreamBlock): """A block for History event card along the timeline which is shown on the HistoryPage.""" event_block_editor = StructBlock([ ('heading', CharBlock(required=False, max_length=100)), ('description', TextBlock(required=False)) ])
class HomePage(RoutablePageMixin, Page): footer_colour = models.CharField("Hover colour", max_length=255, blank=True, null=True) splash_items = StreamField([ ('image', StructBlock([('image', ImageChooserBlock(blank=True, required=False)), ('title', CharBlock(required=False)), ('page_link', PageChooserBlock(blank=True))], icon='image')), ], blank=True) @route('^checkout/$') def checkout(self, request): context = self.get_context(request) return TemplateResponse(request, 'shop/checkout.html', context) @route('^amend-basket/$') def amend_basket(self, request): context = self.get_context(request) return TemplateResponse(request, 'shop/amend_basket.html', context) content_panels = Page.content_panels + [ StreamFieldPanel('splash_items'), ] promote_panels = [ FieldPanel('footer_colour'), ] + Page.promote_panels
class Plain(Page): footer_colour = models.CharField("Hover colour", max_length=255, blank=True, null=True) plain_text = RichTextField(blank=True) page_content = StreamField([ ('text_block', StructBlock([ ('text', RichTextBlock(blank=True)), ('width', ChoiceBlock(required=False, max_length=20, choices=( (u'6', u'half'), (u'8', u'third'), ))), ], template='home/blocks/text.html', icon="pilcrow")), ], blank=True) content_panels = Page.content_panels + [ FieldPanel('plain_text'), StreamFieldPanel('page_content'), ] promote_panels = [ FieldPanel('footer_colour'), ] + Page.promote_panels
class CardBlock(StructBlock): """Карточки с изображением, текстом и кнопкой.""" title = CharBlock(required=True, help_text="Add your title") cards = ListBlock( StructBlock( [ ("image", ImageChooserBlock(required=True)), ("title", CharBlock(required=True, max_length=40)), ("text", TextBlock(required=True, max_length=200)), ("button_page", PageChooserBlock(required=False)), ( "button_url", URLBlock( required=False, help_text="Если выбрана страница кнопки выше, она будет использоваться первой.", # noqa ), ), ] ) ) class Meta: # noqa template = "layouts/card_block.html" icon = "placeholder" label = "Карточка с фото"
class ProgramDocuments(models.Model): """ List of documents associated with a program .. no_pii: """ display = models.BooleanField( blank=False, null=False, default=True, verbose_name="Display Program Documents", ) header = models.CharField( max_length=128, blank=False, null=False, default="Program Documents", verbose_name="Header for Program Documents", ) documents = StreamField( [ ('file', StructBlock( [ ('display_text', CharBlock()), ('document', DocumentChooserBlock()) ], icon='doc-full' )), ('link', StructBlock( [ ('display_text', CharBlock()), ('url', URLBlock()), ], icon='link' )) ], blank=True, verbose_name="Documents" ) page = ParentalKey(ProgramPage, on_delete=models.CASCADE, related_name='program_documents', unique=True) panels = [ FieldPanel('display'), FieldPanel('header'), StreamFieldPanel('documents'), ]
class ContactTypeStreamBlock(StreamBlock): """Model allowing the CMS to bring together multiple struct block objects.""" contact_type_editor = StructBlock([ ('heading', TextBlock()), ('description', RichTextBlock(required=False)), ('email', TextBlock()) ], icon='title', classname='title')
class DataSetMixin(models.Model): class Meta(): abstract = True parent_page_types = ['datasection.DataSetListing'] subpage_types = [] release_date = models.DateField(default=datetime.now) authors = StreamField( [('internal_author', PageChooserBlock(required=False, target_model='ourteam.TeamMemberPage', icon='fa-user')), ('external_author', StructBlock([('name', CharBlock(required=False)), ('title', CharBlock(required=False)), ('photograph', ImageChooserBlock(required=False)), ('page', URLBlock(required=False))], icon='fa-user'))], blank=True) meta_data = StreamField( [ ('description', RichTextBlock(required=True, features=RICHTEXT_FEATURES_NO_FOOTNOTES)), ('provenance', RichTextBlock(required=False, features=RICHTEXT_FEATURES_NO_FOOTNOTES)), ('variables', RichTextBlock(required=False, features=RICHTEXT_FEATURES_NO_FOOTNOTES)), ('geography', RichTextBlock(required=False, features=RICHTEXT_FEATURES_NO_FOOTNOTES)), ('geograpic_coding', RichTextBlock(required=False, features=RICHTEXT_FEATURES_NO_FOOTNOTES)), ('unit', RichTextBlock(required=False, features=RICHTEXT_FEATURES_NO_FOOTNOTES)), ('internal_notes', RichTextBlock(required=False, features=RICHTEXT_FEATURES_NO_FOOTNOTES)), ('licence', RichTextBlock(required=False, features=RICHTEXT_FEATURES_NO_FOOTNOTES)), ('citation', RichTextBlock(required=False, template="blocks/urlize_richtext.html", features=RICHTEXT_FEATURES_NO_FOOTNOTES)), ], verbose_name='Content', help_text= 'A description is expected, but only one of each shall be shown') other_pages_heading = models.CharField(blank=True, max_length=255, verbose_name='Heading', default='More about')
class LessonPage(Page): page_type = CharField(max_length=100, choices=PAGE_CHOICES, default='none') show_in_sitemap = BooleanField(default=True) menu_title = TextField(blank=True) is_nav_root = BooleanField(default=False) is_selectable = BooleanField(default=True) reference_title = TextField(null=True, blank=True) subtitle = TextField(null=True, blank=True) lesson_number = SmallIntegerField(blank=True, null=True) summary = CharField(max_length=100, null=True, blank=True) repetition_material = CharField(max_length=100, null=True, blank=True) audio_material = CharField(max_length=100, null=True, blank=True) comments_for_lesson = StreamField( [('advertisement', AdvertisementInline()), ('paragraph', RichTextBlock()), ('image', ImageChooserBlock()), ('document', DocumentViewerBlock()), ('html', RawHTMLBlock()), ('audio', AudioBlock()), ('video', VideoPlayerBlock()), ('post', PostBlock())], null=True, blank=True) body = StreamField([ ('advertisement', AdvertisementInline()), ('paragraph', RichTextBlock()), ('image', ImageChooserBlock()), ('document', DocumentViewerBlock()), ('html', RawHTMLBlock()), ('audio', AudioBlock()), ('video', VideoPlayerBlock()), ('post', PostBlock()), ], blank=True) dictionary = StreamField( [('advertisement', AdvertisementInline()), ('paragraph', RichTextBlock()), ('image', ImageChooserBlock()), ('document', DocumentViewerBlock()), ('html', RawHTMLBlock()), ('audio', AudioBlock()), ('video', VideoPlayerBlock()), ('translations', ListBlock(StructBlock([('word', RichTextBlock(required=True)), ('translation', RichTextBlock(required=True)) ]), template="blocks/transcriptions.html")), ('post', PostBlock())], null=True, blank=True) other_tabs = StreamField([('tab', TabBlock())], blank=True) def get_lesson_number(self): return self.slug.split("lecon-", 1)[1] has_own_topic = BooleanField(default=False) topic = OneToOneField(Topic, on_delete=SET_NULL, null=True, blank=True) def get_nav_root(self) -> Page: return get_nav_root(self) class Meta: permissions = (('listen_lesson', 'Can listen lesson'), )
class FeatureListBlock(StructBlock): features = ListBlock( StructBlock([("image", ImageChooserBlock(required=True)), ("title", RichTextBlock(features=RICHTEXT_ALL_FEATURES, required=True))])) class Meta: template = 'website/blocks/feature_list_block.html'
class JumpMenuBlock(StructBlock): # this block renders a list of indivual anchor links as a jump menu # used in conjunction with the Named Anchor block menu = ListBlock( StructBlock([('title', CharBlock()), ('menu_id', CharBlock())])) class Meta: icon = 'order-down' template = 'blocks/jump_menu_block.html' help_text = 'Add a list of named anchors that correspond to the Named achors below e.g. "document-name"'
class AccordionBlock(StructBlock): panels = ListBlock(StructBlock([ ('title', TextBlock(help_text='The headline to display when the accordion panel is closed.')), ('body', RichTextBlock(help_text='The inner content of this accordion panel. It is initially hidden.')) ], label='Panel')) class Meta: icon = 'emoji-scroll' template = 'blocks/accordion.html' help_text = 'Accordions are elements that help you organize and navigate multiple documents in a single container. They can be used for switching between items in the container.'
class SplitBannerSectionBlock(StructBlock): orientation = ChoiceBlock( choices=[ ('left', 'Left'), ('right', 'Right'), ], required=True, default='left', help_text='Choose which side of the image the text will appear on.') headline = TextBlock(help_text='Write a title for this section.', required=False) paragraph = RichTextBlock(icon='fa-paragraph', required=False) CTA = StructBlock([ ('text', CharBlock(help_text='What should the button say?', required=False)), ('link', URLBlock(help_text='Where should the button link to?', required=False)), ], help_text='An optional Call to Action button', blank=True) image_or_video = StructBlock( [ ('image', ImageChooserBlock(help_text='Choose a horizontal photo', required=False)), ('link', URLBlock(help_text='A youtube link to a video', required=False)), ], help_text= 'Either upload an image, or link to a video. If both fields are present, the video will take precident', blank=False, required=True) visible = BooleanBlock(default=True, required=False) class Meta: icon = 'fa-object-ungroup' template = 'blocks/split_banner_section.html' help_text = 'A dynamic block with a split red banner background and image'
class FourColumnBlock(StructBlock): """4 column block for price/service etc""" background = ChoiceBlock(choices=COLOUR_CHOICES, default="orange") block_title = CharBlock(classname='block title') block_subtitle = CharBlock(classname='block subtitle') first_column = StructBlock([ ('heading', CharBlock(classname="description")), ('subheading', CharBlock(classname="sub description")), ('bigtext', CharBlock(classname="bigtext")), ('toplist', ListBlock(CharBlock(classname='top list'))), ('bottomlist', ListBlock(CharBlock(classname='bottom list'))), ]) second_column = StructBlock([ ('heading', CharBlock(classname="description")), ('subheading', CharBlock(classname="sub description")), ('bigtext', CharBlock(classname="bigtext")), ('toplist', ListBlock(CharBlock(classname='top list'))), ('bottomlist', ListBlock(CharBlock(classname='bottom list'))), ]) third_column = StructBlock([ ('heading', CharBlock(classname="description")), ('subheading', CharBlock(classname="sub description")), ('bigtext', CharBlock(classname="bigtext")), ('toplist', ListBlock(CharBlock(classname='top list'))), ('bottomlist', ListBlock(CharBlock(classname='bottom list'))), ]) fourth_column = StructBlock([ ('heading', CharBlock(classname="description")), ('subheading', CharBlock(classname="sub description")), ('bigtext', CharBlock(classname="bigtext")), ('toplist', ListBlock(CharBlock(classname='top list'))), #Max number is 3 ('bottomlist', ListBlock(CharBlock(classname='bottom list'))), ]) class Meta: template = 'blocks/four_column_block.html' icon = 'placeholder' label = 'Four Columns'
class PanelListBlock(FlattenValueContext, StructBlock): panels = ListBlock( StructBlock([ ('left_panel', PanelBlock()), ('right_panel', PanelBlock()), ])) class Meta: template = 'wagtailnhsukfrontend/panel_list.html'
class CarouselBlock(StreamBlock): image = ImageChooserBlock() quotation = StructBlock([ ('text', TextBlock()), ('author', CharBlock()), ]) video = EmbedBlock() class Meta: icon = 'cogs'
class TopicPage(JanisPage): janis_url_page_type = "topic" description = models.TextField(blank=True) image = models.ForeignKey(TranslatedImage, null=True, blank=True, on_delete=models.SET_NULL, related_name='+') external_services = StreamField( [ ('link_en', StructBlock([ ('url', URLBlock()), ('title', CharBlock()), ], icon='link', label='Link [EN]')), ('link_es', StructBlock([ ('url', URLBlock()), ('title', CharBlock()), ], icon='link', label='Link [ES]')), ('link_ar', StructBlock([ ('url', URLBlock()), ('title', CharBlock()), ], icon='link', label='Link [AR]')), ('link_vi', StructBlock([ ('url', URLBlock()), ('title', CharBlock()), ], icon='link', label='Link [VI]')), ], verbose_name='External links to services', blank=True ) base_form_class = custom_forms.TopicPageForm content_panels = [ FieldPanel('title_en'), FieldPanel('title_es'), FieldPanel('title_ar'), FieldPanel('title_vi'), FieldPanel('description'), ImageChooserPanel('image'), StreamFieldPanel('external_services'), InlinePanel('topiccollections', label='Topic Collections this page belongs to'), ]
class SimpleSliderBlock(StructBlock): slides = StreamBlock([ ('slide', StructBlock([ ('caption', RichTextBlock(icon='fa-paragraph', required=False)), ('image_or_video', StructBlock( [ ('image', ImageChooserBlock(help_text='Choose a horizontal photo', required=False)), ('link', URLBlock(help_text='A youtube link to a video', required=False)), ], help_text= 'Either upload an image, or link to a video. If both fields are present, the video will take precident', blank=False, required=True)), ], help_text='A single slide', blank=False)), ], help_text='Add a slide to the slider', blank=True) def get_context(self, value, parent_context=None): context = super().get_context(value, parent_context=parent_context) def count_visible_slides(): count = 0 for slide in (value['slides']): count = count + 1 return count context['visible_slides'] = count_visible_slides() return context class Meta: icon = 'fa-object-group' template = 'blocks/simple_slider.html' help_text = 'A dynamic slideslow of multiple images or videos.'
class ImageGridBlock(StreamBlock): grid = StructBlock([ ('image', ImageChooserBlock(required=True, help_text='size: 800X450px')), ('caption', CharBlock(max_length=26, help_text='26 characters limit')), ('description', CharBlock(max_length=300, required=False, help_text='300 characters limit')), ('link', PageChooserBlock(required=False)) ]) class Meta: icon = 'image' template = 'blocks/image_grid_block.html'
class FeaturedPagesBlock(StructBlock): title = CharBlock() pages = ListBlock( StructBlock([ ('page', PageChooserBlock()), ('image', ImageChooserBlock()), ('text', TextBlock()), ('sub_text', CharBlock(max_length=100)), ])) class Meta: template = 'blocks/services/featured_pages_block.html'
class PanelListBlock(FlattenValueContext, StructBlock): panels = ListBlock( StructBlock([ ('left_panel', PanelBlock()), ('right_panel', PanelBlock()), ])) class Meta: icon = 'list-ul' template = 'wagtailnhsukfrontend/panel_list.html' help_text = 'This component is now deprecated and will be removed from future versions, please use the card group block'
class CarouselBlock(StructBlock): """ Custom `StructBlock` that allows the user to create a sequence of sub-blocks of different types, which can be mixed and reordered at will. """ image = ImageChooserBlock() quotation = StructBlock([('text', TextBlock()), ('author', CharBlock())]) video = EmbedBlock() class Meta: icon = "fa-images" template = "blocks/carousel_block.html"
class DefinitionList(StructBlock): class Meta: help_text = 'Displays a list of terms and definitions.' icon = 'list-ul' label = 'Definition list' form_template = 'publications/block_forms/custom_struct.html' template = 'publications/blocks/definition_list.html' definitions = ListBlock(StructBlock([ ('term', CharBlock()), ('definition', TextBlock()), ]), icon='list-ul')
class LogosBlock(StructBlock): title = CharBlock() intro = CharBlock() logos = ListBlock( StructBlock(( ('image', ImageChooserBlock()), ('link_page', PageChooserBlock(required=False)), ('link_external', URLBlock(required=False)), ))) class Meta: icon = 'site' template = 'blocks/services/logos_block.html'