Learn Wagtail Course

Extending The Draftail RichText Editor

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)

The Git Commit

If you're interested in seeing the entire Learn Wagtail course source code, it's all available in the repo. This tutorial only has one file. Click here to open the git commit.

Was this helpful to you?

Sharing is caring. Help the community by sharing this article.