在 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>
我想向我的 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>