Nunjucks: How to use JavaScript code inside templates?

Created on 30 Jan 2016  路  7Comments  路  Source: mozilla/nunjucks

I was wondering whether there is a way to manipulate the template using JavaScript functions or statements inside nunjucks templating.

Suppose, for example, I have a nunjucks file where I need to apply different classes based on resolution and I have already have a function isMobile() which I am using in many places in JS files. So, I thought to use the same function inside the template file. something as shown below:

index.nunjucks

<body>
    <div class="{% if(isMobile()) { %}mobile-class {% else{ %} desktop-class {% } %}">
        <!-- content here -->
    </div>
</body>

Please help.

Most helpful comment

I do completely see the elegance of not having code logic inside your templates and for the majority of cases this is great. However, it would be nice if there was a specific tag or escape syntax that would allow you to evaluate code for the particular implementation's backing language, in this case JavaScript where nunjucks gets out of the way and just says, OK do your thing, then comes back.

For example, something simple like {{ eval( 'new Date()).getFullYear()') }} so it was intentionally inconvenient to write inline yet for small things, it made sense. The environment has the ability to evaluate string of code and requires escaping as well as being on a single line which promotes very tiny evaluations and makes long lines of inline code unmaintainable and ugly.

All 7 comments

index.nunjucks

<body>
    <div class="{% if isMobile() %}mobile-class{% else %}desktop-class{% endif %}">
        <!-- content here -->
    </div>
</body>

Then pass the function object to your environment's render() method:

env.render( 'index.nunjucks', { isMobile: isMobile } );

@ricordisamoa Thanks. This looks like an hack to me. Why can't I use JavaScript code in a straight way?

compiling is happening at runtime then definitely I must be able to use JavaScript straightforward right? (just like lodash templates)

It is just a doubt I have. :)

Why can't I use JavaScript code in a straight way?

https://github.com/mozilla/nunjucks/issues/419#issuecomment-97087967

Nunjucks is not JS, even if it looks like a subset sometimes.

https://github.com/mozilla/nunjucks/issues/650#issuecomment-175668301

You can call functions, but you can't run arbitrary JS code

hmm seems like a drawback for this template engine. Thanks.

Usually most of the logic is embedded in code, not templates. Compared with many other template engines, Nunjucks is quite powerful.

I do completely see the elegance of not having code logic inside your templates and for the majority of cases this is great. However, it would be nice if there was a specific tag or escape syntax that would allow you to evaluate code for the particular implementation's backing language, in this case JavaScript where nunjucks gets out of the way and just says, OK do your thing, then comes back.

For example, something simple like {{ eval( 'new Date()).getFullYear()') }} so it was intentionally inconvenient to write inline yet for small things, it made sense. The environment has the ability to evaluate string of code and requires escaping as well as being on a single line which promotes very tiny evaluations and makes long lines of inline code unmaintainable and ugly.

I want to create a ternary operator, like in Twig, where you can say if the variable exists, output it. Otherwise, output something else.

Here is the Twig syntax of what I'm trying to accomplish in the code example below:
bg_color ? bg_color : background--white
text_color ? text_color : text--black
text_align ? text_align : text--center

This is the code I have set up in my nunjucks:
How would I write the above statements in nunjucks syntax?

<section class="layout-container background--{{ bg_color }} text--{{ text_color }} text--{{ text_align }}">
    {% block content %} {% endblock %}
</section>

I've tried setting it up like so:
{% if bg_color %}background--{{ bg_color }}{% else %}background--white{% endif %}

I have two partials included in my index.njk file. If I set bg_color on the first partial... the second partial seems to inherit the styles from the partial before it.

I just want to be able to have a default background color of white for all partials, unless I set the bg_color variable.

{% set bg_color = "gray" %}
{% set text_color = "white" %}
{% set items = [
    {
      "heading"  : "Column 1",
      "content" : ""
    },
    {
      "heading"  : "Column 2",
      "content" : ""
    }
  ]
%}
{% include "partials/modules/module-two-column--content.njk" %}

<!-- even though bg_color and text_color have not been set, they are showing up as gray and white, which was what was set on the partial above this one-->
{% set items = [
    {
      "image_path" : "https://picsum.photos/1200/400",
      "alt" : "alt text",
      "card_title" : "This is the card title",
      "card_content" : "This is the card content",
      "card_link_url" : "#",
      "card_button" : "Button Text"
    },
    {
      "image_path" : "https://picsum.photos/1200/400",
      "alt" : "alt text",
      "card_title" : "This is the card title",
      "card_content" : "This is the card content",
      "card_link_url" : "#",
      "card_button" : "Button Text"
    }
  ]
%}
{% include "partials/modules/module-two-column--stacked-cards.njk" %}
Was this page helpful?
0 / 5 - 0 ratings

Related issues

kud picture kud  路  3Comments

sandiprb picture sandiprb  路  5Comments

ziir picture ziir  路  3Comments

thisKai picture thisKai  路  3Comments

atian25 picture atian25  路  5Comments