class Section(DiscoverUniBasePage): intro = RichTextField(blank=True) subsections = StreamField([ ('subsection', blocks.StructBlock([ ('subsection_title', blocks.TextBlock()), ('subsection_content', blocks.RichTextBlock(features=['h3', 'h4', 'bold', 'italic', 'embed', 'link', 'document-link', 'image', 'ol', 'ul', 'hr', 'blockquote'])) ])) ]) related_links_title = TextField(blank=True) related_links = StreamField([ ('links', blocks.PageChooserBlock(required=False)), ], blank=True) lateral_link_title = TextField(blank=True) lateral_links = StreamField([ ('links', blocks.PageChooserBlock(required=False)), ], blank=True) content_panels = DiscoverUniBasePage.content_panels + [ FieldPanel('intro'), StreamFieldPanel('subsections'), FieldPanel('related_links_title'), StreamFieldPanel('related_links'), FieldPanel('lateral_link_title'), StreamFieldPanel('lateral_links') ] @property def has_lateral_links(self): return self.lateral_links or self.lateral_link_title def get_breadcrumbs(self): return self.get_ancestors().live()[1:]
class BootstrapCommon4ColumnBlock(blocks.StructBlock): item = blocks.ListBlock( blocks.StructBlock([ ('heading1', blocks.CharBlock(required=False)), ('paragraph1', blocks.RichTextBlock(required=False)), ('image1', ImageChooserBlock(required=False)), ('link1', blocks.PageChooserBlock(required=False)), ('heading2', blocks.CharBlock(required=False)), ('paragraph2', blocks.RichTextBlock(required=False)), ('image2', ImageChooserBlock(required=False)), ('link2', blocks.PageChooserBlock(required=False)), ('heading3', blocks.CharBlock(required=False)), ('paragraph3', blocks.RichTextBlock(required=False)), ('image3', ImageChooserBlock(required=False)), ('link3', blocks.PageChooserBlock(required=False)), ('heading4', blocks.CharBlock(required=False)), ('paragraph4', blocks.RichTextBlock(required=False)), ('image4', ImageChooserBlock(required=False)), ('link4', blocks.PageChooserBlock(required=False)) ])) class Meta: template = 'bootstrap_common/blocks/grid/bootstrap_common_4_column_block.html' label = '4 Column' icon = 'grip'
class SectionBlock(blocks.StructBlock): section = blocks.PageChooserBlock(label="section_index") featured_pages = blocks.ListBlock( blocks.PageChooserBlock(label="featured_page")) class Meta: icon = 'pick' label = 'Featured section' template = 'home/blocks/section_block.html'
class HeroStaticLeftBlock(blocks.StructBlock): background_image = ImageChooserBlock() title = blocks.CharBlock(required=False) headline = blocks.CharBlock() body = blocks.TextBlock() page = blocks.PageChooserBlock(required=False) page_secodary = blocks.PageChooserBlock(required=False) external_url = blocks.URLBlock(required=False) class Meta: template = 'main/blocks/hero_static_left.html'
class HeroCarouselBlock(blocks.StructBlock): headline = blocks.CharBlock() tiles = blocks.ListBlock( blocks.StructBlock([ ('background_image', ImageChooserBlock()), ('headline', blocks.RichTextBlock(features=['bold', 'italic'], required=False)), ('page', blocks.PageChooserBlock()), ('secondary_page', blocks.PageChooserBlock(required=False)), ]), ) class Meta: template = 'main/blocks/hero_carousel.html'
class WhiteHeaderWithButton(blocks.StreamBlock): header_text = blocks.CharBlock(classname="header text") button_text = blocks.CharBlock(classname="header text") button_url = blocks.PageChooserBlock(classname="internal url") class Meta: template = 'universal_page/blocks/white_header_with_button.html'
class Link(blocks.StructBlock): link_text = blocks.CharBlock( max_length=50, default="More Detail", ) internal_page = blocks.PageChooserBlock(required=False, ) external_link = blocks.URLBlock(required=False, ) class Meta: value_class = LinkValue def clean(self, value): internal_page = value.get("internal_page") external_page = value.get("external_link") errors = {} if internal_page and external_page: errors["internal_page"] = ErrorList([ "Both of these fields cannot be filled. Please select or enter one option" ]) errors["external_link"] = ErrorList([ "Both of these fields cannot be filled. Please select or enter one option" ]) elif not internal_page and not external_page: errors["internal_page"] = ErrorList([ "Please select a page or enter a URL for one of these options" ]) errors["external_link"] = ErrorList([ "Please select a page or enter a URL for one of these options" ]) if errors: raise ValidationError("Validation error in your link", params=errors) return super().clean(value)
class TeaserBlock(CollapsibleFieldsMixin, blocks.StructBlock): heading = blocks.CharBlock(**heading_block_kwargs) page = blocks.PageChooserBlock() caption = blocks.CharBlock( required=False, help_text=_( "An optional caption, which is displayed below the block's content. " "Overwrites the page title of the linked page."), ) description = blocks.TextBlock( required=False, help_text=_( "An optional description, which is displayed below the block's caption. " "Overwrites the page description of the linked page."), ) fields = [ "page", { "label": _("Card"), "fields": ["heading", "align", "caption", "description"] }, ] class Meta: icon = "link" template = "xr_pages/blocks/teaser.html" value_class = XrStructValue
class TwoColumnBlock(blocks.StructBlock): title = blocks.CharBlock(required=False, max_length=255) color = blocks.CharBlock(required=True, max_length=255) left_column = blocks.StreamBlock([ ('heading', blocks.CharBlock(classname="full title")), ('paragraph', blocks.RichTextBlock()), ('image', ImageChooserBlock()), ('embedded_video', EmbedBlock()), ], icon='arrow-left', label='Left column content') right_column = blocks.StreamBlock([ ('heading', blocks.CharBlock(classname="full title")), ('paragraph', blocks.RichTextBlock()), ('image', ImageChooserBlock()), ('button', blocks.PageChooserBlock(classname="btn")), ('embedded_video', EmbedBlock()), ], icon='arrow-right', label='Right column content') class Meta: template = 'home/two_column_block.html' icon = 'placeholder' label = 'Two Columns'
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 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 = ("patterns/molecules/navigation/blocks/menu_item.html", )
class CardBlock(blocks.StructBlock): link = blocks.PageChooserBlock(help_text="Page to link to", ) card_header = blocks.CharBlock( max_length=30, default="", help_text="Title for card", ) card_text = blocks.TextBlock( max_length=400, help_text="Short desription of page.", required=False, blank=True, null=True, ) button_text = blocks.CharBlock( max_length=20, required=False, default="View", help_text="Text to appear on link button", ) card_image = ImageChooserBlock(help_text="Image to display") class Meta: template = "streams/card.html" icon = "fa-id-card-o" label = "Card link" help_text = "Create a card to link to another page."
class Migration(migrations.Migration): dependencies = [ ('oc_core', '0001_initial'), ] operations = [ migrations.CreateModel( name='Navigation', fields=[ ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('title', models.CharField(max_length=255)), ('slug', models.SlugField(max_length=255)), ('navigation', fields.StreamField( [(b'menu_block', blocks.StructBlock( [(b'title', blocks.CharBlock()), (b'menu_items', blocks.ListBlock( blocks.StreamBlock([ (b'link_external', blocks.StructBlock( [(b'caption', blocks.CharBlock()), (b'url', blocks.CharBlock())])), (b'link_page', blocks.PageChooserBlock()) ])))]))], blank=True)), ], ), ]
class PolicyLinks(blocks.StructBlock): link_name = blocks.TextBlock(required=True, help_text="add your link name") link_page = blocks.PageChooserBlock(required=True, help_text="choose internal page") link_tab_chooser = LinkTabChooserBlock(required=True, help_text="choose either open image on new or current tab") class Meta: icon = "link"
class SlideBlock(BaseSlideBlock): """A basic slide to be used in a carousel block""" title = blocks.CharBlock(required=True) heading = blocks.CharBlock(required=False, default='', label='Section heading') description = blocks.RichTextBlock(required=False) url = blocks.URLBlock(required=False) page = blocks.PageChooserBlock(required=False, help_text='Overrides url') image = ImageChooserBlock(required=True) caption = blocks.CharBlock(required=False, label='Image caption') def get_context(self, value, parent_context=None): context = super().get_context(value, parent_context=parent_context) context = BaseSlideBlock.get_default_values(value, context) if 'page' in value and value['page'] is not None: context['url'] = value['page'].url else: context['url'] = value['url'] context['image'] = value['image'] context['caption'] = value['caption'] return context class Meta: template = 'cms/blocks/slide_block.html'
class CardBlock(blocks.StructBlock): title = blocks.CharBlock(required=True, help_text="Add Your Title") cards = blocks.ListBlock( blocks.StructBlock( [ ("image", ImageChooserBlock(required=True)), ("title", blocks.CharBlock(required=True, max_length=40)), ("text", blocks.TextBlock(required=True, max_length=200)), ("button_page", blocks.PageChooserBlock(required=False)), ("button_url", blocks.URLBlock(required=False)), ] ) ) class Meta: template = "streams/card_block.html" icon = "placeholder" label = "Staff"
class TimelineItemBlock(blocks.StructBlock): timeline_item = blocks.ListBlock( blocks.StructBlock([ ('date', blocks.CharBlock( required=True, help_text="enter the date that the event happened on")), ('title', blocks.CharBlock(required=True, help_text="name the event here")), ('image', ImageChooserBlock( required=False, help_text="insert an image to go with your event (optional)") ), ('text', blocks.TextBlock(required=True, help_text="describe the event here")), ('item_page', blocks.PageChooserBlock( required=False, help_text="use if you want to link item to another page")), ('item_url', blocks.URLBlock( required=False, help_text="use if you want to go to external links")), ])) class Meta: # noqa template = "streams/timeline_item_block.html" icon = "edit" label = "Timeline Item"
class CardBlock(blocks.StructBlock): subtitle = blocks.CharBlock(required=False, max_length=50, help_text="Add your subtitle") title = blocks.CharBlock(required=False, max_length=50, help_text="Add your title") cards = blocks.ListBlock( blocks.StructBlock([ ("image", ImageChooserBlock(required=True)), ("title", blocks.CharBlock(required=True, max_length=40)), ("text", blocks.TextBlock(required=True, max_length=200)), ("button_page", blocks.PageChooserBlock(required=False)), ("button_url", blocks.URLBlock( required=False, help_text= "If the button page above is selected, that will be used first." )), ], icon='list-ul')) class Meta: template = "streams/card_block.html" icon = "form" label = "Cards"
class BootstrapGrayscaleMastheadBlock(blocks.StructBlock): heading = blocks.CharBlock(required=False) heading_image = ImageChooserBlock(required=False) subheading = blocks.RichTextBlock(required=False) background_image = ImageChooserBlock() button_text = blocks.CharBlock(required=False) button_link = blocks.PageChooserBlock(required=False) COLOR_CHOICES = ( ('', 'Light'), ('dark', 'Dark'), ('theme', 'Theme') ) background_theme = blocks.ChoiceBlock(choices=COLOR_CHOICES, required=False) def get_context(self, value, parent_context=None): context = super().get_context(value, parent_context=parent_context) if value['background_theme'] == 'dark': context['value']['btn_color'] = 'btn-light' context['value']['txt_color'] = '#f8f9fa' elif value['background_theme'] == 'theme': context['value']['btn_color'] = 'btn-primary' context['value']['txt_color'] = '#f8f9fa' else: context['value']['btn_color'] = 'btn-dark' context['value']['txt_color'] = '#050505' return context class Meta: app_label = 'bootstrap_grayscale' template = 'bootstrap_grayscale/blocks/grayscale_masthead_block.html' icon = 'title'
class ArtBlock(blocks.StructBlock): gallery_block_title = blocks.RichTextBlock(required=True) art_cards = blocks.ListBlock( blocks.StructBlock([ ('title_of_picture', blocks.CharBlock(required=True, max_length=40, help_text="Name of Art Piece")), ('image', ImageChooserBlock(required=True)), ('picture_description', blocks.RichTextBlock(required=True, max_length=200)), ('button_to_site_page', blocks.PageChooserBlock(required=False)), ('button_to_external_URL', blocks.URLBlock( required=False, help_text='Here, you can link to an external website')), ('button_text', blocks.CharBlock( required=True, max_length=25, help_text='Text that will be displayed on the button')), ])) class Meta: template = "blocks/art_block.html" icon = 'pencil' label = 'Art cards'
class FeaturedContent(blocks.StructBlock): heading = blocks.CharBlock() body = blocks.RichTextBlock() 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 = VideoPlayer(required=False) class Meta: template = '_includes/organisms/featured-content.html' icon = 'doc-full-inverse' label = 'Featured Content' classname = 'block__flush' value_class = FeaturedContentStructValue class Media: js = ['featured-content-module.js']
class LimitedRichTextBlock(blocks.StructBlock): title = blocks.CharBlock(max_length=250) body = blocks.RichTextBlock(features=["bold", "italic", "ol"]) another_page = blocks.PageChooserBlock() external_url = blocks.URLBlock() def clean(self, value): errors = {} title_words = value.get("title").lower().split() if "the" in title_words: errors["title"] = ErrorList(['Your title must not include the word "the".']) if any(word in str(value.get("body")).lower() for word in title_words): errors["body"] = ErrorList( ["Body should not include any words used in the title."] ) if errors: raise ValidationError("Validation error in StructBlock", params=errors) return super().clean(value) class Meta: template = "home/blocks/limited_richtext_block.html" label = "Limited RichText"
class BootstrapBusinessCasualMastheadBlock(blocks.StructBlock): heading = blocks.CharBlock() subheading = blocks.RichTextBlock() background_image = ImageChooserBlock() masthead_image = ImageChooserBlock( help_text='Make sure this is a seamless image.') upper_text = blocks.TextBlock() lower_text = blocks.TextBlock() button_text = blocks.CharBlock(required=False) button_link = blocks.PageChooserBlock(required=False) COLOR_CHOICES = (('', 'Light'), ('dark', 'Dark'), ('theme', 'Theme')) background_theme = blocks.ChoiceBlock(choices=COLOR_CHOICES, required=False) def get_context(self, value, parent_context=None): context = super().get_context(value, parent_context=parent_context) if value['background_theme'] == 'dark': context['value']['btn_color'] = 'btn-light' context['value']['txt_color'] = '#f8f9fa' elif value['background_theme'] == 'theme': context['value']['btn_color'] = 'btn-primary' context['value']['txt_color'] = '#f8f9fa' else: context['value']['btn_color'] = 'btn-dark' context['value']['txt_color'] = '#050505' return context class Meta: app_label = 'bootstrap_business_casual' template = 'bootstrap_business_casual/blocks/bootstrap_business_casual_masthead_block.html'
class CourseFinderResults(DiscoverUniBasePage): page_order = 9 header = TextField(blank=True) related_links_title = TextField(blank=True) related_links = StreamField([ ('links', blocks.PageChooserBlock()), ]) content_panels = DiscoverUniBasePage.content_panels + [ FieldPanel('header', classname="full"), FieldPanel('related_links_title'), StreamFieldPanel('related_links', classname="full"), ] def get_context(self, request): context = super(CourseFinderResults, self).get_context(request) context['search_url'] = self.get_search_url() context['course_finder_url'] = get_page_for_language( self.get_language(), CourseFinderChooseCountry.objects.all()).url context['institutions_list'] = InstitutionList.get_options()[ self.get_language()] return context def get_search_url(self): if self.get_language() == enums.languages.WELSH: return "/%s/course-finder/results/" % self.get_language() return '/course-finder/results/'
class CardBlock(blocks.StructBlock): """Cards with image and text and button(s).""" title = blocks.CharBlock(required=True, help_text="Add your title") cards = blocks.ListBlock( blocks.StructBlock([ ("image", ImageChooserBlock(required=True)), ("title", blocks.CharBlock(required=True, max_length=40)), ("text", blocks.TextBlock(required=True, max_length=200)), ("button_page", blocks.PageChooserBlock(required=False)), ( "button_url", blocks.URLBlock( required=False, help_text= "If the button page above is selected, that will be used first.", # noqa ), ), ])) class Meta: # noqa template = "streams/card_block.html" icon = "placeholder" label = "Staff Cards"
class ServicesCard(blocks.StructBlock): """ Services cards """ # blocks.StructBlock( # [ # ('image', images_blocks.ImageChooserBlock(required=True)), # ('title', blocks.CharBlock(max_length=48)), # ('text', blocks.TextBlock(max_length=256)), # ('button_page', blocks.PageChooserBlock(required=False)), # ('button_url', blocks.PageChooserBlock(required=False, helptext="button page has priority")), # ] # ) image = images_blocks.ImageChooserBlock( required=True, help_text= "Please limit the image size to max 40KiB, recommended dimensions = 512x288px" ) title = blocks.CharBlock(max_length=48, required=False) sub_title = blocks.CharBlock(max_length=48, required=False) text = blocks.TextBlock(max_length=1024, required=False) button = blocks.PageChooserBlock(required=False) button_text = blocks.CharBlock(max_length=32, required=True, default="Lear more") # ('button_url', blocks.PageChooserBlock(required=False, helptext="button page has priority")), class Meta: template = 'streams/service_block.html' icon = 'placeholder' label = 'Services'
class InternalOrExternalLinkBlock(blocks.StructBlock): internal_link = blocks.PageChooserBlock( required=False, label='Internal link', ) external_link = blocks.CharBlock( required=False, max_length=255, label='External link', ) class Meta: icon = 'redirect' def get_api_representation(self, value, context=None): """Standardise the API output so the consumer doesn't have to worry about whether a link is internal or external""" original_retval_dict = super().get_api_representation(value, context=context) retval = None # If there's both an internal link and an exernal link configured, the internal # one takes priority. Also, we only want to return flat URL, not dictionary with # 'internal_link' or 'external_link' keys, or even a 'url' key if ('internal_link' in original_retval_dict and isinstance(original_retval_dict['internal_link'], int)): # Correct this to be a full URL, not a page ID retval = value['internal_link'].specific.get_url( ) # Note, this lacks the port number when used locally elif 'external_link' in original_retval_dict: retval = value['external_link'] return retval
class HorizontalCardsBlock(blocks.StructBlock): """ Cards with image and title else """ # title = blocks.CharBlock(required=False, help_text='Add a title for the cards if necessary, ') cards = blocks.ListBlock( blocks.StructBlock([ ('image', images_blocks.ImageChooserBlock( required=True, help_text='Use a 400x300px picture,')), ('title', blocks.CharBlock(max_length=48, required=False)), ('subtitle', blocks.TextBlock(max_length=48, required=False)), ('text', blocks.TextBlock(max_length=256, required=False)), ('link_page', blocks.PageChooserBlock(required=False)), ('link_url', blocks.URLBlock(required=False)), ('link_text', blocks.CharBlock(max_length=32, required=False)), ('reverse', blocks.BooleanBlock(required=False, help_text="Place image to the right?")) ])) class Meta: template = 'streams/fullwidthcards_block.html' icon = 'placeholder' label = 'Full width cards'
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 Link(blocks.StructBlock): link_text = blocks.CharBlock(max_length=50, default='More Details') internal_page = blocks.PageChooserBlock(required=False) external_link = blocks.URLBlock(required=False) class Meta: value_class = LinkValue def clean(self, value): internal_page = value.get('internal_page') external_link = value.get('external_link') errors = {} if internal_page and external_link: errors['external_link'] = ErrorList( ['Both of these fields can not be filled out!']) errors['internal_page'] = ErrorList( ['Both of these fields can not be filled out!']) elif not internal_page and not external_link: errors['external_link'] = ErrorList([ 'Please select a page or enter a link for only one of these options.' ]) errors['internal_page'] = ErrorList([ 'Please select a page or enter a link for only one of these options.' ]) if errors: raise ValidationError('Validation error in your link', params=errors) return super().clean(value)