class DemoStreamBlock(StreamBlock): h2 = CharBlock(icon="title", classname="title") h3 = CharBlock(icon="title", classname="title") h4 = CharBlock(icon="title", classname="title") intro = RichTextBlock(icon="pilcrow") paragraph = RichTextBlock(icon="pilcrow") aligned_image = ImageBlock(label="Aligned image", icon="image") pullquote = PullQuoteBlock() aligned_html = AlignedHTMLBlock(icon="code", label='Raw HTML') document = DocumentChooserBlock(icon="doc-full-inverse")
class TeamBlock(StructBlock): title = CharBlock(help_text='Title for the team block') description = CharBlock(help_text='Team description') @property def get_team(): team_members = Person.objects.live().filter(person_type='T') class Meta: icon = "fa-quote-left" template = "blocks/team_block.html"
class SidebarCallOutBlock(StructBlock): title = CharBlock() body = RichTextBlock(required=False) icon = CharBlock(required=False, help_text='Text block passed as the icon selected. ' 'Choose between Ionic Icons or FontAwesome.') links = ListBlock(LinkBlock(), required=False) class Meta: icon = 'radio-empty' template = 'blocks/sidebar_callout.html'
class ImageBlock(StructBlock): """ Custom `StructBlock` for utilizing images with associated caption and attribution data """ image = ImageChooserBlock(required=True) caption = CharBlock(required=False) attribution = CharBlock(required=False) class Meta: icon = 'image'
class ParentMenuBlock(StructBlock): parent_link_text = CharBlock() parent_internal_link = PageChooserBlock(blank=True, required=False, icon='fa-link') parent_external_link = CharBlock(blank=True, required=False, icon='fa-link') child_link = CardsBlock(ChildMenuBlock()) class Meta: template = 'tags/menuitem_parent.html'
class BigTeaserBlock(StructBlock): title = CharBlock(required=True) subtitle = CharBlock(required=False) picture = ImageChooserBlock() text = RichTextBlock() external_link = URLBlock( required=False, help_text="Will be ignored if an internal link is provided") internal_link = PageChooserBlock( required=False, help_text='If set, this has precedence over the external link.') from_date = DateBlock(required=False) to_date = DateBlock(required=False) class Meta: icon = 'fa fa-list-alt' template = 'blocks/big_teaser_block.html' def __init__(self, wideimage=False, local_blocks=None, **kwargs): super().__init__(local_blocks=local_blocks, **kwargs) self.wideimage = wideimage def get_context(self, value, parent_context=None): context = super(BigTeaserBlock, self).get_context(value, parent_context=parent_context) context['super_title'] = value.get('title') image = value.get('picture') rendition = image.get_rendition('max-800x800') context['image'] = {'url': rendition.url, 'name': image.title} if value.get('internal_link'): context['href'] = value.get('internal_link').url else: context['href'] = value.get('external_link') if context['href']: context['text_right_link'] = True context['text_right_link_text'] = 'Learn more' context.update({ 'title': value.get('subtitle'), 'description': value.get('text'), 'divider': True, 'calendaricon': True, }) if value.get('from_date') and value.get('to_date'): context['date'] = '"{} to {}"'.format( formats.date_format(value.get('from_date'), "SHORT_DATE_FORMAT"), formats.date_format(value.get('to_date'), "SHORT_DATE_FORMAT")) context['wideimage'] = self.wideimage return context
class IframeBlock(Accessible, StructBlock): iframe_url = URLBlock(required=True, icon="arrow-right") iframe_width = CharBlock(required=False) iframe_height = CharBlock(required=False) iframe_id = CharBlock(required=False) iframe_html = RawHTMLBlock(required=False) fallback_image = ImageBlock() class Meta: icon = "site" template = 'longform/blocks/html.html' accessible_template = "longform/blocks/accessible_html.html"
class StoryBlock(StreamBlock): h2 = CharBlock(icon="title", classname="title") h3 = CharBlock(icon="title", classname="title") h4 = CharBlock(icon="title", classname="title") intro = RichTextBlock(icon="pilcrow") paragraph = RichTextBlock(icon="pilcrow") aligned_image = ImageBlock(label="Aligned image") wide_image = WideImage(label="Wide image") bustout = BustoutBlock() pullquote = PullQuoteBlock() raw_html = RawHTMLBlock(label='Raw HTML', icon="code") embed = EmbedBlock(icon="code")
class StoryBlock(StreamBlock): h2 = CharBlock(icon="title", classname="h2 title") h3 = CharBlock(icon="title", classname="h3 title") h4 = CharBlock(icon="title", classname="h4 title") paragraph = StoryTextBlock(icon="pilcrow") image = ImageBlock(label="image") pullquote = PullQuoteBlock() raw_html = RawHTMLBlock(label='Raw HTML', icon="code") embed = EmbedBlock(icon="code") class Meta: template = "blog/blocks/storyblock.html"
class ShortHeroBlock(StructBlock): image = ImageChooserBlock(required=True, help_text='The image serving as the header ' 'image for the page. Shorter ' 'than the carousel, intended ' 'for sub pages.') color = ChoiceBlock([('light', 'Light'), ('dark', 'Dark')]) title = CharBlock() subtitle = CharBlock(required=False) class Meta: icon = 'image' template = 'blocks/short_hero.html'
class SoundCloudBlock(StructBlock): track_id = CharBlock(required=False) playlist_id = CharBlock(required=False) auto_play = BooleanBlock(required=False) hide_related = BooleanBlock(required=False) show_comments = BooleanBlock(required=False) show_user = BooleanBlock(required=False) show_reposts = BooleanBlock(required=False) visual = BooleanBlock(required=False) class Meta: icon = 'media' template = 'blocks/soundcloud.html'
class ChildMenuBlock(StructBlock): link_text = CharBlock() internal_link = PageChooserBlock(blank=True, required=False, icon='fa-link') external_link = CharBlock(blank=True, required=False, icon='fa-link') # Above: Note we don't use a URLBlock because we need to use arbitrary # strings for internal links (e.g. /artists). This is probably a terrible # idea and there's likely a better solution, but this works... class Meta: template = 'tags/menuitem_child.html'
class PostStreamBlock(StreamBlock): """ Defines the ``StreamBlock`` used in the ``BlogPage`` model. This adds a dynamic behavior when writing the body of a new blog page. It includes: - h2 and h2 titles - a paragraph - an image that could be aligned on the left, on the right, in the center or with a full width - a quote with a proper attribution """ h2 = CharBlock(icon="title") h3 = CharBlock(icon="title") paragraph = RichTextBlock(icon="pilcrow") aligned_image = ImageBlock(label=_("Aligned image"), icon="image") pullquote = PullQuoteBlock(icon="openquote")
class PressStreamBlock(StreamBlock): heading = CharBlock(icon="title", classname="title") subheading = CharBlock(icon="title", classname="title") text = RichTextBlock(icon="pilcrow", features=['bold', 'italic', 'ul', 'ol', 'link']) image = ImageChooserBlock(template='press/blocks/image.html') image_gallery = ListBlock(CaptionedImageBlock(), icon="image", label="Image Slideshow") #image_or_video_gallery = ListBlock(CarouselBlock(), icon="image", label="Image or Video Slideshow") video = EmbedBlock() project = PageChooserBlock(target_model='design.ProjectPage', template='design/blocks/related_project.html') pullquote = BlockQuoteBlock() document = DocumentChooserBlock(icon="doc-full-inverse")
class HomeStreamBlock(StreamBlock): h2 = CharBlock(icon="title", classname="title") h3 = CharBlock(icon="title", classname="title") h4 = CharBlock(icon="title", classname="title") intro = RichTextBlock(icon="pilcrow") paragraph = RichTextBlock(icon="pilcrow") aligned_image = ImageBlock(label="Aligned image", icon="image") pullquote = PullQuoteBlock() aligned_html = AlignedHTMLBlock(icon="code", label='Raw HTML') document = DocumentChooserBlock(icon="doc-full-inverse") one_column = OneColumnBlock() two_columns = TwoColumnBlock() three_columns = ThreeColumnBlock() embedded_video = EmbedBlock(icon="media") google_map = GoogleMapBlock()
class WPPage(Page): """ This class will hold pages, similar to WordPress' post_type of 'page'. Posts will inherit from this class, adding additional fields needed. """ class Meta: verbose_name = "Page" content = StreamField([ ('heading', CharBlock(classname="full title")), ('paragraph', TextBlock()), ('image', ImageChooserBlock()), ('url', URLBlock()), ('code', CodeBlock()), ]) tags = ClusterTaggableManager(through=WPPageTag, blank=True) modified = models.DateTimeField("Page Modified", null=True) search_fields = Page.search_fields + ( index.SearchField('title'), index.SearchField('content'), ) content_panels = Page.content_panels + [ FieldPanel('tags'), StreamFieldPanel('content'), ] def save(self, *args, **kwargs): self.modified = timezone.now() super(WPPage, self).save(*args, **kwargs) def __str__(self): return 'ID %s: %s' % (str(self.pk), self.title)
class QuoteBlock(StructBlock): quote = TextBlock("quote title") attribution = CharBlock() class Meta: icon = 'openquote' template = 'blog/blocks/quote.html'
class FormFieldBlock(StructBlock): field_label = CharBlock(label=_('Label')) help_text = TextBlock(required=False, label=_('Help text')) field_class = forms.CharField widget = None def get_slug(self, struct_value): return force_text(slugify(unidecode(struct_value['field_label']))) def get_field_class(self, struct_value): return self.field_class def get_widget(self, struct_value): return self.widget def get_field_kwargs(self, struct_value): kwargs = { 'label': struct_value['field_label'], 'help_text': struct_value['help_text'], 'required': struct_value.get('required', False) } if 'default_value' in struct_value: kwargs['initial'] = struct_value['default_value'] form_widget = self.get_widget(struct_value) if form_widget is not None: kwargs['widget'] = form_widget return kwargs def get_field(self, struct_value): return self.get_field_class(struct_value)( **self.get_field_kwargs(struct_value))
class RevealBlock(StructBlock): summary = CharBlock() variant = ChoiceBlock(label='Variant', choices=( ('inline', 'Inline'), ('block', 'Block'), )) def __init__(self, *args, **kwargs): children_stream_block = [text.as_tuple()] # if compact == True, don't allow any other sub-component if not kwargs.pop('compact', False): # importing components here avoids circular dependency from .callout import callout_compact from .gallery import gallery children_stream_block += [ callout_compact.as_tuple(), gallery.as_tuple() ] # configure sub-components local_blocks = kwargs.get('local_blocks', []) local_blocks.append( ('children', StreamBlock(children_stream_block, label='Content'))) kwargs['local_blocks'] = local_blocks super().__init__(*args, **kwargs)
class LinkBlock(StructBlock): title = CharBlock(required=True) picture = ImageChooserBlock(required=False) text = RichTextBlock(required=False) link = URLBlock(required=False) date = DateBlock(required=False) class Meta: classname = 'link' icon = 'fa fa-external-link' template = 'widgets/page-teaser-wide.html' def get_context(self, value, parent_context=None): context = super(LinkBlock, self).get_context(value, parent_context=parent_context) context['arrow_right_link'] = True context['title'] = value.get('title') context['description'] = value.get('text') context['date'] = value.get('date') image = value.get('picture') if image: rendition = image.get_rendition('fill-640x360-c100') context['image'] = {'url': rendition.url, 'name': image.title} if value.get('link'): context['href'] = value.get('link') return context
class ProtocolBlock(StructBlock): complete_pdf = DocumentChooserBlock(label='Complete PDF') pdfs = ListBlock(PDFBlock(), label='Chapter PDFs') image = ImageBlock() version = CharBlock() class Meta: icon = 'fa fa-newspaper-o' template = 'blocks/protocol_block.html' def get_context(self, value, parent_context=None): context = super(ProtocolBlock, self).get_context(value, parent_context=parent_context) context['links'] = [] for pdf in value.get('pdfs'): context['links'] += [{ 'fontawesome': 'file-pdf-o', 'href': pdf.get('file').url, 'text': pdf.get('description') }] try: rendition = value.get('image').get_rendition('max-500x500') context['image'] = { 'url': rendition.url, 'name': value.get('image').title } except: pass return context
class PersonBlock(StructBlock): photo = ImageChooserBlock(required=True) name = CharBlock() biography = RichTextBlock() class Meta: icon = 'user'
class NumberFieldBlock(OptionalFormFieldBlock): default_value = CharBlock(required=False, label=_('Default value')) widget = forms.NumberInput class Meta: label = _('Number field')
class ImageTitleTextBlock(StructBlock): image = ImageChooserBlock() title = CharBlock() text = RichTextBlock(features=['bold', 'italic', 'ul', 'ol', 'link']) class Meta: template = 'core/blocks/image_title_text.html'
class TabBlock(StructBlock): name = CharBlock() content = GenericContentStreamBlock(local_blocks=[('columns', RowBlock())]) class Meta: form_template = 'common/block_forms/tab.html'
class StatementBlock(StructBlock): title = CharBlock() subtitles = ListBlock(CharBlock(required=False), required=False) call_to_action = ListBlock(CallToActionBlock(), required=False, help_text='Large button to direct user to ' 'specific content. Last element ' 'has greatest emphasis.') signup_form = BooleanBlock(required=False, help_text='Check to display an email ' 'signup form in this frame.') caveats = ListBlock(CharBlock(required=False), required=False) class Meta: icon = 'pilcrow' template = 'blocks/statement.html'
class TitleTextImageListBlock(StructBlock): image_list = ListBlock(TitleTextImageBlock()) title = CharBlock() text = RichTextBlock(features=['bold', 'italic', 'ul', 'ol', 'link']) class Meta: template = 'core/blocks/title_text_imagelist.html'
class ServicePanel(StructBlock): services = ListBlock(Service) title = CharBlock(help_text='title for the block') class Meta: icon = "fa-quote-left" template = "blocks/services_panel.html"
class ImageGridItem(StructBlock): image = ImageChooserBlock(required=True) hyperlink = URLBlock(required=False) caption = CharBlock(required=False, max_length=200) class Meta: form_classname = "fieldname-image_grid_item"
class ProcessPanel(StructBlock): title = CharBlock(help_text='title for the panel') processes = ListBlock(ProcessBlock) class Meta: icon = "fa-quote-left" template = "blocks/process.html"