home ~ projects ~ socials

Change MiniJinja Variables Inside A Macro Via Namespaces

I'm using MiniJinjamj as the template engine for my static site builderneo. It's very powerful, but there aren't a lot of examples floating around for it. Something that took me a while to figure out was how to set a global variable for a page that I can update inside macros and/or for loop. It's not possible with the default scoping, but using a namespace.

Here's the approach I'm using:

```cargo
[dependencies]
minijinja = { version = "2.0.1", features = ["loader"] }
```

use minijinja::{Environment, context};

fn main() {
  let mut env = Environment::new();

  env.add_template_owned("page.jinja", r#"
{%- import "macros.jinja" as macros -%}
{%- set config = namespace() -%}
{%- set config.counter = 0 -%}

Before Marco: {{ config.counter }}
{{ macros.bump(config) }} 
After Marco: {{ config.counter }}

  "#.to_string()).unwrap();

  env.add_template_owned("macros.jinja", r#"
{%- macro bump(config_in_macro) -%}
{% for stub_example in ['a', 'b', 'c', 'd'] %}
{%- set config_in_macro.counter = config_in_macro.counter + 1 -%}
{% endfor %}
{%- endmacro -%}
  "#.to_string()).unwrap();

  let tmpl = env.get_template("page.jinja").unwrap();
  println!("{}", tmpl.render(context!()).unwrap());
}
Output:
Before Marco: 0
 
After Marco: 4
-- end of line --

References