Wagtail富文本编辑器代码块钩子问题:多行生成多个div
Wagtail富文本编辑器代码块钩子异常问题解决方向
问题现象
选中多行内容应用自定义代码块时,每行内容被单独包裹在<div class="code">标签内,而非整个选中区块用单个div包裹:
预期输出
<div class="code"> content line one content line two </div>
实际输出
<div class="code">content line one </div> <div class="code">content line two </div>
原钩子代码
@hooks.register('register_rich_text_features') def register_py_code_block_feature(features): """ Registering for adding python code block """ feature_name = 'py-code-block' type_ = 'py-code-block' control = { 'type': type_, 'label': 'PY', 'description': 'Python Code Block', # Optionally, we can tell Draftail what element to use when displaying those blocks in the editor. 'element': 'div', 'style': { "display": "block", }, } db_conversion = { 'from_database_format': {'div': BlockElementHandler(type_)}, 'to_database_format': {'block_map': {type_: { 'element': 'div', 'props': { 'class': 'code blog_code language-python' } } } }, } features.register_editor_plugin('draftail', feature_name, draftail_features.BlockFeature(control)) features.register_converter_rule('contentstate', feature_name, db_conversion) features.default_features.append('py-code-block')
解决方向
核心原因
Draftail的BlockFeature默认将每行文本视为独立块处理,同时原生的BlockElementHandler不会合并连续的同类型块元素。
具体修改方案
调整编辑器控件配置,允许块合并
在control字典中添加merge属性并启用,同时设置样式保留换行格式:control = { 'type': type_, 'label': 'PY', 'description': 'Python Code Block', 'element': 'div', 'block': True, 'merge': True, # 允许连续的同类型块自动合并 'style': { "display": "block", "white-space": "pre-wrap", # 保留原始换行符格式 }, }自定义块元素处理器,合并连续区块
继承BlockElementHandler并重写处理逻辑,避免将连续的同类型div拆分成多个块:from wagtail.core.rich_text import BlockElementHandler class MergedBlockElementHandler(BlockElementHandler): def handle_starttag(self, attrs, state): # 检查当前是否已处于目标类型的块中,避免重复创建块 if state.get('current_block_type') == self.block_type: return state return super().handle_starttag(attrs, state) def handle_endtag(self, state): # 记录当前块类型的结束状态 state.pop('current_block_type', None) return super().handle_endtag(state) # 更新数据库转换配置中的处理器 db_conversion = { 'from_database_format': {'div': MergedBlockElementHandler(type_)}, 'to_database_format': {'block_map': {type_: { 'element': 'div', 'props': { 'class': 'code blog_code language-python' } } } }, }处理编辑器文本拆分逻辑
Draftail默认会将换行文本拆分为多个段落,应用代码块前可通过编辑器API将选中的多行文本合并为一个单一文本节点,确保代码块能包裹整个选中内容。
内容的提问来源于stack exchange,提问作者sherin
相关产品推荐
相关产品推荐

