pythonyamljinja2templating-enginecookiecutter

How should I render YAML arrays neatly with cookiecutter?


I have a cookiecutter template that I want to render a YAML file based on some options.

As a simple example, suppose a rendered YAML file could look like this:

supported_databases:
  - mysql
  - postgres

And my cookiecutter JSON looked like this:

{
  "mysql": ["yes", "no"],
  "postgres": ["yes", "no"]
}

My YAML file is going to be horribly peppered with ifs to support all 4 valid combinations:

{%- if cookiecutter.mysql == 'yes' or cookiecutter.postgres == 'yes' %}
supported_databases:
{%- if cookiecutter.mysql == 'yes' %}
  - mysql
{%- endif %}
{%- if cookiecutter.mysql == 'yes' %}
  - postgres
{%- endif %}
{%- endif %}

The outer if is required to prevent invalid YAML being rendered in the case when both options are 'no'.

Is there a neater way to accomplish this?

Thanks for any help.


Solution

  • You can take advantage of YAML's flow style:

    supported_databases: [
      {% for db_type in ['mysql', 'postgres'] %}
        {% if cookiecutter[db_type] == 'yes' %}{{ db_type }},{% endif %}
      {% endfor %}
      ]
    

    If both options are no, this renders:

    supported_databases: [
      ]
    

    Which is valid YAML representing an empty sequence as value for supported_databases.

    With both options present, you get

    supported_databases: [
        mysql,
        postgres,
      ]
    

    Which is also valid YAML since unlike JSON, YAML allows a trailing comma in sequences. This YAML is semantically equivalent to the YAML you show in the question.

    Caution: Code untested.