我遇到了一个难题,希望 Wagtail 内部专家能够帮助我解决。我最终想要做的是将一个复杂的、嵌套的基于 StreamField 的页面呈现为纯文本/HTML,可用于搜索索引并在搜索结果页面上显示为片段。
问题在于,页面上的某些 block 不应该包含在搜索索引中,因为它们包含有关其他大部分不相关页面的元数据。因此,我不希望搜索页面 A 时显示仅引用页面 A 的结果。
我提出的解决方案是手动遍历 block 树并仅渲染 StreamField 中的某些类型的 block 。但是,虽然这对于 RichTextBlock
来说相对容易。 ,因为我可以从 block 字典中获取“值”字符串,所以对于我们的任何自定义 block 来说,这根本就不简单。
我想渲染单个 block 的 HTML,但我真的不知道如何做到这一点,如果这样的事情可能的话。在深入研究 StreamField 的渲染管道后,我最好的线索是我也许能够手动构建 BoundBlock
输入适当的数据,然后调用 render()
关于这一点。但我不太确定如何获取原始 block 字典并将其转换为 StreamValue
对于BoundBlock
构建自。如果这是正确的想法......
我还在研究一个反向解决方案,以防我只是在这里吠叫错误的树。我想我也许可以将特定的上下文变量传递到 StreamField.render_as_block(context)
在生成搜索索引的函数中,我可以对各个 block 进行编程来查找,然后在看到它时根本不渲染自己。如果我设法解决这个问题,我会更新这个问题。
最佳答案
我不知道我理解是否正确,但您可以迭代 StreamField 的 block 。一些例子:
block 定义:
class MyCustomImageBlock(StructBlock):
image = ImageChooserBlock()
caption = CharBlock()
class Meta:
template = '/blocks/image-with-caption.html'
icon = 'image'
class MyCarouselBlock(ListBlock):
class Meta:
template = '/blocks/custom-list.html'
icon = 'media'
带有标题的图像
自定义 StreamBlock 定义:
class MyCustomStreamBlock(StreamBlock):
some_image = MyCustomImageBlock()
image_carousel = MyCarouselBlock(child_block=MyCustomImageBlock)
页面定义:
class MyPage(Page):
content = StreamField(MyCustomStreamBlock())
模板
现在您可以简单地渲染 StreamField 的 block ,并使用 include_block 来渲染各个 block 。您也可以传递变量。
{% for block in page.content %}
{% include_block block with current_page=page %} # in case you want to render only something when on a certain page
{% endfor %}
我经常使用的一些技巧是: 创建一个仅包含 1 种类型的自定义 block 的自定义 StreamBlock。然后循环遍历一些变量以呈现内容编辑器为每个 block 定义的不同样式的数据:
{% for block in page.content %}
<!--
{% cycle 'right' 'left' as position %}
{% cycle 'primary' 'secondary' 'white' as color %}
-->
{% include_block block with pos=position color=color %}
{% endfor %}
关于wagtail - 如何渲染 StreamField 的单个子 block ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55148854/