如何在Wagtail CMS中创建自定义InlineEntityElementHandler?链接样式冲突
问题描述
我想在Wagtail中创建一个模仿内置富文本链接功能的自定义特性,仅差异是名称不同,且给链接添加arrow类。因为我们用无头架构的前端需要两种不同类型的链接,同时必须保留原有的Link Chooser(页面、外部链接、邮箱等)选择界面。但我写的代码导致内置链接和自定义链接都带上了arrow类。
我的代码如下:
@hooks.register('register_rich_text_features') def register_arrow_link(features): feature_name = 'arrow' type_ = 'LINK' tag = 'a class="arrow"' control = { 'type': type_, 'label': '->', 'description': 'Arrow Link', } features.register_editor_plugin( 'draftail', feature_name, draftail_features.EntityFeature(control) ) db_conversion = { 'from_database_format': {tag: InlineEntityElementHandler(type_)}, 'to_database_format': {'entity_decorators': {type_: tag}} } features.register_converter_rule('contentstate', feature_name, db_conversion) features.default_features.append(feature_name)
问题原因
你用了和内置链接完全相同的实体类型LINK,这会导致自定义的转换规则覆盖掉内置链接的规则——所有链接都会被转换成带arrow类的标签,自然内置链接也会受到影响。
解决方案
需要创建一个独立的自定义实体类型,和内置LINK区分开,同时复用内置的Link Chooser界面。修改后的代码如下:
from wagtail.core import hooks from wagtail.core.rich_text import draftail_features from wagtail.core.rich_text.rewriters import InlineEntityElementHandler @hooks.register('register_rich_text_features') def register_arrow_link(features): # 自定义特性名称和实体类型(必须和内置LINK区分) feature_name = 'arrow_link' entity_type = 'ARROW_LINK' # 编辑器控件:复用内置LinkChooser,自定义显示标签 control = { 'type': entity_type, 'label': '→', 'description': '带箭头的链接', # 指定使用内置的链接选择组件 'component': 'Link', 'icon': 'link', } # 注册编辑器插件 features.register_editor_plugin( 'draftail', feature_name, draftail_features.EntityFeature(control) ) # 数据库转换规则:仅处理自定义实体类型 db_conversion = { 'from_database_format': { # 从数据库识别带arrow类的a标签,转换为自定义实体 'a[class="arrow"]': InlineEntityElementHandler(entity_type), }, 'to_database_format': { 'entity_decorators': { # 将自定义实体转换为带arrow类的a标签 entity_type: lambda props: f'a class="arrow" href="{props["url"]}"', }, }, } features.register_converter_rule('contentstate', feature_name, db_conversion) # 确保内置链接功能保留,同时添加自定义功能 if 'link' not in features.default_features: features.default_features.append('link') features.default_features.append(feature_name)
关键改动说明
- 把实体类型从
LINK改成ARROW_LINK,避免和内置链接规则冲突 - 编辑器控件中指定
component: 'Link',复用内置的Link Chooser界面,不用自己重新开发选择逻辑 - 转换规则只针对自定义的
ARROW_LINK实体,内置LINK仍使用原有规则,两者完全独立 - 显式保留内置
link功能,确保两种链接都能在编辑器中使用
内容的提问来源于stack exchange,提问作者kirillwolkow
相关产品推荐
相关产品推荐

