Как использовать переменную контекста при переходе к тегу шаблона - PullRequest
1 голос
/ 04 февраля 2020

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

class SetVarNode(template.Node):
     def __init__(self, new_val, var_name):
        self.new_val = new_val
        self.var_name = var_name

    def render(self, context):
        context[self.var_name] = self.new_val
        return ''

@register.tag
def setvar(parser, token):    
    # This version uses a regular expression to parse tag contents.
    try:
        # Splitting by None == splitting by spaces.
        tag_name, arg = token.contents.split(None, 1)
    except ValueError:
        raise template.TemplateSyntaxError(
            "%r tag requires arguments" % token.contents.split()[0]
        )
    m = re.search(r'(.*?) as (\w+)', arg)
    if not m:
        raise template.TemplateSyntaxError(
            "%r tag had invalid arguments" % tag_name
        )
    new_val, var_name = m.groups()
    if not (new_val[0] == new_val[-1] and new_val[0] in ('"', "'")):
        raise template.TemplateSyntaxError(
            "%r tag's argument should be in quotes" % tag_name
        )
    return SetVarNode(new_val[1:-1], var_name)

Это позволяет мне установить переменную один раз для использования в шаблоне: {% setvar "a string" as new_template_var %}

Как я могу изменить это, чтобы разрешить моей переменной объединяться с существующей контекстной переменной?

Например, я хочу передать context['var1'] в setvar как

{% setvar "a string {{ var1 }}" as new_template_var %}

, однако {{ var1 }} включается как строка, а не само значение переменной.

Ответы [ 2 ]

0 голосов
/ 04 февраля 2020

Простое решение: объединить вашу литеральную строку и вашу переменную с фильтром, ie:

{% setvar "a string"|add:var1 as new_template_var %}

, но вы должны правильно обрабатывать шаблоны Variable и FilterExpression в вашем узле, чтобы преобразовать имя переменной в ее текущее значение контекста.

Как говорится, это действительно не нужно (если у вас нет дополнительных требований или вы просто делаете это для целей обучения):

Наконец, если вам нужен только простой синтаксис для пользовательского тега шаблона обновления контекста, рассмотрите возможность использования ярлыка simple_tag (), который поддерживает присвоение результатов тега переменной шаблона.

(https://docs.djangoproject.com/en/3.0/howto/custom-template-tags/#setting -a-переменной-в-контексте )

0 голосов
/ 04 февраля 2020

В вашем SetVarNode.render(..) вам нужно будет инициировать его как шаблон и отобразить его с помощью context.

Не проверено:

class SetVarNode(template.Node):
    def __init__(self, new_val, var_name):
        self.new_val = new_val
        self.var_name = var_name

    def render(self, context):
        t = Template(self.new_val)
        value = t.render(context)
        context[self.var_name] = value
        return ''
...