简体   繁体   中英

If Statement in Nunjucks Macro Not working

I'm new to Nunjucks. Am loving it so far but ran into an issue.

I just made a macro that will output a title & description. I also have if statement inside of my macro to show a particular div "if" I'm on a certain page.

My issue is that my "if statement" isn't working at all. Is it not possible to do a "if statement" in a macro like this? I know the if statement is working correctly. It works if I include the .njk template as an include. Here is an example:

{% macro titleInfo(title, description) %}

<div class="header-title text-white">
  <div class="container">
    <div class="row align-items-center">
      <div class="col-sm-12 col-lg-9">
        <h1>
          {{title}}
        </h1>
        <p>
          <small>
            {{description | safe}}
          </small>
        </p>
      </div> <!-- /.col -->
      {% if active_page == 'check' %} {# this isn't working right now #}
        <div class="col-sm-12 col-lg-3 text-lg-right frames-in-stock">
          <p>
            <strong>000</strong> of <strong>000</strong>
          </p>
        </div> <!-- /.col -->
      {% endif %}
    </div> <!-- /.row -->
  </div> <!-- /.container -->
</div> <!-- /.header-title -->

{% endmacro %}

I'm including the macro and implementing it on my page like so:

 {% extends "layout.njk" %}
 {% set active_page = "check" %}
 {% import "../templates/components/header-title.njk" as title %}
 {% block content %}

   {% include "components/header.njk" %}

   {# {% include "components/header-title.njk" %} #}

   {{
     title.titleInfo (
       'Your Inventory',
       'Please check all that apply.'
     )
   }}

  {% include "components/main-nav.njk" %}

{% endblock %}

Is it not possible to have an if statement in a macro? If it is possible, any direction on what I'm doing wrong would be great!

A macros doesn't have access to global scope when it define in separated file. You must pass active as variable to macros.

{% macro titleInfo(title, description, active) %} ...


Another way is using custom loader to substitution macros to main render page on run-time.

....
// rendered template
{% set active = true %}
{% enable SOMEMACRO %}
...
// somemacro.njk
{% macro SOMEMACRO %}
...
{% endmacro %}
...


// the custom loader implementation to support {% enable regexp-macro-name %}

let macros = fs.readdirSync('templates/macros')
    .reduce(function (res, f) { 
         res[f] = fs.readFileSync(`templates/macros/${f}`, 'utf8'); 
         return res;
    }, {});

let CustomLoader = nunjucks.FileSystemLoader.extend({
    getSource: function(name) {
        let result = nunjucks.FileSystemLoader.prototype.getSource.call(this, name);

        if (!result) 
            return null;

        result.src = result.src.replace(/{%\senable\s(\S+)\s%}/g, 
            function(str, match, offset, s){
                return Object.keys(macros)
                    .filter((key) => (new RegExp(match)).test(key))
                    .map((key) => macros[key] || '')
                    .join('\n');    
            }
        );

        return result;
    }
}); 

let env = new nunjucks.Environment(new CustomLoader(['templates/']), {autoescape: true});
env.express(app);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM