在Wagtail Editor Interface中显示基于布尔块的附加内容面板

时间:2016-09-10 21:48:42

标签: django django-models wagtail

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

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'),

]

(在我弄明白之后,我想知道我是否可以使它成为必需,但只有在检查了保持时,而不是整个streamblock)

{% 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 %}

1 个答案:

答案 0 :(得分:2)

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

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

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())
        ])
    ])

这里我在块类中添加了一个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>