benjarwar benjarwar - 1 year ago 171
CSS Question

Wagtail/Django block doesn't render content properly from custom/nested StructBlock template

I have a block in the head of my base template that will render "extra" CSS. This CSS will be customized from fields coming in from a Wagtail CMS instance.

So, in the

base.html
template I have:

<head>
{% block extra_css %}{% endblock %}
</head>
<body>
{% block content %}{% endblock %}
</body>


Then, in my
detail.html
template, which extends off of the base, I have:

{% block content %}
{% for block in page.body %}
{{ block }}
{% endfor %}
{% endblock %}


body
is a
StreamField
in Wagtail. One of said fields is a custom
StructBlock
, the model of which is set up like so:

class CalloutBlock(blocks.StructBlock):
accent_color = blocks.CharBlock(required=False, label='Accent Color', help_text='HEX Value/Color')
class Meta:
template = 'inc/blocks/callout.inc.tpl'


Finally, in that
callout.inc.tpl
template, I am attempting to render a
<style>
tag that should get injected in my
extra_css
block:

{% block extra_css %}
<style>
.accent_color {
background-color: {{accent_color}} !important;
}
</style>
{% endblock %}


However, this block is not injected into the
<head>
as I'd expected. Instead, it renders in the body, like so, as if the
{% block extra_css %}
tag were not there at all:

<head>
</head>
<body>
<style>
.accent_color {
background-color: {{accent_color}} !important;
}
</style>
</body>


Is simply a limitation in Django templates? Is nesting the issue? Or is it because I'm using a custom template at the model level, and that's somehow outside the scope of the parent template parsing?

Django: 1.10

Wagtail: 1.6

Answer Source

This is a limitation in the way custom templates for StreamField blocks work. (There's a similar limitation in Django templating in general too, though - the {% block %} mechanism only works in conjunction with {% extends %}, not {% include %}.) The HTML content for the block is rendered in a separate call to the template engine, independently of the outer page template, so there's no way of passing control between the two.

(Note that Wagtail 1.6 introduces the {% include_block %} tag, which improves the situation a bit by making it possible to pass variables from the outer template's context to the block template. It still won't allow passing control from one to the other, though.)

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download