Search code examples
jinja2

Remove unneeded whitespaces in Jinja template without HTML


I wrote a Jinja template:

ФИО: {{ fullname }}

{% for task, fact_hours, plan_hours in week_results %}
    {%- if fact_hours != 0 and plan_hours != 0 -%}
Задача №:{{ task.id }} "{{ task.name }}"
    Фактическое время: {{ fact_hours }}
    Планируемое время: {{ plan_hours }}
        {%- if fact_hours <= plan_hours %}
    Соответствует графику
        {%- else %}
    НЕ соответствует графику
        {%- endif +%}

    {% endif %}
{%- endfor %}

It's rendering data this way:

ФИО: Оксана Викторовна Абракадабровна

Задача №:511 "Доработки PlanFix"
    Фактическое время: 3.0
    Планируемое время: 3.0
    Соответствует графику

    Задача №:8710 "Аналитика поступлений и затрат"
    Фактическое время: 0.8
    Планируемое время: 2.0
    Соответствует графику

    Задача №:8753 "0. Сопровождение клиента"
    Фактическое время: 2.2
    Планируемое время: 2.5
    Соответствует графику

I want to reach this format:

ФИО: Оксана Владимировна Абракадабровна

Задача №:511 "Доработки PlanFix"
    Фактическое время: 3.0
    Планируемое время: 3.0
    Соответствует графику

Задача №:8710 "Аналитика поступлений и затрат"
    Фактическое время: 0.8
    Планируемое время: 2.0
    Соответствует графику

Задача №:8753 "0. Сопровождение клиента"
    Фактическое время: 2.2
    Планируемое время: 2.5
    Соответствует графику

In other words, I need to remove the tab before the first line of each loop iteration. By the way, I don't really understand why the tab doesn't show for the first iteration.
Can I reach this without using HTLM tags?

I tried to wrap the line in block and append -:

{%- block loop_item scoped -%}Задача №:{{ task.id }} "{{ task.name }}"{%- endblock -%}

but it seems like whitespace controls doesn't work on a block.

Caveat: it prints empty lines when {%- if fact_hours != 0 and plan_hours != 0 -%} is False.

So, I'm trying to print nothing in this case.
For example, with the template:

ФИО: {{ fullname }}

{% for task, fact_hours, plan_hours in week_results %}
    {%- if fact_hours != 0 and plan_hours != 0 -%}
Задача №:{{ task.id }} "{{ task.name }}"
    Фактическое время: {{ fact_hours }}
    Планируемое время: {{ plan_hours }}
        {%- if fact_hours <= plan_hours %}
    Соответствует графику
        {%- else %}
    НЕ соответствует графику
        {%- endif %}
    {%- else -%}
        {{ '' }}
    {% endif %}
{% endfor %}

It outputs:

ФИО: Оксана Владимировна Бабенко

Задача №:511 "Доработки PlanFix"
    Фактическое время: 3.0
    Планируемое время: 3.0
    Соответствует графику

    
Задача №:8710 "Аналитика поступлений и затрат"
    Фактическое время: 0.8
    Планируемое время: 2.0
    Соответствует графику
Задача №:8753 "0. Сопровождение клиента"
    Фактическое время: 2.2
    Планируемое время: 2.5
    Соответствует графику
Задача №:9381 "1. Разработка органиграммы компании с описанием функционала и разделением ответственности"
    Фактическое время: 2.5
    Планируемое время: 7.0
    Соответствует графику

    

    

    

    

    

    
Задача №:9416 "3. Создание рабочего календаря технического директора"
    Фактическое время: 1.7
    Планируемое время: 2.0
    Соответствует графику
Задача №:9417 "5. Сопровождение внедрения изменений в работу отдела продаж"
    Фактическое время: 0.8
    Планируемое время: 2.0
    Соответствует графику

    

    

    

    

Solution

  • This happens because of the whitespace control you added to the really last endfor, which is effectively removing the normal new line and leaves you with the spaces artificially created by the + in the {%- endif +%}.

    Remove them both and you should be good for that part.

    Then, to get rid of the blank lines when the condition if fact_hours != 0 and plan_hours != 0 is False, use a for ... if ... syntax.

    Unlike in Python, it’s not possible to break or continue in a loop. You can, however, filter the sequence during iteration, which allows you to skip items. The following example skips all the users which are hidden:

    {% for user in users if not user.hidden %}
        <li>{{ user.username|e }}</li>
    {% endfor %}
    

    Source: https://jinja.palletsprojects.com/en/3.0.x/templates/#for

    So, given the template:

    ФИО: {{ fullname }}
    
    {% 
      for task, fact_hours, plan_hours in week_results 
        if fact_hours != 0 and plan_hours != 0 
    -%}
    Задача №:{{ task.id }} "{{ task.name }}"
        Фактическое время: {{ fact_hours }}
        Планируемое время: {{ plan_hours }}
            {%- if fact_hours <= plan_hours %}
        Соответствует графику
            {%- else %}
        НЕ соответствует графику
            {%- endif %}
    
    {% endfor %}
    

    It effectively gives your expected output:

    ФИО: Оксана Викторовна Абракадабровна
    
    Задача №:511 "Доработки PlanFix"
        Фактическое время: 3.0
        Планируемое время: 3.0
        Соответствует графику
        
    Задача №:8710 "Аналитика поступлений и затрат"
        Фактическое время: 0.8
        Планируемое время: 2.0
        Соответствует графику
        
    Задача №:8753 "0. Сопровождение клиента"
        Фактическое время: 2.2
        Планируемое время: 2.5
        Соответствует графику