replace button link block with a separate button link tool inside draftail
This commit is contained in:
@@ -0,0 +1,92 @@
|
||||
"""Inline "button" link for Draftail rich text fields.
|
||||
|
||||
Stored as `<a linktype="button" data-href="...">label</a>`. The linktype (not a
|
||||
plain href) avoids colliding with the built-in link feature, and lets
|
||||
expand_db_html rewrite it to `<a class="button" href="...">` for the front end.
|
||||
Wired up in wagtail_hooks.py.
|
||||
"""
|
||||
|
||||
from django.urls import reverse_lazy
|
||||
from django.utils.html import escape
|
||||
from draftjs_exporter.dom import DOM
|
||||
from wagtail.admin.rich_text.converters.html_to_contentstate import (
|
||||
InlineEntityElementHandler,
|
||||
)
|
||||
from wagtail.admin.rich_text.editors.draftail import features as draftail_features
|
||||
from wagtail.rich_text import LinkHandler
|
||||
|
||||
FEATURE_NAME = "button-link"
|
||||
ENTITY_TYPE = "BUTTON"
|
||||
|
||||
|
||||
def button_link_entity_decorator(props):
|
||||
"""ContentState to DB HTML (keeps just the chosen URL)."""
|
||||
return DOM.create_element(
|
||||
"a",
|
||||
{"linktype": "button", "data-href": props.get("url", "")},
|
||||
props["children"],
|
||||
)
|
||||
|
||||
|
||||
class ButtonLinkEntityElementHandler(InlineEntityElementHandler):
|
||||
"""DB HTML to ContentState."""
|
||||
|
||||
mutability = "MUTABLE"
|
||||
|
||||
def get_attribute_data(self, attrs):
|
||||
return {"url": attrs.get("data-href", "")}
|
||||
|
||||
|
||||
class ButtonLinkRichTextHandler(LinkHandler):
|
||||
"""DB HTML to front-end HTML (expand_db_html)."""
|
||||
|
||||
identifier = "button"
|
||||
|
||||
@classmethod
|
||||
def expand_db_attributes(cls, attrs):
|
||||
href = escape(attrs.get("data-href", ""))
|
||||
return f'<a class="button" href="{href}">'
|
||||
|
||||
|
||||
def register_button_link_feature(features):
|
||||
features.register_editor_plugin(
|
||||
"draftail",
|
||||
FEATURE_NAME,
|
||||
draftail_features.EntityFeature(
|
||||
{
|
||||
"type": ENTITY_TYPE,
|
||||
"icon": "arrow-right-full",
|
||||
"description": "Knapp",
|
||||
# Reuse the link chooser modal + payload, so buttons work like links.
|
||||
"attributes": ["url", "id", "parentId"],
|
||||
"allowlist": {"href": "^(http:|https:|mailto:|tel:|#|/|undefined$)"},
|
||||
"chooserUrls": {
|
||||
"pageChooser": reverse_lazy("wagtailadmin_choose_page"),
|
||||
"externalLinkChooser": reverse_lazy("wagtailadmin_choose_page_external_link"),
|
||||
"emailLinkChooser": reverse_lazy("wagtailadmin_choose_page_email_link"),
|
||||
"phoneLinkChooser": reverse_lazy("wagtailadmin_choose_page_phone_link"),
|
||||
"anchorLinkChooser": reverse_lazy("wagtailadmin_choose_page_anchor_link"),
|
||||
},
|
||||
},
|
||||
js=[
|
||||
# Gives LinkModalWorkflowSource its PAGE_CHOOSER_MODAL_ONLOAD_HANDLERS.
|
||||
"wagtailadmin/js/page-chooser-modal.js",
|
||||
"js/draftail-button-link.js",
|
||||
],
|
||||
css={"all": ["css/draftail-button-link.css"]},
|
||||
),
|
||||
)
|
||||
features.register_converter_rule(
|
||||
"contentstate",
|
||||
FEATURE_NAME,
|
||||
{
|
||||
"from_database_format": {
|
||||
'a[linktype="button"]': ButtonLinkEntityElementHandler(ENTITY_TYPE),
|
||||
},
|
||||
"to_database_format": {
|
||||
"entity_decorators": {ENTITY_TYPE: button_link_entity_decorator},
|
||||
},
|
||||
},
|
||||
)
|
||||
features.register_link_type(ButtonLinkRichTextHandler)
|
||||
features.default_features.append(FEATURE_NAME)
|
||||
Reference in New Issue
Block a user