Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Block assignment with {% set %}...{% endset %} #232

Closed
Xion opened this Issue · 6 comments

6 participants

@Xion

Currently, {% set %} allows only for assigning Jinja expressions to variables:

{% set foo = 'bar' %}

I propose expanding the syntax to allow for {% set %}{% endset %} block assignments:

{% set rawr %}
This is <strong>Sparta</strong>!
{% endset %}

As for rationale, this would allow for rendering {% block %} content into a variable (presumably as jinja2.Markup). Using Jinja powers, this would subsequently enable conditional and/or repeated inclusion of block content.

One extremely common application of this technique would be rendering page's titles/subtitles:

<head>
    {% block head %}
    <link rel="stylesheet" href="style.css" />
    <title>
        {% set title -%}
            {% block title %}{% endblock %}
        {%- endset %}
        {% if title %}{{ title }} -{% endif %}My Webpage
    </title>
    {% endblock %}
</head>

Incidentally, this is a modified example from Jinja docs. The original one has a bug and will always render the leading dash before "My Website", even if title block is empty. With block-level {% set %}, this problem can be amended.


Arguably, {% set %} block is not a very much needed feature because there is an existing workaround using an ad-hoc {% macro %}:

<head>
    {% block head %}
    <link rel="stylesheet" href="style.css" />
    <title>
        {% macro _title() -%}
            {% block title %}{% endblock %}
        {%- endmacro %}
        {% set title = _title() %}
        {% if title %}{{ title }} -{% endif %}My Webpage
    </title>
    {% endblock %}
</head>

What speaks in favor of {% set %} block, though, is that the above solution is clearly inelegant. There are also precedents in other templating engines, most notably the {let}{/let} block in Closure Templates.

@Osmose

A use case for this that I run into all the time is setting a variable to the value of a {% trans %} block. :+1:

@glombard

:+1: The macro workaround works OK but it can get messy, the set block assignment would be much nicer.

@malthe

Maintainer?

@mitsuhiko
Owner

This is implemented now. I think it's useful.

@mitsuhiko mitsuhiko closed this
@malthe

It would be cool to be able to easily wrap the result in Markup such that the variables can immediately be used in babel translations:

{{ _('Please click %(button)s', button=button) }}

I currently need to set app.jinja_env.globals['safe'] = Markup and use:

{{ _('Please click %(button)s', button=safe(button)) }}

The syntax might be something like:

{% set button | safe %}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.