templatesjinja2whitespace

Remove empty lines and don't join non-empty lines in Jinja


I want to make something like the following list of badges look nice:

Badge
{% if cond %}Other badge {% endif %}
Another badge
{% if not cond %}One more badge {% endif %}
Last badge

I am hoping for:

I tried 16 combinations of adding - to the {% or %} delimiters, but I can't achieve both things at once.

More details:

Related questions:


Solution

  • The thing is, the manual whitespace control mechanism treats a range of spacing characters the same, upon those characters are tabulations, spaces and new lines.

    For the record, the definition of a whitespace is given in Python's documentation:

    A character is whitespace if in the Unicode character database (see unicodedata), either its general category is Zs (“Separator, space”), or its bidirectional class is one of WS, B, or S.

    Source: https://docs.python.org/3/library/stdtypes.html#str.isspace


    This being said, it means you will probably not find a good one-liner solution, because using a whitespace control character will also chomp your new lines.

    The only one I can think of that would make you trick the whitespace control is to print the new line inside a Jinja expression:

    Badge
    {% if cond %}Other badge{{ "\n" }}{% endif -%}
    Another badge
    {% if not cond %}One more badge{{ "\n" }}{% endif -%}
    Last badge
    

    There are a bunch of other suggestion that are definitely more verbose that you can choose from, though, here are three that I can think of:

    1. Put the new line inside the condition and use a whitespace control on the end of the condition (which is actually kind-of the same as the one-liner):
      Badge
      {% if cond %}Other badge
      {% endif -%}
      Another badge
      {% if not cond %}One more badge
      {% endif -%}
      Last badge
      
    2. With the use of whitespace controls, you can end up with clear indentation in your conditions:
      Badge
      {% if cond -%}
          Other badge 
      {% endif -%}
      Another badge
      {% if not cond -%}
          One more badge 
      {% endif -%}
      Last badge 
      
      or keep it flat:
      Badge
      {% if cond -%}
      Other badge 
      {% endif -%}
      Another badge
      {% if not cond -%}
      One more badge 
      {% endif -%}
      Last badge 
      
    3. Without whitespace control characters, you'll have to start your condition on the previous line:
      Badge{% if cond %}
      Other badge{% endif %}
      Another badge{% if not cond %}
      One more badge{% endif %}
      Last badge
      
      or end the condition on the next line
      Badge
      {% if cond %}Other badge
      {% endif %}Another badge
      {% if not cond %}One more badge
      {% endif %}Last badge