# Using a Jinja2 variable in an "%include" statement

**URL:** <https://cylc.discourse.group/t/using-a-jinja2-variable-in-an-include-statement/363>\
**Category:** Cylc Support\
**Created:** [August 1, 2021, 9:50pm UTC](https://cylc.discourse.group/t/using-a-jinja2-variable-in-an-include-statement/363 "2021-08-01T21:50:08Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![funkapus](https://avatars.discourse-cdn.com/v4/letter/f/b19c9b/32.png) [@funkapus](https://cylc.discourse.group/u/funkapus)\
**Post date:** [August 1, 2021, 9:50pm UTC](https://cylc.discourse.group/t/using-a-jinja2-variable-in-an-include-statement/363/1 "2021-08-01T21:50:08Z")

</div>

Hi. I apologize profusely if the answer to this is spelled out in the docs – [cylc.github.io](http://cylc.github.io) is timing out for me right now.

My suite.rc uses platform-specific include files to handle things like batch queueing systems and parameters that vary from platform to platform. The way I’ve been handling it is to have a Jinja2 variable set at the top of the suite.rc, e.g.

```auto
{% set J_PLATFORM = "foo" %}

```

and then, near the bottom of the suite.rc, some lines that act based on the variable value:

```auto
# Platform dependence
{% if J_PLATFORM == "foo" %}
%include inc/platform_foo.cylcrc
{% elif J_PLATFORM == "bar" %}
%include inc/platform_bar.cylcrc
{% elif J_PLATFORM == "baz" %}
%include inc/platform_baz.cylcrc
{% else %}
    {{ raise('User-specified configuration variable J_PLATFORM has invalid value.') }}
{% endif %}

```

While this form has worked fine for me, it also meant that every time someone installed the system on a new platform, after creating an include file (let’s say, inc/platform\_mysys.cylcrc), it wasn’t enough that to just edit the top of suite.rc to set J\_PLATFORM to “mysys”. They also had to add  
an “elif” clause near the bottom to cover the new case as well.

So I wanted to replace the entire if/elif/endif block with something like this:

```auto
# Platform dependence
%include inc/platform_{{J_PLATFORM}}.cylcrc

```

Then, the only suite.rc change that would be required of the user installing our suite onto a new system would be to change what the J\_PLATFORM variable was set to. However, this doesn’t validate: I get a FileParseError message telling me "Include-file not found: inc/platform\_{{J\_PLATFORM}}.cylcrc, as if the Jinja2 engine is not substituting in the value for {{J\_PLATFORM}} prior to cylc examining the suite.rc contents. I don’t understand this, because I do it in other contexts in the same suite.rc, e.g.

```auto
{% set J_CP_CADENCE = "PT15M" %}

(stuff snipped)

[scheduling]
    [[dependencies]]
        (stuff snipped)
        [[[^+{{J_CP_CADENCE}}/{{J_CP_CADENCE}}]]]

```

and that works fine.

What am I missing?

Thanks!

---

<div class="post-metadata">

**Author:** ![funkapus](https://avatars.discourse-cdn.com/v4/letter/f/b19c9b/32.png) [@funkapus](https://cylc.discourse.group/u/funkapus)\
**Post date:** [August 2, 2021, 1:49am UTC](https://cylc.discourse.group/t/using-a-jinja2-variable-in-an-include-statement/363/2 "2021-08-02T01:49:44Z")

</div>

OK, some more investigation has shown me that it’s all about the include. If I just put a line that says nothing but

```auto
include inc/platform_{{J_PLATFORM}}.cylcrc

```

(i.e. no “%” at the beginning), then when the suite.rc fails to validate, it tells me

```auto
FileParseError:
Invalid line 1436: include inc/platform_foo.cylcrc

```

So in that case, it does the Jinja variable substitution. But if I precede that with a “%” sign, so that it becomes an actual include statement, the variable substitution doesn’t happen.

I’m guessing that what’s going on is that even though the docs said that the Jinja engine goes first, what _really_ goes first is the includes, because maybe the include files have Jinja code in them. If the Jinja engine ran first, and then the includes happened, then Jinja code in the include files would never get acted on. And that makes sense.

So now I’m wondering if what I want to do is even possible.

---

<div class="post-metadata">

**Author:** ![hilary.j.oliver](https://yyz2.discourse-cdn.com/free1/user_avatar/cylc.discourse.group/hilary.j.oliver/32/4_2.png) [@hilary.j.oliver](https://cylc.discourse.group/u/hilary.j.oliver)\
**Post date:** [August 2, 2021, 3:05am UTC](https://cylc.discourse.group/t/using-a-jinja2-variable-in-an-include-statement/363/3 "2021-08-02T03:05:42Z")

</div>

> [@funkapus](#):
>
> I’m guessing that what’s going on is that even though the docs said that the Jinja engine goes first, what _really_ goes first is the includes, because maybe the include files have Jinja code in them. If the Jinja engine ran first, and then the includes happened, then Jinja code in the include files would never get acted on. And that makes sense.

Yes you’re right. We should mention this in the docs, where `%include` is documented, and in the Jinja2 section. (Sorry for that omission!).

Fortunately, Jinja2 has its own template inclusion mechanism to do what you need:

```auto
#!Jinja2

{% set inc1 = "include.flow" %}
[scheduling]
...
{% include inc1 %}

```

---

<div class="post-metadata">

**Author:** ![hilary.j.oliver](https://yyz2.discourse-cdn.com/free1/user_avatar/cylc.discourse.group/hilary.j.oliver/32/4_2.png) [@hilary.j.oliver](https://cylc.discourse.group/u/hilary.j.oliver)\
**Post date:** [August 2, 2021, 3:08am UTC](https://cylc.discourse.group/t/using-a-jinja2-variable-in-an-include-statement/363/4 "2021-08-02T03:08:20Z")

</div>

(The native Cylc `%include` mechanism also predates our Jinja2 support, BTW)

---

<div class="post-metadata">

**Author:** ![oliver.sanders](https://yyz2.discourse-cdn.com/free1/user_avatar/cylc.discourse.group/oliver.sanders/32/110_2.png) [@oliver.sanders](https://cylc.discourse.group/u/oliver.sanders)\
**Post date:** [August 2, 2021, 8:59am UTC](https://cylc.discourse.group/t/using-a-jinja2-variable-in-an-include-statement/363/5 "2021-08-02T08:59:07Z")

</div>

Note: Jinja2 has both `import` and `include` blocks, you may want to add the `with context` keywords:

- [Template Designer Documentation — Jinja2 2.10 documentation](https://jinja2docs.readthedocs.io/en/stable/templates.html#include)
- [Template Designer Documentation — Jinja2 2.10 documentation](https://jinja2docs.readthedocs.io/en/stable/templates.html#import-visibility)
