Во-первых, я думаю, что ваш ArticleSectionBlock
может быть упрощен до:
class ArticleSectionBlock(blocks.StructBlock):
header = blocks.CharBlock(required=False))
content = blocks.RichTextBlock(required=False))
Ваш content
StreamField уже определен как список ArticleSectionBlock
с, поэтому нет необходимости в ArticleSectionBlock
быть самим списком.(Если вы действительно хотите, чтобы StreamField представлял собой список списков, ответ здесь по-прежнему применим, но вам необходимо настроить шаблон для использования вложенных циклов {% for %}
и помнить, что потомки ListBlock
don 'у него есть уникальные свойства id
.
В вашем шаблоне вы можете перебрать page.content
, чтобы получить список объектов блоков со свойствами value
, block_type
и id
, каждое из которых соответствуетодин ArticleSectionBlock
.Повторяя его дважды, вы можете вывести оглавление, за которым следует само содержимое:
<ul>
{% for block in page.content %}
<li><a href="#{{ block.id }}">{{ block.value.header }}</a></li>
{% endfor %}
</ul>
{% for block in page.content %}
<h1><a id="{{ block.id }}">{{ block.value.header }}</a></h1>
{{ block.value.content }}
{% endfor %}
В качестве альтернативы использованию block.id
в качестве идентификатора привязки, вы можете использовать {{ forloop.counter }}
.