在 Wagtail 编辑器界面中显示基于布尔块的附加内容面板

Display additional content panel based on boolean block in Wagtail Editor Interface

我想向我的 Wagtail 模型添加一个布尔值块,并仅在选中时显示内容面板字段。我已经想出如何添加一个布尔块并根据它的值在模板中呈现内容,但不知道如何用它来控制编辑器界面。这是我的模型。我想显示 heldover_from,日期选择器块,只有在选中保留布尔值时才显示。

class AgendaPage(Page):
author= models.CharField(max_length=255)
date = models.DateField('Post date')
agenda = StreamField([
    ('agenda_item', blocks.StreamBlock([
        ('item_title', blocks.TextBlock()),
        ('item_text', blocks.TextBlock()),
        ('mtg_doc', blocks.StructBlock([
            ('doc_description', blocks.TextBlock()),
            ('doc_link', blocks.TextBlock()),
            ('submitted_late', blocks.BooleanBlock(required=False, help_text='Submitted Late')),
            ('heldover', blocks.BooleanBlock(required=False, help_text='Held Over')),
            ('heldover_from', blocks.DateBlock(required=False, help_text="Held Over From")

        ]))
      ]
    ))
])




content_panels = Page.content_panels + [
    FieldPanel('author'),
    FieldPanel('date'),
    StreamFieldPanel('agenda'),

]

(在我弄清楚之后,我想知道我是否可以要求它,但前提是检查了保留,而不是整个流块)

{% for block in self.agenda %}
  {% if block.block_type == "agenda_item" %} {# will always be true, but included here for clarity #}
  <li>
    {% for subblock in block.value %}
        {% if subblock.block_type == "item_title" %}
            <h2>{{subblock.value}}</h2>
         {% elif subblock.block_type == "item_text" %}
                 <p>{{subblock.value}}</p>
         {% elif subblock.block_type == "mtg_doc" %}
                <p><a href="{{subblock.value.doc_link}}">{{subblock.value.doc_description}}</a><br />
            {% ifequal subblock.value.submitted_late True %}
             (Submitted Late)
            {% endifequal %}
                </p>
        {% endif %}
    {% endfor %}
</li>
  {% endif %}
{% endfor %}

您可以按照 http://docs.wagtail.io/en/v1.6.2/topics/streamfield.html#custom-editing-interfaces-for-structblock 中所述覆盖 StructBlock 的表单模板来执行此操作 - 尽管它确实需要摆弄表单标记的一些相当低级的细节。

首先,让我们将 mtg_doc 块定义拉出到它自己的 class 中以获得更多的喘息空间:

class MtgDocBlock(blocks.StructBlock):
    doc_description = blocks.TextBlock()
    doc_link = blocks.TextBlock()
    submitted_late = blocks.BooleanBlock(required=False, help_text='Submitted Late')
    heldover = blocks.BooleanBlock(required=False, help_text='Held Over')
    heldover_from = blocks.DateBlock(required=False, help_text="Held Over From")

    class Meta:
        form_template = 'myapp/block_forms/mtg_doc.html'


class AgendaPage(Page):
    ...
    agenda = StreamField([
        ('agenda_item', blocks.StreamBlock([
            ('item_title', blocks.TextBlock()),
            ('item_text', blocks.TextBlock()),
            ('mtg_doc', MtgDocBlock())
        ])
    ])

我在这里向块 class 添加了一个 form_template 参数,它指定了一个替代模板来代替 Wagtail 的内置模板来呈现表单。由于我们不想更改实际呈现,我们可以只包含内置模板(位于 wagtailadmin/block_forms/struct.html)并向其添加一些 JS 行为。在 templates/myapp/block_forms/mtg_doc.html:

{% include "wagtailadmin/block_forms/struct.html" %}

<script>
    // all fields of the block have a common prefix on the ID,
    // which is available as the template variable 'prefix'.
    // Retrieve the 'heldover' checkbox
    var checkbox = $('#{{ prefix }}-heldover');

    // Retrieve the 'li' element containing the 'heldover_from' field
    var field = $('#{{ prefix }}-alignment').closest('li');

    function showHideField() {
        // update the visibility of field according to the state of
        // the checkbox
        if (checkbox.is(':checked')) {
            field.show();
        } else {
            field.hide();
        }
    }
    // call showHideField immediately to reflect the initial state
    // of the checkbox
    showHideField();
    // trigger showHideField whenever the checkbox state is changed
    checkbox.change(showHideField);
</script>