Home Code

Published on 26 January 2017

Code blocks for Wagtail using Pygments

This is a very simple and quick approach I've used in several website where I needed to have chunks of code as a StreamField blocks. You only need the Pygments package and a few lines of code.

First thing you need to do is to install Pygments:

$ pip install pygments

Then define the appropriate block class that you include in your StreamField definition:

from django.utils.safestring import mark_safe

from pygments import highlight
from pygments.formatters import get_formatter_by_name
from pygments.lexers import get_lexer_by_name

from wagtail.wagtailcore import blocks


class CodeBlock(blocks.StructBlock):
    """
    Code Highlighting Block
    """
    LANGUAGE_CHOICES = (
        ('python', 'Python'),
        ('bash', 'Bash/Shell'),
        ('html', 'HTML'),
        ('css', 'CSS'),
        ('scss', 'SCSS'),
        ('json', 'JSON'),
    )

    STYLE_CHOICES = (
        ('syntax', 'default'),
        ('emacs', 'emacs'),
        ('monokai', 'monokai'),
        ('vim', 'vim'),
        ('xcode', 'xcode'),
    )

    language = blocks.ChoiceBlock(choices=LANGUAGE_CHOICES)
    style = blocks.ChoiceBlock(choices=STYLE_CHOICES, default='syntax')
    code = blocks.TextBlock()

    def render(self, value):
        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),
            noclasses=False,
        )
        return mark_safe(highlight(src, lexer, formatter))

    class Meta:
        icon = 'code'

Make sure you add your own css classes in the body of the render method. You could change this method to fulfill any special requirements you might have.

You could implement your own CSS or borrow some ready-to-use files from https://github.com/dwayne/sass-pygments

If the previous snippet is not enough feel free to have a look at this blog's source code https://github.com/jordij/jordijoan.me or drop me a line.

Enjoy!