Wagtail:如何覆盖数据库中的 HTML 标记输出。使用 <strong> 或 <em> 代替 <b> 或 <i> 作为富文本模板标签

Posted

技术标签:

【中文标题】Wagtail:如何覆盖数据库中的 HTML 标记输出。使用 <strong> 或 <em> 代替 <b> 或 <i> 作为富文本模板标签【英文标题】:Wagtail: How to override HTML tag output from database. Use <strong> or <em> instead of <b> or <i> for richtext template tag 【发布时间】:2018-09-28 21:15:56 【问题描述】:

我试图让我的 wagtail 模板输出 &lt;strong&gt;&lt;/strong&gt; 而不是 &lt;b&gt;&lt;/b&gt;&lt;em&gt;&lt;/em&gt; 而不是 &lt;i&gt;&lt;/i&gt;

我手动编辑了 wagtailcore_pagerevision 表记录中的 content_json 值,以便 &lt;b&gt; 标签为 &lt;strong&gt;&lt;i&gt; 标签为 &lt;em&gt;,但输出 html 继续输出 &lt;b&gt;&lt;i&gt; 标签分别。

在我的模板中, block.value|richtext 用于块, self.body|richtext 用于非块。

做这项工作的鹡鸰代码是:

@register.filter
def richtext(value):
    if isinstance(value, RichText):
        # passing a RichText value through the |richtext filter should have no effect
        return value
    elif value is None:
        html = ''
    else:
        html = expand_db_html(value)

    return mark_safe('<div class="rich-text">' + html + '</div>')

我的问题是.. 我怎样才能告诉 Wagtail 或 Django 使用 &lt;strong&gt;&lt;em&gt; 标签?

这似乎不是 halo-js 所见即所得的问题或设置,而是我似乎找不到的某种配置或其他设置。

顺便说一句.. 我使用 Wagtail 1.13.1(带有默认的 Hallo 编辑器)、Django 1.11 和 mysql 作为数据库。

为了解决我的问题,我用这段代码覆盖..

# override the wagtail version and replace <b>, <i>
@register.filter(name='richtext')
def richtext(value):
    if isinstance(value, RichText):
        # passing a RichText value through the |richtext filter should have no effect
        # return value
        html = value.source
    elif value is None:
        html = ''
    else:
        html = expand_db_html(value)

    html = html.replace('<b>', '<strong>').replace('</b>', '</strong>') \
            .replace('<i>', '<em>').replace('</i>', '</em>')

    return mark_safe('<div class="rich-text">' + html + '</div>')

但应该有更好、更有效的方法。

【问题讨论】:

嗨@robnardo,你可以看到here,这是由浏览器处理的,可能很难改变。在将内容保存到数据库之前,您必须手动更改标签,例如。通过页面的overriding save method 或使用挂钩 嗨@KonradLyda thx 及时回复,但正如您在第二段中看到的那样,我已经“手动编辑”了修订表中的记录 - 所以数据库中的内容有&lt;strong&gt;&lt;em&gt; 标签。某些东西正在渲染它们。 您确定已正确提交对表的更改吗?因为我做了同样的练习(将数据库表中的 标签更改为 )并且网站上的输出是正确的。我也在使用 Wagtail 1.13.1。 【参考方案1】:

我遇到了同样的问题,并在 Wagtail Slack 支持频道上提问。我得到了register a new rich text feature的建议。该文档显示了一个删除线示例。以下是粗体(强)和斜体(em):

import wagtail.admin.rich_text.editors.draftail.features as draftail_features
from wagtail.admin.rich_text.converters.html_to_contentstate import (
    InlineStyleElementHandler,
)


@hooks.register('register_rich_text_features')
def register_strong_feature(features):
    """
    Registering the `strong` feature. It will render bold text with `strong` tag.
    Default Wagtail uses the `b` tag.
    """
    feature_name = 'strong'
    type_ = 'BOLD'
    tag = 'strong'

    # Configure how Draftail handles the feature in its toolbar.
    control = 
        'type': type_,
        'icon': 'bold',
        'description': 'Bold',
    

    # Call register_editor_plugin to register the configuration for Draftail.
    features.register_editor_plugin(
        'draftail', feature_name, draftail_features.InlineStyleFeature(control)
    )

    # Configure the content transform from the DB to the editor and back.
    db_conversion = 
        'from_database_format': tag: InlineStyleElementHandler(type_),
        'to_database_format': 'style_map': type_: tag,
    

    # Call register_converter_rule to register the content transformation conversion.
    features.register_converter_rule('contentstate', feature_name, db_conversion)

以及带有&lt;em&gt;标签的斜体:

@hooks.register('register_rich_text_features')
def register_em_feature(features):
    """
    Registering the `em` feature. It will render italic text with `em` tag.
    Default Wagtail uses the `i` tag.
    """
    feature_name = 'em'
    type_ = 'ITALIC'
    tag = 'em'

    control = 
        'type': type_,
        'icon': 'italic',
        'description': 'Italic',
    

    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_: tag,
    

    features.register_converter_rule('contentstate', feature_name, db_conversion)

指定富文本字段的功能。不要忘记删除旧的“粗体”和“斜体”:

from wagtail.core.fields import RichTextField

class FooPage(Page):
    body = RichTextField(features=['strong', 'em']) 

【讨论】:

以上是关于Wagtail:如何覆盖数据库中的 HTML 标记输出。使用 <strong> 或 <em> 代替 <b> 或 <i> 作为富文本模板标签的主要内容,如果未能解决你的问题,请参考以下文章

Wagtail:序列化页面模型

Wagtail 页面中的字段权限

Wagtail ModelAdmin 只读

Wagtail:如何在管理员中设置计算字段(@property)标题

如何将计算变量添加到 wagtail StructBlock 模板上下文?

如何在循环中更新 html 标记的值而不覆盖前几轮