Tutorial Summary

Wagtails RichText editor, Draftail, is very minimal out of the box. There are times when you need to extend it's functionality. Luckily for backend developers, we can extend the Draftail editor by writing a Wagtail Hook in Python. No JavaScript needed! We're create an inline <code> and a centered text feature in this tutorial.

Wagtail has a really nice and minimalistic WYSIWYG editor called Draftail. The nice thing about it being so minimalistic is the features we don't have to support out of the box. As in, we don't need to support every known HTML element ever written; we just need to support:

  • Bold
  • Italic
  • H2-H4
  • Links
  • Image Embeds
  • Video Embeds
  • Horizontal Rules

But there comes a time when you need more. Maybe you client wants to center text on their website. Well.. you have two options:

  1. Create another field with the option to center text, or
  2. Let them center text in Draftail

I lean towards option #2: let them center their own text. The below code is the final code that you'll see in the git commit and the YouTube video above. For a full understanding of what's going on, definitely watch the video. Or feel free to tinker with the code until it does what you want it to do.

"""Richtext hooks."""
import wagtail.admin.rich_text.editors.draftail.features as draftail_features
from wagtail.admin.rich_text.converters.html_to_contentstate import (
    InlineStyleElementHandler
)
from wagtail.core import hooks


@hooks.register("register_rich_text_features")
def register_code_styling(features):
    """Add the <code> to the richtext editor and page."""

    # Step 1
    feature_name = "code"
    type_ = "CODE"
    tag = "code"

    # Step 2
    control = {
        "type": type_,
        "label": "</>",
        "description": "Code"
    }

    # Step 3
    features.register_editor_plugin(
        "draftail", feature_name, draftail_features.InlineStyleFeature(control)
    )

    # Step 4
    db_conversion = {
        "from_database_format": {tag: InlineStyleElementHandler(type_)},
        "to_database_format": {"style_map": {type_: {"element": tag}}}
    }

    # Step 5
    features.register_converter_rule("contentstate", feature_name, db_conversion)

    # Step 6. This is optional
    # This will register this feature with all richtext editors by default
    features.default_features.append(feature_name)


@hooks.register("register_rich_text_features")
def register_centertext_feature(features):
    """Creates centered text in our richtext editor and page."""

    # Step 1
    feature_name = "center"
    type_ = "CENTERTEXT"
    tag = "div"

    # Step 2
    control = {
        "type": type_,
        "label": "Center",
        "description": "Center Text",
        "style": {
            "display": "block",
            "text-align": "center",
        },
    }

    # Step 3
    features.register_editor_plugin(
        "draftail", feature_name, draftail_features.InlineStyleFeature(control)
    )

    # Step 4
    db_conversion = {
        "from_database_format": {tag: InlineStyleElementHandler(type_)},
        "to_database_format": {
            "style_map": {
                type_: {
                    "element": tag,
                    "props": {
                        "class": "d-block text-center"
                    }
                }
            }
        }
    }

    # Step 5
    features.register_converter_rule("contentstate", feature_name, db_conversion)

    # Step 6, This is optional.
    features.default_features.append(feature_name)
Sign up for our newsletter

Get notified about new lessons :)


Our Sites