External links in Wagtail Rich Text fields
Rich Text fields in Wagtail are widely used and popular due to their extensive functionality and expandability. However, there is one feature that is often missed: the ability to add links that open in a new tab. Until now.
For the past 6 months, I have been interning here at Four Digits, and one of my assignments was to develop a feature for the Rich Text fields in Wagtail that allows adding links that open in a new tab. In this blog post I am going to walk through how I achieved this.
To add a new feature to Rich Text fields in Wagtail you need to create a Wagtail hook to register the feature. In this Wagtail hook you declare a Label
and Description
for the feature:
control = {
"type": type_,
"label": "New tab 🔗",
"description": "Open link in new tab",
}

In this hook you also how to register a draftail EntityFeature here you declare the label, description and custom JS and CSS if needed: (I won't dive into the JS and CSS because this is too large to explain in this blog post.)
features.register_editor_plugin(
"draftail",
feature_name,
draftail_features.EntityFeature(control, js=["js/newtab.js"], css={"all": ["css/newtab_form.css"]}),
)
In this case I needed custom JS and CSS to render the form and handle form submission. This was done using React
and DraftJS

The last thing that needs to be done is to handle the database format conversion. This done by registering a converter_rule
:
features.register_converter_rule(
"contentstate",
feature_name,
{
"from_database_format": {"a[target='_blank']": NewTabLinkEntityElementHandler(type_)},
"to_database_format": {"entity_decorators": {type_: new_tab_link_entity_decorator}},
},
)
"from_database_format"
and "to_database_format"
: These are key-value pairs specifying the conversion rules for the feature when converting from and to the database format.
"from_database_format"
uses the NewTabLinkEntityElementHandler
class NewTabLinkEntityElementHandler(InlineEntityElementHandler):
mutability = "MUTABLE"
def get_attribute_data(self, attrs):
"""
Override this method to add additional data to the entity.
"""
return {
"url": attrs["href"],
"target": "_blank",
"rel": "noopener noreferrer",
}
This class overrides the get_attribute_data
method to add additional attributes to the entity.
"to_database_format"
use the new_tab_link_entity_decorator
def new_tab_link_entity_decorator(props):
"""
Draft.js ContentState to database HTML.
Converts the ``LINK`` entities into ``<a>`` tags with the right attributes.
"""
return DOM.create_element(
"a",
{
"href": props["url"],
"target": "_blank",
"rel": "noopener noreferrer",
},
props["children"],
)
This function is responsible for converting Draft.js ContentState entities into HTML. It creates a new <a>
element with the appropriate attributes

With this we have now have registered a working external link feature.
We made this package open-source so it is available for usage in your own projects. To use this package go to the following link and follow the instructions: https://pypi.org/project/wagtail-external-link-richtext/#description