Wagtail Dev Notes
Updated Sep 8, 2025
Extending Wagtail RichText features
Using the method described in the Wagtail docs with a helper function register_block_feature to make adding multiple features cleaner.
Add to wagtail_hooks.py. I added it to a settings app that is installed before my other apps so that the new rich text features are added globally.
import wagtail.admin.rich_text.editors.draftail.features as draftail_features
from wagtail.admin.rich_text.converters.html_to_contentstate import BlockElementHandler
from wagtail import hooks
# https://docs.wagtail.org/en/stable/extending/extending_draftail.html
def register_block_feature(features, name, type_, element, label, description, css_class=None):
"""
Register a custom block-level Draftail feature.
"""
control = {
'type': type_,
'label': label,
'description': description,
'element': element,
}
# Register the block feature
features.register_editor_plugin(
'draftail', name, draftail_features.BlockFeature(control)
)
# Map stored HTML to editor state with CSS class
from_db_selector = f'{element}[class={css_class}]' if css_class else element
# Map editor state back to HTML if CSS class
to_db_props = {'element': element}
if css_class:
to_db_props['props'] = {'class': css_class}
features.register_converter_rule('contentstate', name, {
'from_database_format': {from_db_selector: BlockElementHandler(type_)},
'to_database_format': {'block_map': {type_: to_db_props}},
})
# Add to default features so it's available everywhere
features.default_features.append(name)
# Add features with custom CSS classes to style output
@hooks.register('register_rich_text_features')
def register_custom_block_features(features):
register_block_feature(features, 'blue-text', 'BLUE-TEXT', 'p', '🟦', 'Blue Text', css_class='richtext__blue-text')
register_block_feature(features, 'blue-text-large', 'BLUE-TEXT-LARGE', 'p', 'LG:🟦', 'Blue Text Large', css_class='richtext__blue-text-large')