Home > Back-end >  Macro causing white space in Jinja2?
Macro causing white space in Jinja2?

Time:04-22

I was expecting that this macro

{% macro join_them(first) -%}
    {% set data = [] %}
    {% if first not in ["", None, "None"] %}
        {{ data.append(first) }}
    {% endif %}
    {% for arg in varargs %}
        {% if arg not in ["", None, "None"] %}
            {{ data.append(arg) }}
        {% endif %}
    {% endfor %}
    {{' '.join(data)}}
{%- endmacro %}

Would render this

<td> * {{ join_them(docs["Author"]["Name"].title, docs["Author"]["Name"].first, docs["Author"]["Name"].middle, docs["Author"]["Name"].last, docs["Author"]["Name"].suffix) }}</td>

As this line, without the use of the macro, does

<td> * {{ ' '.join([docs["Author"]["Name"].title, docs["Author"]["Name"].first, docs["Author"]["Name"].middle, docs["Author"]["Name"].last, docs["Author"]["Name"].suffix])}}</td>

The non macro version is working fine, and outputing the name information correctly, but the Macro version is putting out white space and some "None" strings.

e.g.


           <td> *

    None







        None




Computer Community
            *</td>
            <td>Computer   Community </td>

Anyone have any suggestions on what I'm missing here? Or a better way to handle this? I don't typically use macros in Jinja2, but this seemed a perfect opportunity to do so.

CodePudding user response:

The macro is indeed causing those blank lines, and you had the right approach already, you need to use whitespace control to remove them. You only placed them at the beginning and the end of your macro but note that:

You can also strip whitespace in templates by hand. If you add a minus sign (-) to the start or end of a block, a comment, or a variable expression, the whitespaces before or after that block will be removed

Source: https://jinja.palletsprojects.com/en/3.1.x/templates/#whitespace-control, emphasis, mine

So, for each and every single block in your macro, you have to repeat this operation. To be extra sure, what you could do here is to frame any block in the macro with the minus sign.

Then for the None appearing, this is because you are using an expression delimiter {{ ... }} to append to your array, when you should use a statement delimiter {% ... %} and a do, as pointed in the documentation

If the expression-statement extension is loaded, a tag called do is available that works exactly like the regular variable expression ({{ ... }}); except it doesn’t print anything. This can be used to modify lists

{% do navigation.append('a string') %}

Source: https://jinja.palletsprojects.com/en/3.1.x/templates/#expression-statement

So, your macro should end up looking like:

{%- macro join_them() -%}
  {%- set data = [] -%}
  {%- for arg in varargs if arg not in ["", None, "None"] -%}
    {%- do data.append(arg) -%}
  {%- endfor -%}
  {{- ' '.join(data) -}}
{%- endmacro -%}

Note that, if you don't have the expression-statement extension loaded, you could also replace the {% do ... %} blocks by this inline-if 'hack':

{{- '' if data.append(arg) -}}
  • Related