Как убедиться, что индивидуальный тег Jinja только один раз выводит?

StackOverflow https://stackoverflow.com/questions/3159156

  •  01-10-2019
  •  | 
  •  

Вопрос

У меня есть пользовательский тег в Jinja2, который я хочу выводить что-то только в первый раз, когда он называется. Так сказать, у меня есть следующий шаблон:

1. {% only_once %}
2. {% only_once %}
3. {% only_once %}

Я хочу, чтобы вывод был:

1. "I only get printed once!"
2.
3.

Я предполагаю, что лучший способ сделать это - установить флаг в контексте шаблона для отслеживания того, уже напечатал что-то или нет. Вот образец кода, но это правильно?

class OnlyOnceExtension(Extension):
    tags = set(['only_once'])

    @contextfunction
    def parse(self, context, parser):
        if hasattr(context, 'my_flag') and context.my_flag:
            return Output("")
        else:
            return Output("I only get printed once!")

Это правильно? Я прочитал некоторые вещи о контексте неизменно, так будет ли это не работать? (видеть http://jinja.pocoo.org/2/documentation/api. и поиск неизменных)

Это было полезно?

Решение

Мое предложение заключается в том, чтобы реализовать это в коде Python:

class OnlyOnce(object):
    def __init__(self, data):
        self.data = data
        self.printed = False

    def __str__(self):
        if self.printed is False:
            self.printed = True
            return self.data
        return ''

Создать OnlyOnce экземпляр в вашем коде Python и передайте его на шаблон, а затем каждый раз, когда вы хотите использовать его, просто используйте {{ only_once }}.

Одна вещь, которую я заметил о многих людях, использующих Jinja, - это то, что они хотят делать вещи в виде Джанго-острого, то есть написание расширений. Но выражения / импортирование детей Jinja / что бы ни было достаточно мощным, что вам не нужно использовать расширения для всего.

И да, используя context.my_flag вещь плохая идея. Только шаблон получает изменение контекста. КОГДА-ЛИБО.

Другие советы

Если вы хотите сделать это чисто с Jinja, вы можете просто проверить переменную Loop.index таким образом,

{% for bar in bars %}
    {% if loop.index == 1 %}
        Print me once
    {% endif %}
    Print me every time
{% endfor %}

Я бы определил булевую и макрос и уходил оттуда. Вместо печатать переменную, вы печатаете результат макроса, который использует оператор IF и Boolean, чтобы решить, должен ли оно печатать. Итак, вы получаете следующее:

{{ set was_printed = false }}
{% macro print_once(to_print) %}
    {% if was_printed is sameas false %}
        {{ to_print }}
        {% set was_printed = true %}
    {% endif %}
{% endmacro %}
1. {% print_once(only_once) %}
2. {% print_once(only_once) %}
3. {% print_once(only_once) %}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top