from wagtail import blocks from wagtail.embeds.blocks import EmbedBlock from wagtail.images.blocks import ImageChooserBlock class CodeBlock(blocks.StructBlock): LANGUAGE_CHOICES = [ ("python", "Python"), ("javascript", "JavaScript"), ("typescript", "TypeScript"), ("tsx", "TSX"), ("bash", "Bash"), ("json", "JSON"), ("css", "CSS"), ("html", "HTML"), ("plaintext", "Plain Text"), ] language = blocks.ChoiceBlock(choices=LANGUAGE_CHOICES, default="python") filename = blocks.CharBlock(required=False) raw_code = blocks.TextBlock() class Meta: icon = "code" template = "blog/blocks/code_block.html" def get_language_label(self, value): choices = dict(self.LANGUAGE_CHOICES) lang = str(value.get("language", "")) if isinstance(value, dict) else "" return choices.get(lang, "Plain Text") class CalloutBlock(blocks.StructBlock): ICON_CHOICES = [ ("info", "Info"), ("warning", "Warning"), ("trophy", "Trophy / Conclusion"), ("tip", "Tip"), ] icon = blocks.ChoiceBlock(choices=ICON_CHOICES, default="info") heading = blocks.CharBlock() body = blocks.RichTextBlock(features=["bold", "italic", "link"]) class Meta: icon = "pick" template = "blog/blocks/callout_block.html" class PullQuoteBlock(blocks.StructBlock): quote = blocks.TextBlock() attribution = blocks.CharBlock(required=False) class Meta: icon = "openquote" template = "blog/blocks/pull_quote_block.html" class ImageBlock(blocks.StructBlock): image = ImageChooserBlock() caption = blocks.CharBlock(required=False) alt = blocks.CharBlock(required=True) class Meta: icon = "image" template = "blog/blocks/image_block.html" ARTICLE_BODY_BLOCKS = [ ( "rich_text", blocks.RichTextBlock( features=["h2", "h3", "h4", "bold", "italic", "link", "ol", "ul", "hr", "blockquote", "code"] ), ), ("code", CodeBlock()), ("callout", CalloutBlock()), ("image", ImageBlock()), ("embed", EmbedBlock()), ("pull_quote", PullQuoteBlock()), ]