片段id链接在wagtail的富文本内容中

问题描述 投票:1回答:3

我在Wagtail 2.0富文本字段中有一堆内容,看起来像

Page heading
(intro blurb)

heading 1
(heading-1-relevant text)

heading 2
(heading-2-relevant text)

...

我想给每个标题一个id,这样任何文本都可以成为跳转到相关内容的链接。我似乎无法找到一个选项给标题一个明确的id,富文本编辑器中的“链接”按钮似乎不允许我在内容中选择活动的片段标识符。

有没有办法在Wagtail的富文本编辑器上在同一页面上添加基于片段标识符的导航?

wagtail
3个回答
1
投票

一年后重新审视我自己的问题,因为这仍然是我们需要的,我们提出的解决方案是简单地包装RichText html序列化,并将片段id注入放在最上面:

import re
from django import template
from django.utils.text import slugify
from wagtail.core.rich_text import RichText

# We'll be wrapping the original RichText.__html__(), so make
# sure we have a reference to it that we can call.
__original__html__ = RichText.__html__

# This matches an h1/.../h6, using a regexp that is only
# guaranteed to work because we know that the source of
# the HTML code we'll be working with generates nice
# and predictable HTML code.
heading_re = r"<h(\d)[^>]*>([^<]*)</h\1>"


def add_id_attribute(match):
    """
    This is a regexp replacement function that takes
    in the above regex match results, and then turns:
        <h1>some text</h1>
    Into:
        <h1><a id="some-text"></a><a href="#some-text">some text</a></h1>
    where the id attribute value is generated by running
    the heading text through Django's slugify() function.
    """
    n = match.group(1)
    text_content = match.group(2)
    id = slugify(text_content)
    return f'<h{n}><a id="{id}""></a><a href="#{id}">{text_content}</a></h{n}>'


def with_heading_ids(self):
    """
    We don't actually change how RichText.__html__ works, we just replace
    it with a function that does "whatever it already did", plus a
    substitution pass that adds fragment ids and their associated link
    elements to any headings that might be in the rich text content.
    """
    html = __original__html__(self)
    return re.sub(heading_re, add_id_attribute, html)


# Rebind the RichText's html serialization function such that
# the output is still entirely functional as far as wagtail
# can tell, except with headings enriched with fragment ids.
RichText.__html__ = with_heading_ids

这样做效果很好,不需要任何乱七八糟或乱糟糟的黑客攻击,并且只需将此代码作为服务器启动过程的一部分加载就很容易启用/禁用(我们将它存放在我们的wagtailcustom_tags.py文件中,所以当Django加载所有模板标记集,RichText“浓缩”自动启动。

我们最初尝试扩展... | richtext模板过滤器,虽然这完全有可能,但这只适用于我们自己编写的自定义块,使用我们自己的自定义模板,因此结果不是一个解决方案,因为它应该“只是”工作”。


0
投票

那么使用RawHTMLBlockStreamField呢?制作一个这样的页面:

class BlogPage(Page):
    body = StreamField([
        ('tag', blocks.RawHTMLBlock(),
        ('body', blocks.RichTextBlock()),

然后在您的管理员中,您可以:

choose RawHTMLBlock: <h1 id="test">
choose RichTextBlock: your staff here
choose RawHTMLBlock: </h1>

0
投票

要控制页面主体的结构,最好鼓励用户使用标题块,而不是富文本块中的标题。然后你可以有一个标题块类型,它有两个字段,'text'和'id',你可以specify a template输出带有h属性的id元素。

class Heading2Block(blocks.StructBlock):
    heading = blocks.CharBlock(classname='full title')
    link_id = blocks.CharBlock(help_text='For making hyperlinks to this heading')

    class Meta:
        template = 'blocks/h2.html'

将以下内容放入blocks/h2.html

<h1{% if value.link_id %} id="{{ value.link_id|slugify }}"{% endif %}>{{ value.heading }}</h1>

在早期版本的Wagtail中,可以从Hallo.js富文本编辑器中删除h小部件,这是鼓励用户采用标题块的好方法。 Draftail目前没有类似的限制,但有一个pull request重新实现它。

© www.soinside.com 2019 - 2024. All rights reserved.