class ContentBlock(StructBlock): width = ChoiceBlock(choices=[('2', '2 columns'), ('3', '3 columns'), ('4', '4 columns'), ('5', '5 columns'), ('6', '6 columns'), ('7', '7 columns'), ('8', '8 columns'), ('9', '9 columns'), ('10', '10 columns'), ('11', '11 columns'), ('12', '12 columns')], required=True, help_text='Length in Bootstrap columns for ' 'display on desktop.') offset = ChoiceBlock(choices=[('2', '2 columns'), ('3', '3 columns'), ('4', '4 columns'), ('5', '5 columns'), ('6', '6 columns'), ('7', '7 columns'), ('8', '8 columns'), ('9', '9 columns'), ('10', '10 columns'), ('11', '11 columns'), ('12', '12 columns')], required=False, help_text='Offset in Bootstrap columns for ' 'display on desktop.') align = ChoiceBlock(choices=[('text-left', 'Left aligned text'), ('text-center', 'Center aligned text'), ('text-right', 'Right aligned text'), ('text-justify', 'Justified text'), ('text-nowrap', 'No wrap text')], required=False, help_text='Alignment for text in content block.') class Meta: icon = 'doc-empty'
class CodeBlock(StructBlock): LANGUAGE_CHOICES = ( ('python', 'Python'), ('html', 'HTML'), ('css', 'CSS'), ('scss', 'SCSS'), ('json', 'JSON'), ('sh', 'Shell'), ) STYLE_CHOICES = ( ('syntax', 'default'), ('monokai', 'monokai'), ('xcode', 'xcode'), ) language = ChoiceBlock(choices=LANGUAGE_CHOICES) style = ChoiceBlock(choices=STYLE_CHOICES, default='syntax') code = TextBlock() def render(self, value, context=None): src = value['code'].strip('\n') lang = value['language'] lexer = get_lexer_by_name(lang) css_classes = ['code', value['style']] formatter = get_formatter_by_name('html', lineos=None, cssclass=' '.join(css_classes), noclasses=False) return mark_safe(highlight(src, lexer, formatter)) class Meta: icon = 'code'
class GlobalStreamBlock(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="title", template="blocks/header.html") image = StructBlock([('image', ImageChooserBlock()), ('caption', CharBlock(blank=True, required=False)), ('style', ChoiceBlock(choices=[('', 'Select an image size'), ('full', 'Full-width'), ('contain', 'Contained-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") embed = EmbedBlock( help_text= 'Insert an embed URL e.g https://www.youtube.com/embed/SGJFWirQ3ks')
class CallToActionBlock(LinkBlock): color = ChoiceBlock([('black', 'Black'), ('white', 'White')], required=True) size = ChoiceBlock([('lg', 'Large'), ('md', 'Medium'), ('sm', 'Small'), ('xs', 'Extra Small')]) class Meta: icon = 'link' template = 'blocks/call_to_action.html'
class HeadingBlock(StructBlock): class Meta: icon = "title" template = "blocks/heading_block.html" heading_text = CharBlock(classname="Heading", required=True) heading_size = ChoiceBlock(choices=HEADING_SIZE_CHOICES, blank=False, required=True) heading_position = ChoiceBlock(choices=POSITION_CHOICES, blank=True, required=False, default="left")
class CodeBlock(blocks.StructBlock): LANGUAGE_CHOICES = [ ('arduino', 'Arduino'), ('bash', 'Shell'), ('c', 'C'), ('css', 'CSS'), ('django', 'Django'), ('docker', 'Docker'), ('javascript', 'JavaScript'), ('json', 'JSON'), ('md', 'Markdown'), ('nginx', 'Nginx'), ('plpgsql', 'Pl/pgSQL'), ('postgresql', 'PostgreSQL'), ('python', 'Python'), ('sql', 'SQL'), ('sqlite3', 'SQLite3'), ('yaml', 'YAML'), ] STYLE_CHOICES = [ ('syntax', 'default'), ] language = ChoiceBlock(choices=LANGUAGE_CHOICES) style = ChoiceBlock(choices=STYLE_CHOICES, default='syntax') code = TextBlock() def render(self, value, context): src = value['code'].strip('\n') lang = value['language'] lexer = get_lexer_by_name(lang) css_classes = ['code', value['style']] formatter = get_formatter_by_name( 'html', linenos=None, #cssclass = ' '.join(css_classes), cssclass='syntax', #style = 'default', noclasses=False, ) return mark_safe(highlight(src, lexer, formatter)) class Meta: icon = 'code'
class ImageBlock(StructBlock): """ `StructBlock`: image with caption and alignment """ image = ImageChooserBlock(required=True) caption = CharBlock(required=False) style = ChoiceBlock(choices=settings.WAGTAIL_IMAGE_CHOICES, required=True, default=settings.WAGTAIL_IMAGE_CHOICES[0][0]) def get_api_representation(self, value, context=None): key = value['style'] alignment, rend_style = settings.WAGTAIL_IMAGE_PRESETS[key] rendition = value['image'].get_rendition(rend_style) resp = { 'alt': value['image'].title, 'url': rendition.url, 'alignment': alignment, } if ('caption' in value and len(value['caption']) > 0): resp['caption'] = value['caption'] return resp class Meta: icon = 'image'
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 CodeBlock(StructBlock): """ Code Highlighting Block """ LANGUAGE_CHOICES = ( ('python', 'Python'), ('cpp', 'C++'), ('html', 'HTML'), ('css', 'CSS'), ) language = ChoiceBlock(choices=LANGUAGE_CHOICES) code_text = TextBlock() def render(self, value): src = value['code_text'].strip('\n') lang = value['language'] lexer = get_lexer_by_name(lang) formatter = get_formatter_by_name( 'html', linenos='table', noclasses=True, style='monokai', ) return mark_safe(highlight(src, lexer, formatter))
class VisualizationBlock(StructBlock): vis_type = ChoiceBlock(choices=[ ('map', 'Map'), ('graph', 'Graph'), ('table', 'Table'), ]) variable = VariableChooserBlock()
class CalloutBlock(StructBlock): variant = ChoiceBlock(label='Variant', choices=( ('info', 'Service control'), ('attention', 'Primary care'), ('warning', 'Important information'), ('alert', 'Urgent care'), ('severe', 'Emergency care'), )) compact = BooleanBlock(default=False, required=False) 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 .reveal import reveal_compact children_stream_block.append(reveal_compact.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 GalleryBlock(StructBlock): variant = ChoiceBlock(label='Variant', choices=( ('inline', 'Inline'), ('collage', 'Collage'), )) children = StreamBlock([image.as_tuple()], label='Images')
class HeadingBlock(StructBlock): SIZE_CHOICES = (('h2', 'H2'), ('h3', 'H3'), ('h4', 'H4'), ('h5', 'H5'), ('h6', 'H6')) text = CharBlock(required=True) size = ChoiceBlock(choices=SIZE_CHOICES, blank=True, required=False) class Meta: icon = 'title' template = 'blog/blocks/heading_block.html'
class ImageBlock(StructBlock): main_image = ImageChooserBlock() style = ChoiceBlock(choices=IMAGE_STYLE_CHOICES, default="height:auto") url = CharBlock(max_length=250, required=False) class Meta: template = 'common/blocks/image_custom_block.html' icon = 'image' label = 'Image'
class ContentCarouselFrame(StructBlock): image = ImageChooserBlock() image_location = ChoiceBlock([('left', 'Left'), ('right', 'Right')], required=False) description = PromoParagraphBlock() class Meta: icon = 'image' template = 'blocks/content_carousel_frame.html'
class ImageWithCaptionBlock(StructBlock): image = ImageChooserBlock(required=True) caption = CharBlock(required=False) image_width = ChoiceBlock(choices=(('content_wide', 'Content wide'), ('page_wide', 'Page wide')), required=True) class Meta: image = 'pages/images/streamfield_blocks/image_with_caption.jpg' template = 'pages/streamfield_blocks/image_with_caption.html'
class ImageBlock(StructBlock): class Meta: icon = "image" template = "blocks/image_block.html" image = ImageChooserBlock() image_position = ChoiceBlock(choices=POSITION_CHOICES, blank=True, required=False, default="left")
class ButtonBlock(StructBlock): class Meta: icon = "placeholder" template = "blocks/button_block.html" button_text = CharBlock(required=True) link_to_internal_page = PageChooserBlock(can_choose_root=True, required=False) link_to_external_page = CharBlock( required=False, help_text= "Manually enter URL if you want the button link to an external page. This value will override the link above." ) button_color = ChoiceBlock(choices=COLOR_CHOICES, blank=False, required=True) button_positon = ChoiceBlock(choices=POSITION_CHOICES, blank=True, required=False, default="left")
class RevealBlock(StructBlock): summary = CharBlock() variant = ChoiceBlock(label='Variant', choices=( ('inline', 'Inline'), ('block', 'Block'), )) children = StreamBlock( [text.as_tuple(), gallery.as_tuple()], label='Content')
class ImageGrid(StructBlock): images = ListBlock(ImageGridItem()) # width = WidthChoiceBlock(required=True, default="width-100") width = ChoiceBlock(choices=[ ('width-100', '100% stretched'), ('width-150', '150% stretched'), ('width-50', '50% stretched') ], default='width-100', label='Grid width') class Meta: template = 'base/image_grid_block.html' form_classname = "fieldname-image_grid"
class HeadingBlock(StructBlock): """ Custom `StructBlock` that allows the user to select h2 - h4 sizes for headers """ encabezado = CharBlock(classname="title", required=True) nivel = ChoiceBlock(choices=[('', 'Select a header size'), ('h2', 'H2'), ('h3', 'H3'), ('h4', 'H4')], blank=True, required=False) class Meta: icon = "title"
class TeaserImageBlock(StructBlock): image = ImageChooserBlock(required=False, help_text='Recommended minimal width: 737px') position = ChoiceBlock( choices=[ ('top', 'Top'), ('left', 'Left'), ('right', 'Right'), ], required=False, ) large = BooleanBlock(required=False)
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'
class HeadingBlock(StructBlock): """ Custom `StructBlock` that allows the user to select h2 - h4 sizes for headers """ heading_text = CharBlock(classname="title", required=True) size = ChoiceBlock(choices=[('', 'Select a header size'), ('h2', 'H2'), ('h3', 'H3'), ('h4', 'H4')], blank=True, required=False) class Meta: icon = "title" template = "blocks/heading_block.html"
class ImageGalleryElementBlock(StructBlock): image = ImageChooserBlock(help_text='Recommended minimal width: 737px') page = PageChooserBlock(required=False) link = blocks.URLBlock(required=False) description = blocks.CharBlock(required=False) shrink = ChoiceBlock( choices=[ (1, 'S'), (2, 'XS'), (3, 'XXS'), ], required=False, )
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 CodeBlock(StructBlock): """ Code Highlighting Block """ LANGUAGE_CHOICES = ( ('bash', 'Bash/Shell'), ('c', 'C'), ('cmake', 'CMake'), ('cpp', 'C++'), ('csharp', 'C#'), ('css', 'CSS'), ('go', 'Go'), ('haskell', 'Haskell'), ('haxe', 'Haxe'), ('html', 'HTML'), ('java', 'Java'), ('js', 'JavaScript'), ('json', 'JSON'), ('kotlin', 'Kotlin'), ('lua', 'Lua'), ('make', 'Makefile'), ('perl', 'Perl'), ('perl6', 'Perl 6'), ('php', 'PHP'), ('python', 'Python'), ('python3', 'Python 3'), ('ruby', 'Ruby'), ('sql', 'SQL'), ('swift', 'Swift'), ('xml', 'XML'), ) language = ChoiceBlock(choices=LANGUAGE_CHOICES) code = TextBlock() class Meta: icon = 'code' def render(self, value): src = value['code'].strip('\n') lang = value['language'] lexer = get_lexer_by_name(lang) formatter = get_formatter_by_name( 'html', linenos='table', cssclass='code-highlight', style='default', noclasses=False, ) return mark_safe(highlight(src, lexer, formatter))
class TabsBlock(StructBlock): variant = ChoiceBlock(label='Variant', choices=( ('bottom', 'Bottom'), ('top', 'Top'), )) children = StreamBlock([('tab', TabBlock())]) 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
class CodeBlock(StructBlock): """ Code Highlighting Block """ WCB_LANGUAGES = get_language_choices() language = ChoiceBlock(choices=WCB_LANGUAGES, help_text=_('Coding language'), label=_('Language')) code = TextBlock(label=_('Code')) @property def media(self): theme = get_theme() prism_version = get_prism_version() if theme: prism_theme = '-{}'.format(theme) else: prism_theme = "" js_list = [ "https://cdnjs.cloudflare.com/ajax/libs/prism/{}/prism.min.js". format(prism_version, ), ] for lang_code, lang_name in self.WCB_LANGUAGES: js_list.append( "https://cdnjs.cloudflare.com/ajax/libs/prism/{}/components/prism-{}.min.js" .format( prism_version, lang_code, )) return Media( js=js_list, css={ 'all': [ "https://cdnjs.cloudflare.com/ajax/libs/prism/{}/themes/prism{}.min.css" .format(prism_version, prism_theme), ] }) class Meta: icon = 'code' template = 'wagtailcodeblock/code_block.html' form_classname = 'code-block struct-block' form_template = 'wagtailcodeblock/code_block_form.html'
class MediaTeaserBlock(StructBlock): media = MediaChooserBlock(required=True) image_position = ChoiceBlock( choices=[ ('top', 'Top'), ('left', 'Left'), ('right', 'Right'), ], required=False, ) def get_context(self, value, parent_context=None): media = value.get('media') if not media: # Media can be deleted, there is no cascading to the teaser-object in case this happens. return {} teaser_image = media.teaser_image.get_rendition('max-1200x1200').url if media.teaser_image else '' author = media.author year = media.year languages = [language.name for language in media.languages.all()] image_position = value.get('image_position') if not media.content and media.file: href = media.file.url readmorelink = _('Download') else: href = media.get_absolute_url() readmorelink = _('Show media') return { 'href': href, 'title': media.title, 'description': media.abstract, 'author': '{author}{year}{languages}'.format( author='Author: {0}'.format(author) if author else '', year='{0}Year: {1}'.format(', ' if author else '', year) if year else '', languages='{0}Languages: {1}'.format(', ' if author or year else '', ', '.join(languages)) if languages else '' ), 'readmorelink': {'text': readmorelink}, 'imgsrc': teaser_image, 'imgpos': image_position or 'top', 'mediastyle': True, } class Meta: icon = 'fa fa-file' label = 'Media Teaser' template = 'widgets/teaser.html'