Ejemplo n.º 1
0
    def test_custom_editor_in_rich_text_block(self):
        block = RichTextBlock(editor='custom')

        form_html = block.render_form(block.to_python("<p>hello</p>"), 'body')

        # Check that the custom plugin options are being passed in the hallo initialiser
        self.assertIn('makeHalloRichTextEditable("body", {"halloheadings": {"formatBlocks": ["p", "h2"]}});', form_html)
Ejemplo n.º 2
0
    def test_features_list_on_rich_text_block(self):
        block = RichTextBlock(features=['blockquote', 'embed', 'made-up-feature'])

        form_html = block.render_form(block.to_python("<p>hello</p>"), 'body')

        # Check that the custom plugin options are being passed in the hallo initialiser
        self.assertIn('"halloblockquote":', form_html)
        self.assertIn('"hallowagtailembeds":', form_html)
        self.assertNotIn('"hallolists":', form_html)
        self.assertNotIn('"hallowagtailimage":', form_html)

        # check that media (js/css) from the features is being imported
        media_html = str(block.media)
        self.assertIn('testapp/js/hallo-blockquote.js', media_html)
        self.assertIn('testapp/css/hallo-blockquote.css', media_html)
        # check that we're NOT importing media for the default features we're not using
        self.assertNotIn('wagtaildocs/js/hallo-plugins/hallo-wagtaildoclink.js', media_html)
Ejemplo n.º 3
0
class HomePagesStreamBlock(StreamBlock):
    paragraph = RichTextBlock(icon="pilcrow", label=u'段落')
    image_list_4 = FourColImageListBlock(icon="image", label=u"四列图片")
    image_list_3 = ThreeColImageListBlock(icon="image", label=u"三列图片")
    image_list_2 = TwoColImageListBlock(icon="image", label=u"两列图片")
    link_list = LinkList(icon="link", label=u"链接列表")
    html = RawHTMLBlock(icon="code", label=u'HTML代码')
    overlap = OverlapDesign(icon="pilcrow", label=u"大小标题模块")
    quote = TextBlock(icon = "openquote", label=u'引用')
    image_list_5 = HPFiveColImageListBlock(icon="image", label=u"主页五列图片")
    carousel = Carousel(icon="image", label=u"幻灯片图片")
Ejemplo n.º 4
0
class AccordionBlock(StructBlock):
    class Meta:
        icon = "arrow-down-big"
        template = "blocks/accordion_block.html"

    accordion_group_title = TextBlock(required=False, blank=True, default="")
    accordion_items = ListBlock(
        StructBlock([
            ('accordion_title', CharBlock(required=True)),
            ('accordion_content', RichTextBlock(required=True)),
        ]))
Ejemplo n.º 5
0
class DefaultStreamPage(Page):
    body = StreamField([
        ('text', CharBlock()),
        ('rich_text', RichTextBlock()),
        ('image', ImageChooserBlock()),
    ], default='')

    content_panels = [
        FieldPanel('title'),
        StreamFieldPanel('body'),
    ]
Ejemplo n.º 6
0
class LockedBackgroundStreamBlock(StreamBlock):
    section_heading = CharBlock(
        icon="title",
        classname="title",
        template="longform/blocks/section_heading.html")
    heading = CharBlock(icon="title",
                        classname="title",
                        template="longform/blocks/heading.html")
    sub_heading = CharBlock(icon="title",
                            classname="title",
                            template="longform/blocks/sub_heading.html")
    intro = RichTextBlock(icon="pilcrow",
                          template="longform/blocks/intro.html")
    paragraph = RichTextBlock(icon="pilcrow",
                              template="longform/blocks/paragraph.html")
    pullquote = PullQuoteBlock()
    html = IframeBlock(template="longform/blocks/html.html")

    class Meta:
        template = 'longform/blocks/content_stream.html'
Ejemplo n.º 7
0
class BaseStreamBlock(StreamBlock):
    """
    Define the custom blocks that `StreamField` will utilize
    """
    heading_block = HeadingBlock(label="标题", heading_text="请选择字号")
    paragraph_block = RichTextBlock(icon="pilcrow",
                                    template="blocks/paragraph_block.html",
                                    label=u"段落")
    image_block = ImageBlock(label=u"图片", icon="image")
    block_quote = BlockQuote(label=u"引用", )
    table_block = TableBlock(label=u"表格", )
    raw_html = RawHTMLBlock(icon="code", label='Raw HTML')
Ejemplo n.º 8
0
class OneColumnBlock(StructBlock):
    back_image = ImageChooserBlock(blank=True)
    background_size = ImageFormatChoiceBlock(choices=SIZE_CHOICES,default="auto")
    one_column = StreamBlock([
           ('heading', CharBlock(classname="full title")),
           ('paragraph', RichTextBlock()),
        ], icon='arrow-left', label='Parallax content')

    class Meta:
        template = 'home/includes/one_column_block.html'
        icon = 'placeholder'
        label = 'One Column'
Ejemplo n.º 9
0
class SixPolygonHeader(StructBlock):
    first_polygon_header = CharBlock(required=True)
    first_polygon_text = RichTextBlock(required=True)
    first_polygon_icon = ChoiceBlock(choices=ICONS, required=True)

    second_polygon_header = CharBlock(required=True)
    second_polygon_text = RichTextBlock(required=True)
    second_polygon_icon = ChoiceBlock(choices=ICONS, required=True)

    third_polygon_header = CharBlock(required=True)
    third_polygon_text = RichTextBlock(required=True)
    third_polygon_icon = ChoiceBlock(choices=ICONS, required=True)

    fourth_polygon_header = CharBlock(required=True)
    fourth_polygon_text = RichTextBlock(required=True)
    fourth_polygon_icon = ChoiceBlock(choices=ICONS, required=True)

    fifth_polygon_header = CharBlock(required=True)
    fifth_polygon_text = RichTextBlock(required=True)
    fifth_polygon_icon = ChoiceBlock(choices=ICONS, required=True)

    sixth_polygon_header = CharBlock(required=False)
    sixth_polygon_text = RichTextBlock(required=False)
    sixth_polygon_icon = ChoiceBlock(choices=ICONS, required=False)

    class Meta:
        image = 'pages/images/streamfield_blocks/six_polygon_header.jpg'
        template = 'pages/streamfield_blocks/six_polygon_header.html'
Ejemplo n.º 10
0
class FourColumnWithHeadingImageBlock(StructBlock):
    block_heading = CharBlock(required=True)

    image = ImageChooserBlock(required=True)

    first_column_heading = CharBlock(required=True)
    first_column_text = RichTextBlock(required=True)

    second_column_heading = CharBlock(required=True)
    second_column_text = RichTextBlock(required=True)

    third_column_heading = CharBlock(required=True)
    third_column_text = RichTextBlock(required=True)

    fourth_column_heading = CharBlock(required=True)
    fourth_column_text = RichTextBlock(required=True)

    read_more_button = ReadMoreButtonBlock(required=False)

    class Meta:
        image = 'pages/images/streamfield_blocks/four_columns_with_heading_image.jpg'
        template = 'pages/streamfield_blocks/four_columns_with_heading_image.html'
Ejemplo n.º 11
0
class StreamPage(Page):
    body = StreamField([
        ('text', CharBlock()),
        ('rich_text', RichTextBlock()),
        ('image', ExtendedImageChooserBlock()),
    ])

    api_fields = ('body', )

    content_panels = [
        FieldPanel('title'),
        StreamFieldPanel('body'),
    ]
Ejemplo n.º 12
0
class StaticPage(TemplateableMixin, PageWithHeader):
    subtitle = models.CharField(max_length=255, blank=True, null=True)

    content = StreamField(
        [
            ('assesments_of_uses', AssesmentsOfUsesBlock()),
            ('community_stats', CommunityStatsBlock()),
            ('drivers_of_change', DriversOfChangeBlock()),
            ('four_columns_with_image', FourColumnWithHeadingImageBlock()),
            ('foresight_in_policy_cycle', ForesightInPolicyCycleBlock()),
            ('heading_with_image', HeadingWithImageBlock()),
            ('heading_with_text', HeadingWithTextBlock()),
            ('institutions', InstitutionsBlock()),
            ('methodology', MethodologyBlock()),
            ('polygon_header', SixPolygonHeader()),
            ('stakeholders', Stakeholders()),
            ('table_with_header', TableWithHeaderBlock()),
            # ('team', TeamBlock()),
            ('testimonials', TestimonialsBlock()),
            ('three_columns', ThreeColumnBlock()),
            ('topic_grid', TopicGridBlock()),
            ('paragraph',
             RichTextBlock(
                 template='pages/streamfield_blocks/paragraph.html')),
            ('video_embed', VideoEmbedBlock()),
        ],
        blank=True)

    content_panels = PageWithHeader.content_panels + [
        FieldPanel('subtitle'),
        StreamFieldPanel('content'),
    ]

    TEMPLATES_AND_CONTEXTS = (
        ('pages/home_page.html', None),
        ('pages/foresight_dictionary.html', foresight_dictionary_get_context),
    )

    page_template = models.CharField(choices=((k[0], k[0])
                                              for k in TEMPLATES_AND_CONTEXTS),
                                     max_length=255,
                                     blank=True,
                                     null=True)

    settings_panels = PageWithHeader.settings_panels + [
        MultiFieldPanel([
            FieldPanel('page_template', classname="template"),
        ],
                        'Developer settings',
                        classname='collapsible collapsed'),
    ]
Ejemplo n.º 13
0
class NexusGraph(StructBlock):
    block_heading = CharBlock(required=True)
    top_title = CharBlock(required=True)
    top_description = RichTextBlock(required=False)
    top_to_left_description = RichTextBlock(required=False)
    top_to_right_description = RichTextBlock(required=False)
    right_title = CharBlock(required=True)
    right_description = RichTextBlock(required=False)
    right_to_top_description = RichTextBlock(required=False)
    right_to_left_description = RichTextBlock(required=False)
    left_title = CharBlock(required=True)
    left_description = RichTextBlock(required=False)
    left_to_right_description = RichTextBlock(required=False)
    left_to_top_description = RichTextBlock(required=False)
    read_more_button = ReadMoreButtonBlock(required=False)

    class Meta:
        image = 'topics/images/streamfield_blocks/resources_nexus.png'
        template = 'topics/streamfield_blocks/nexus_graph.html'
Ejemplo n.º 14
0
class BaseStreamBlock(StreamBlock):
    """
    Define the custom blocks that `StreamField` will utilize
    """
    heading_block = HeadingBlock()
    paragraph_block = RichTextBlock(icon="fa-paragraph",
                                    template="blocks/paragraph_block.html")
    image_block = ImageBlock()
    block_quote = BlockQuote()
    embed_block = EmbedBlock(
        help_text=
        'Insert an embed URL e.g https://www.youtube.com/embed/SGJFWirQ3ks',
        icon="fa-s15",
        template="blocks/embed_block.html")
Ejemplo n.º 15
0
class ThreeColumnBlock(StructBlock):
    left_column = StreamBlock([
            ('heading', CharBlock(classname="full title")),
            ('paragraph', RichTextBlock()),
            ('image', ImageChooserBlock()),
        ], icon='arrow-left', label='Left column content')

    center_column = StreamBlock([
            ('heading', CharBlock(classname="full title")),
            ('paragraph', RichTextBlock()),
            ('image', ImageChooserBlock()),
        ], icon='arrow-right', label='Center column content')

    right_column = StreamBlock([
            ('heading', CharBlock(classname="full title")),
            ('paragraph', RichTextBlock()),
            ('image', ImageChooserBlock()),
        ], icon='arrow-right', label='Right column content')

    class Meta:
        template = 'home/includes/three_column_block.html'
        icon = 'placeholder'
        label = 'Three Columns'
Ejemplo n.º 16
0
class Job(ClusterableModel, index.Indexed):
    title = CharField(max_length=255, unique=True)
    background = RichTextField(blank=True)
    responsibilities = RichTextField(blank=True)
    skills = RichTextField(blank=True)
    notes = RichTextField(blank=True)
    location = RichTextField(blank=True)
    benefits = RichTextField(blank=True)
    applying = StreamField([
        ('raw_html',
         RawHTMLBlock(
             help_text=
             'To add Google Analytics to your link, use this template: '
             '<a href="www.example.com" onclick="trackOutboundLink("www.example.com"); return false;">link</a>.'
             '  With great power comes great responsibility. '
             'This HTML is unescaped. Be careful!')),
        ('rich_text', RichTextBlock()),
    ],
                           null=True,
                           blank=True)
    core_technologies = RichTextField(blank=True)
    referrals = RichTextField(blank=True)
    preferred = RichTextField(blank=True)
    qualifications = RichTextField(blank=True)
    experience_we_need = RichTextField(blank=True)

    panels = [
        MultiFieldPanel([
            FieldPanel('title'),
            FieldPanel('background'),
            FieldPanel('responsibilities'),
            FieldPanel('skills'),
            FieldPanel('notes'),
            FieldPanel('location'),
            FieldPanel('core_technologies'),
            FieldPanel('qualifications'),
            FieldPanel('experience_we_need'),
            FieldPanel('preferred'),
            FieldPanel('referrals'),
            FieldPanel('benefits'),
            StreamFieldPanel('applying'),
        ]),
    ]

    class Meta:
        ordering = ['title']

    def __str__(self):
        return '{self.title}'.format(self=self)
Ejemplo n.º 17
0
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")
Ejemplo n.º 18
0
class PromoParagraphBlock(ContentBlock):
    body = StreamBlock([('text', RichTextBlock()),
                        ('call_to_action', ListBlock(CallToActionBlock())),
                        ('spacer',
                         ChoiceBlock(choices=[('15', '15 pixels'),
                                              ('30', '30 pixels'),
                                              ('45', '45 pixels'),
                                              ('60', '60 pixels'),
                                              ('75', '75 pixels'),
                                              ('90', '90 pixels')],
                                     required=False))])

    class Meta:
        template = 'blocks/promo_paragraph.html'
        icon = 'doc-full'
Ejemplo n.º 19
0
class ThreeColumnBlock(StructBlock):
    block_heading = CharBlock(required=True)

    first_column_heading = CharBlock(required=True)
    first_column_text = RichTextBlock(required=True)
    first_column_color = ChoiceBlock(choices=COLORS, required=True)
    first_column_icon = ChoiceBlock(choices=ICONS, required=True)
    first_column_page = PageChooserBlock(required=False)

    second_column_heading = CharBlock(required=True)
    second_column_text = RichTextBlock(required=True)
    second_column_color = ChoiceBlock(choices=COLORS, required=True)
    second_column_icon = ChoiceBlock(choices=ICONS, required=True)
    second_column_page = PageChooserBlock(required=False)

    third_column_heading = CharBlock(required=True)
    third_column_text = RichTextBlock(required=True)
    third_column_color = ChoiceBlock(choices=COLORS, required=True)
    third_column_icon = ChoiceBlock(choices=ICONS, required=True)
    third_column_page = PageChooserBlock(required=False)

    class Meta:
        image = 'pages/images/streamfield_blocks/three_columns.jpg'
        template = 'pages/streamfield_blocks/three_columns.html'
Ejemplo n.º 20
0
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")
Ejemplo n.º 21
0
class ContentPage(Page):
    body = StreamField([
        ('text', RichTextBlock()),
        ('author', ModelChooserBlock(Author)),
        ('book', ModelChooserBlock(Book)),
    ])

    favourite_book = models.ForeignKey(Book,
                                       blank=True,
                                       null=True,
                                       on_delete=models.SET_NULL,
                                       related_name='+')

    content_panels = Page.content_panels + [
        StreamFieldPanel('body'),
        ModelChooserPanel('favourite_book'),
    ]
Ejemplo n.º 22
0
class BodyStreamBlock(StreamBlock):
    """
    Defines a ``StreamBlock`` with a dynamic behavior when writing the body of new pages.
    It includes:
        - h2 and h3 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 attributions
        - an embedded iframe for videos
    """
    h2 = CharBlock(icon="title")
    h3 = CharBlock(icon="title")
    paragraph = RichTextBlock(icon="pilcrow")
    image = ImageBlock(label=_("Aligned image"), icon="image")
    video = VideoBlock(label=_("Embedded video"), icon="media")
    pullquote = PullQuoteBlock(label=_("Quote"), icon="openquote")
Ejemplo n.º 23
0
class BlogBodyBlock(StreamBlock):
    heading = CharBlock(classname="full title",
                        icon='title',
                        template='blog/blocks/heading.html')
    quote = QuoteBlock()
    paragraph = RichTextBlock(icon='doc-full', label="Rich Text")
    image = ImageChooserBlock(icon='image')
    embed = EmbedBlock(icon='media')
    caption = CaptionBlock()
    raw_html = RawHTMLBlock(
        icon='code',
        label="Raw HTML",
        help_text=format_html(
            '<ul class="messages"><li class="error">Please mind that '
            'using raw HTML can break site rendering and/or compromise '
            'site security.</li></ul>'),
    )
Ejemplo n.º 24
0
class FormFieldsBlock(StreamBlock):
    char = CharFieldBlock(group=_('Fields'))
    text = TextFieldBlock(group=_('Fields'))
    number = NumberFieldBlock(group=_('Fields'))
    checkbox = CheckboxFieldBlock(group=_('Fields'))
    radios = RadioButtonsFieldBlock(group=_('Fields'))
    dropdown = DropdownFieldBlock(group=_('Fields'))
    checkboxes = CheckboxesFieldBlock(group=_('Fields'))
    date = DateFieldBlock(group=_('Fields'))
    time = TimeFieldBlock(group=_('Fields'))
    datetime = DateTimeFieldBlock(group=_('Fields'))
    image = ImageFieldBlock(group=_('Fields'))
    file = FileFieldBlock(group=_('Fields'))
    text_markup = RichTextBlock(group=_('Other'))

    class Meta:
        label = _('Form fields')
Ejemplo n.º 25
0
class HeadingWithTextBlock(StructBlock):
    block_heading = CharBlock(required=True)
    style = ChoiceBlock(choices=[('white', 'White background'),
                                 ('community', 'Community background')],
                        required=True)

    items = ListBlock(
        StructBlock([
            ('heading', CharBlock(required=True)),
            ('text', RichTextBlock(required=True)),
        ]))

    read_more_button = ReadMoreButtonBlock(required=False)

    class Meta:
        image = 'pages/images/streamfield_blocks/heading_with_text.jpg'
        template = 'pages/streamfield_blocks/heading_with_text.html'
Ejemplo n.º 26
0
class PostPage(Page):

    date = models.DateField(auto_now=True)
    header_image = models.ForeignKey('wagtailimages.Image',
                                     null=True,
                                     blank=True,
                                     on_delete=models.SET_NULL,
                                     related_name='+')

    body = StreamField([
        ('post_heading', CharBlock(max_length=40)),
        ('section_heading', CharBlock(max_length=40)),
        ('inline_image', ImageChooserBlock()),
        ('panorama_image', ImageChooserBlock()),
        ('paragraph', RichTextBlock()),
        ('code', CodeBlock()),
        ('video', EmbedBlock()),
        ('left_aligned_image', LeftAlignedImage()),
        ('right_aligned_image', RightAlignedImage()),
        ('two_column_code_block', TwoColumnCodeBlock()),
        ('left_aligned_code_block', LeftAlignedCodeBlock()),
        ('right_aligned_code_block', RightAlignedCodeBlock()),
    ])

    categories = ParentalManyToManyField('blog.PostPageCategory', blank=True)
    tags = ClusterTaggableManager(through='blog.PostPageTag', blank=True)

    content_panels = Page.content_panels + [
        ImageChooserPanel('header_image'),
        StreamFieldPanel('body'),
        FieldPanel('categories', widget=forms.CheckboxSelectMultiple),
        FieldPanel('tags'),
    ]

    search_fields = Page.search_fields + [
        index.SearchField('body'),
    ]

    def get_context(self, request, *args, **kwargs):
        context = super(PostPage, self).get_context(request, *args, **kwargs)
        context['home_page'] = self.get_parent().specific
        context['post'] = self
        return context
Ejemplo n.º 27
0
class StreamPage(Page):
    class Meta:
        verbose_name = "Content Stream Page"

    content = StreamField([
        ('heading', CharBlock(classname="full title", icon="title")),
        ('paragraph', RichTextBlock(icon="pilcrow")),
        ('image', ImageChooserBlock(icon="image")),
        ('embed', EmbedBlock(icon="media")),
    ],
                          null=True,
                          blank=True)
    content.help_text = "A page made up of blocks of text, images, video, etc."

    content_panels = Page.content_panels + [StreamFieldPanel('content')]

    promote_panels = [
        MultiFieldPanel(Page.promote_panels, "Common page configuration")
    ]
Ejemplo n.º 28
0
class TextBlock(StructBlock):
    variant = ChoiceBlock(
        choices=VARIANT_CHOICES
    )
    value = RichTextBlock()

    def __init__(self, **kwargs):
        super().__init__(**kwargs)

        # delete labels as we don't want them to appear in the admin
        for child_block in self.child_blocks.values():
            child_block.label = None

        # only markdown supported atm so hiding the choices dropdown
        self.child_blocks['variant'].field.widget = forms.HiddenInput()

    class Meta:
        default = {
            'variant': VARIANT_MARKDOWN
        }
Ejemplo n.º 29
0
class BlogIndexPage(MenuPage):
    body = StreamField([
        ('heading', HeadingBlock()),
        ('richtext', RichTextBlock()),
        ('image', ImageBlock()),
        ('blog_posts', LatestBlogPostsBlock()),
    ])

    content_panels = MenuPage.content_panels + [
        StreamFieldPanel('body'),
    ]

    api_fields = [
        'body',
    ]

    parent_page_types = ['reactail.HomePage', 'reactail.ContentPage']
    subpage_types = ['reactail.BlogPost']

    class Meta:
        verbose_name = _('Blog index')
Ejemplo n.º 30
0
class ContentPage(MenuPage):
    body = StreamField([
        ('heading', HeadingBlock()),
        ('richtext', RichTextBlock()),
        ('image', ImageBlock()),
    ])

    content_panels = MenuPage.content_panels + [
        StreamFieldPanel('body'),
    ]

    api_fields = [
        'body',
    ]

    parent_page_types = ['reactail.HomePage', 'reactail.ContentPage']
    subpage_types = ['reactail.ContentPage', 'reactail.BlogIndexPage']

    class Meta:
        verbose_name = _('Content page')
        verbose_name_plural = _('Content pages')
Ejemplo n.º 31
0
class SimplifiedBlock(StreamBlock):
    paragraph = RichTextBlock(icon="pilcrow", template="blocks/paragraph.html")
    header = CharBlock(classname="title",
                       icon="fa-header",
                       template="blocks/h3.html")
    image = StructBlock([('image', ImageChooserBlock()),
                         ('caption', CharBlock(blank=True, required=False)),
                         ('style',
                          ChoiceBlock(choices=[('', 'Select an image size'),
                                               ('full', 'Full-width'),
                                               ('half', 'Half-width')],
                                      required=False))],
                        icon="image",
                        template="blocks/image.html")
    blockquote = StructBlock([
        ('text', TextBlock()),
        ('attribute_name',
         CharBlock(blank=True, required=False, label='e.g. Guy Picciotto')),
        ('attribute_group',
         CharBlock(blank=True, required=False, label='e.g. Fugazi')),
    ],
                             icon="openquote",
                             template="blocks/blockquote.html")
Ejemplo n.º 32
0
class StandardBlock(StreamBlock):
    paragraph = RichTextBlock(icon="pilcrow", template="blocks/paragraph.html")
    header = StructBlock([
        ('header_text', CharBlock(blank=True, required=False, label='Header')),
        ('size',
         ChoiceBlock(choices=[('', 'Select a header size'), ('h2', 'H2'),
                              ('h3', 'H3'), ('h4', 'H4')],
                     blank=True,
                     required=False))
    ],
                         classname="title",
                         icon="fa-header",
                         template="blocks/header.html")
    image = StructBlock([('image', ImageChooserBlock()),
                         ('caption', CharBlock(blank=True, required=False)),
                         ('style',
                          ChoiceBlock(choices=[('', 'Select an image size'),
                                               ('fit', 'Contained width'),
                                               ('full', 'Full-width'),
                                               ('square', 'Square')],
                                      required=False))],
                        icon="image",
                        template="blocks/image.html")
    blockquote = StructBlock([
        ('text', TextBlock()),
        ('attribute_name',
         CharBlock(blank=True, required=False, label='e.g. Guy Picciotto')),
        ('attribute_group',
         CharBlock(blank=True, required=False, label='e.g. Fugazi')),
    ],
                             icon="openquote",
                             template="blocks/blockquote.html")
    embed = EmbedBlock(
        help_text=
        'Insert an embed URL e.g https://www.youtube.com/embed/SGJFWirQ3ks',
        icon="embed",
        template="blocks/embed.html")