Skip to content

Instantly share code, notes, and snippets.

@robodl
Last active April 10, 2024 17:41
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save robodl/48dd4bece30fcaf56c785212931f3bcd to your computer and use it in GitHub Desktop.
Save robodl/48dd4bece30fcaf56c785212931f3bcd to your computer and use it in GitHub Desktop.
Wagtail - Draftail - Multiple color highlighter
.cm-green {
background-image: linear-gradient(30deg,#16d6d9,#96cc29);
}
.cm-blue {
background-image: linear-gradient(30deg,#009cf3,#16d6d9);
}
.cm-pink {
background-image: linear-gradient(30deg,#ff2277,#7a288c);
}
.cm-orange {
background-image: linear-gradient(30deg,#ffbf02,#ed0082);
}
.txt-color {
color: transparent;
-webkit-background-clip: text;
background-clip: text;
position: relative;
}
from django.db import models
from wagtail.core.models import Page
from wagtail.core.fields import RichTextField
from wagtail.admin.edit_handlers import (
MultiFieldPanel,
FieldPanel,
)
class HomePage(Page):
# Database fields
page_description = models.CharField(max_length=1024, blank=True)
page_header = RichTextField(features=['cm_blue', 'cm_orange', 'cm_pink', 'cm_green'], blank=True, null=True)
# Editor panels configuration
content_panels = Page.content_panels + [
MultiFieldPanel(
[
FieldPanel('page_header',classname="title"),
],
heading="Hero",
classname="collapsible"
),
]
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_bluehighlight_feature(features):
feature_name = 'cm_blue'
type_ = 'BLUE_HIGHLIGHT'
tag = f'span{feature_name}'
control = {
'type': type_,
'label': 'Blue HL',
'description': 'Blue gradient highlight',
'style': {'color': '#00b8ed'},
}
features.register_editor_plugin(
'draftail', feature_name, draftail_features.InlineStyleFeature(control)
)
db_conversion = {
'from_database_format': {tag: InlineStyleElementHandler(type_)},
'to_database_format': {
'style_map': {
type_: {
'element': tag,
'props': {
'class': 'txt-color cm-blue'
}
}
}
},
}
features.register_converter_rule('contentstate', feature_name, db_conversion)
@hooks.register('register_rich_text_features')
def register_pinkhighlight_feature(features):
feature_name = 'cm_pink'
type_ = 'PINK_HIGHLIGHT'
tag = f'span{feature_name}'
control = {
'type': type_,
'label': 'Pink HL',
'description': 'Pink gradient highlight',
'style': {'color': '#e5007f'},
}
features.register_editor_plugin(
'draftail', feature_name, draftail_features.InlineStyleFeature(control)
)
db_conversion = {
'from_database_format': {tag: InlineStyleElementHandler(type_)},
'to_database_format': {
'style_map': {
type_: {
'element': tag,
'props': {
'class': 'txt-color cm-pink'
}
}
}
},
}
features.register_converter_rule('contentstate', feature_name, db_conversion)
@hooks.register('register_rich_text_features')
def register_orangehighlight_feature(features):
feature_name = 'cm_orange'
type_ = 'ORANGE_HIGHLIGHT'
tag = 'span'
tag = f'span{feature_name}'
control = {
'type': type_,
'label': 'Orange HL',
'description': 'Orange gradient highlight',
'style': {'color': '#ff9619'},
}
features.register_editor_plugin(
'draftail', feature_name, draftail_features.InlineStyleFeature(control)
)
db_conversion = {
'from_database_format': {tag: InlineStyleElementHandler(type_)},
'to_database_format': {
'style_map': {
type_: {
'element': tag,
'props': {
'class': 'txt-color cm-orange'
}
}
}
},
}
features.register_converter_rule('contentstate', feature_name, db_conversion)
@hooks.register('register_rich_text_features')
def register_greenhighlight_feature(features):
feature_name = 'cm_green'
type_ = 'GREEN_HIGHLIGHT'
tag = f'span{feature_name}'
control = {
'type': type_,
'label': 'Green HL',
'description': 'Green gradient highlight',
'style': {'color': '#00d6aa'},
}
features.register_editor_plugin(
'draftail', feature_name, draftail_features.InlineStyleFeature(control)
)
db_conversion = {
'from_database_format': {tag: InlineStyleElementHandler(type_)},
'to_database_format': {
'style_map': {
type_: {
'element': tag,
'props': {
'id': type_,
'class': 'txt-color cm-green'
}
}
}
},
}
features.register_converter_rule('contentstate', feature_name, db_conversion)
@AntonDumov
Copy link

Hey there! Noticed a small problem in the code. We're using custom span tags formed by joining 'span' and feature_name. That would create non-standard html tags on the web page.

Instead, we can just stick to regular span tags and differentiate them via CSS classes. For the DB conversion rules, instead of using custom tag, we can use class attributes to identify unique spans.

We can just stick to regular span tags:
tag = 'span'

And this:
'from_database_format': {tag: InlineStyleElementHandler(type_)}

Can be rewritten to something like:
'from_database_format': {f'{tag}[class="{feature_name}"]': InlineStyleElementHandler(type_)}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment