Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support {% set %} statements #68

Closed
mchesser opened this issue Jun 17, 2022 · 5 comments · Fixed by #70
Closed

Support {% set %} statements #68

mchesser opened this issue Jun 17, 2022 · 5 comments · Fixed by #70

Comments

@mchesser
Copy link

Allowing set statements like jinja would help clean up some of the templates I have (e.g., conditionally building up a string which is used multiple times later in the template).

with statements can mostly be used as a workaround, however I've found this can get quite verbose in some cases.

@mitsuhiko
Copy link
Owner

I would be curious to see how you use it. I'm generally feeling these days that {% set %} creates a few annoying situations in Jinja and I try to avoid it nowadays. But maybe it really needs to still exist.

@mchesser
Copy link
Author

mchesser commented Jun 21, 2022

Part the reason I wanted this feature probably comes from from porting some code my own preprocessing code to minijina in the most direct way as possible. I'm not overly familiar with templating languages in general, and I have mostly just been using it a simple preprocessor, so I could be missing something simple here.

First to reuse the result of a complicated expression in multiple places:

{% set STDOUT_PATH = "{{ROOT_DIR}}/{{TASK_NAME}}/stdout" %}
{% set TAG = "{{TASK_NAME}}_{{ID}}" %}

run_1.sh --tag {{TAG}} >> {{STDOUT_PATH}}
run_2.sh --tag {{TAG}} >> {{STDOUT_PATH}}
run_3.sh >> {{STDOUT_PATH}}
run_4.sh >> {{STDOUT_PATH}}

Second, building flags from optional parameters:

{% set FLAGS = FLAGS ~ (" -a" if ENABLE_A %}
{% set FLAGS = FLAGS ~ (" -b" if ENABLE_B %}
{% set FLAGS = FLAGS ~ ((" --mode=" ~ MODE) if MODE) %}

The first case is no longer much of an issue thanks to #66 and the second case is fairly straightforward to solve by just chaining all the expressions together.

Overall, I don't really have a strong need -- I just looked at the Jinja reference for a feature that would work for what I wanted and wondered why it didn't exist.

@ScottBailey
Copy link

ScottBailey commented Jun 21, 2022

I would like to have set functionality and have been working on it a bit. My Rust skill is sorta meh so it's taking me some time.

That and I need to research how Jinja handles set - are they global or scoped?

https://github.com/ScottBailey/minijinja/tree/set

@mitsuhiko
Copy link
Owner

It shouldn't be too hard to implement. Just requires some refactoring on the scopes. I already simplified this a bit now with the introduction of unpacking in the {% with %} statement. Basically "just" needs that the other scopes also gain locals. In Jinja they are scoped to the module but the import statement can import the root scope. I don't want to implement import here though since there are also no macros in minijinja. if is the only statement which does not push a scope in Jinja which is already consistent with minijinja too.

@joshuataylor
Copy link
Sponsor Contributor

Nice!

A usecase for this is I am working on parsing files, similar to how dbt does (which uses Python/jinja). dbt uses set extensively to do things like assigning something to a variable -- see https://docs.getdbt.com/reference/dbt-jinja-functions/run_query (sorry, they don't have permalinks to headings).

It looks like this:

{% set results = run_query('select 1 as id') %}
{% do results.print_table() %}

It's very useful when you're giving developers jinja, you can do some very awesome stuff with just jinja & dbt without having to use Python.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants