How to convert a jinja templated yaml file to an equivalent jinja templated json file?

huangapple go评论56阅读模式
英文:

How to convert a jinja templated yaml file to an equivalent jinja templated json file?

问题

Sample yaml file:

foo:
{%- if USE_10 %}
  bar: 10
{%- else %}
  bar: 20
{%- endif %}

What I want:

"foo": {
{%- if USE_10 %}
  "bar" : 10
{%- else %}
  "bar" : 20
{%- endif %}
}
英文:

Given a yaml file that is jinja templated with {%- if condition %}s, {%- forloop %}s etc, how do you convert it into an equivalent json file that still has the jinja templates in the yaml file. Note that I know how to convert it into a rendered json file, after rendering the jinja-templated yaml file. However, producing a jinja-templated json file seems to be a much harder problem even for the case where we have only if-conditions. It seems that I have to build a template abstract syntax tree and evaluate every possible path, and then put back the templates. Any ideas?

Sample yaml file:

foo:
{%- if USE_10 %}
  bar: 10
{%- else %}
  bar: 20
{%- endif %}

What I want

"foo": {
{%- if USE_10 %}
  "bar" : 10
{%- else %}
  "bar" : 20
{%- endif %}
}

This is a very minimal example but the actual yaml file has a lot more jinja logic with for loops etc.

答案1

得分: 1

This task is very complex. Let's look at an example:

foo:
  - one
  - two
{%- if stuff %}
bar:
{%- endif %}
  - three

This places - three in an entirely new sequence if stuff evaluates to True. An equivalent transformation would look like this:

{
  "foo": [
    "one", "two"
{%- if stuff %}
  ],
  "bar": [
{%- else %},
{%- endif %}
    "three"
  ]
}

We now need an {% else %} branch which was not needed in YAML. This shows that such a transformation must be very aware of the generated structure.

So you would not only need to parse the Jinja commands into a syntax tree, you will also need to parse the YAML structure. Which is dependent on Jinja whitespace stripping.

And even if you happen to solve this task for {% if %}, think about having structural content in Jinja variables. You basically need to model the Jinja execution to be able to transform the template fully. Which may or may not be doable depending on whether Jinja is turing complete (I'm not entirely sure).

The bottom line is: Don't do this. It's immensely complex and even just sketching out how a correct solution might look like probably allows you to submit a paper to some fancy conference.

英文:

This task is very complex. Let's look at an example:

foo:
  - one
  - two
{%- if stuff %}
bar:
{%- endif %}
  - three

This places - three in an entirely new sequence if stuff evaluates to True. An equivalent transformation would look like this:

{
  "foo": [
    "one", "two"
{%- if stuff %}
  ],
  "bar": [
{%- else %},
{%- endif %}
    "three"
  ]
}

We now need an {% else %} branch which was not needed in YAML. This shows that such a transformation must be very aware of the generated structure.

So you would not only need to parse the Jinja commands into a syntax tree, you will also need to parse the YAML structure. Which is dependent on Jinja whitespace stripping.

And even if you happen to solve this task for {% if %}, think about having structural content in Jinja variables. You basically need to model the Jinja execution to be able to transform the template fully. Which may or may not be doable depending on whether Jinja is turing complete (I'm not entirely sure).

The bottom line is: Don't do this. It's immensely complex and even just sketching out how a correct solution might look like probably allows you to submit a paper to some fancy conference.

huangapple
  • 本文由 发表于 2023年4月13日 21:41:30
  • 转载请务必保留本文链接:https://go.coder-hub.com/76006160.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定