Nunjucks: String interpolation options

Created on 25 Oct 2016  路  14Comments  路  Source: mozilla/nunjucks

I was wondering if there is already a solution in place for string interpolation.

If not can we put the following filter as a default nunjucks one? instead of adding it manually for each project?

I have the following template:

{# /index.html #}

<div>
   {{ message | interpolate }}
</div>

where ctx.message = "Hello {{ there }}";
and where ctx.there = "world!!!"

and I have added the following filter:

env.addFilter('interpolate', function(str) {
    return nunjucks.renderString(str, this.ctx)
})

output is: <div>Hello world!!!</div> not <div>Hello {{ there }}</div>

Most helpful comment

I kindly disagree string interpolation is not a niche case should be a standard but let's agree to disagree :)

All 14 comments

I haven't found a way to do that either. When I need string interpolation I use set to create a new variable from multiple pieces: strings and other variables. It's tedious but it works.

If only we could use ES6 String literals within Nunjucks...

What exactly you want to do?

Do you want to force rendering of a string, like this?

{% set tmpl = 'Hi {{ name }}' %}

{{ tmpl }}

And to make tmpl output Hi Nick, not Hi {{ name }}, right?

Yes exactly that. 馃憤

If you want to pass a nunjucks template string to a template and do a nested render then I think you are best off writing your own filter for that, because it seems like a rather niche case. But if you don't need to pass the template fragment into context you can use the {% set %} / {% endset %} tags:

var tmpl = `
{% set greeting %}Hello {{ name }}{% endset %}
{{ greeting }}
`;

nunjucks.renderString(tmpl, {'name': 'Nick'}); // outputs "Hello Nick"

I kindly disagree string interpolation is not a niche case should be a standard but let's agree to disagree :)

I support @fdintino, after using Nunjucks for years I can say that it is indeed quite a specific need.

Anyway, as far as I know, Jinja2 does not provide a built-in filter to do such thing.

Considering that, I recommend @valtido to open issue about such filter in Jinja2 repository. If it will be accepted there, surely it will appear in Nunjucks.

I think there might be some confusion. What was provided in the first example is not string interpolation but a nested render. That can generally be accomplished with a {% set %}{% endset %} block in most cases. Jinja2 has the | format filter (which uses python/printf string formatting), I think it would be logical to similarly support es6 template literals. But a filter that calls nunjucks.renderString is problematic. Does it use the calling nunjucks environment or a fresh environment? How do you pass options? Does it use a loader? Those questions make it difficult to write a general-purpose render filter.

Still missing this basic feature. Any update?

People who think string interpolation is a niche case, they should code more often!

I think there might be some confusion. What was provided in the first example is not string interpolation but a nested render. That can generally be accomplished with a {% set %}{% endset %} block in most cases. Jinja2 has the | format filter (which uses python/printf string formatting), I think it would be logical to similarly support es6 template literals. But a filter that calls nunjucks.renderString is problematic. Does it use the calling nunjucks environment or a fresh environment? How do you pass options? Does it use a loader? Those questions make it difficult to write a general-purpose render filter.

I think you spot on with that, es6 flavoured, I think at the time of raising this issue, I was confined with my line of thought as I was also a noob. however, to help a developer save precious time, you should implement es6 flavoured strings. Best of luck.

Same here. Any update on this?

Same here.

This "niche case" is literally the first thing I ran into

{{ `Changelog for ${project.name}` | center }}
Template render error: (unknown path) [Line 1, Column 15]
  expected variable end

Here's a neat little hack for a Jinja-like "format" filter using ES6 string templating, if you're feeling brave:

env.addFilter('format', str => {
    return (new Function('with (this) { return `' + str + '` }')).call(context)
})

This will let you do things like

{{ 'Changelog for ${project.name}' | format | center }}
Was this page helpful?
0 / 5 - 0 ratings

Related issues

dgirgenti picture dgirgenti  路  3Comments

boutell picture boutell  路  6Comments

ricordisamoa picture ricordisamoa  路  5Comments

thisKai picture thisKai  路  3Comments

sandiprb picture sandiprb  路  5Comments