En primer lugar, generalmente desea establecer variables de contexto dentro de su vista. Poner la lógica en la plantilla es realmente una fórmula para un desorden añadido. Dicho esto, llega un momento en que quieres usar esto, y la etiqueta {% with%} hace un lío de cosas ya que TIENES que terminar con un {% endwith%}, perdiendo la variable. El problema con el que me encontré es que no puedo incluir una plantilla mientras le paso un valor. Me gustaría hacer:
{% if criteria %}
{% define 'foo' as some_option %}
{% else %}
{% define 'bar' as some_option %}
{% endif %}
{% include "some_template_partial.html" %}
Ésta es imposible hacer uso de {%}% con etiquetas sin necesidad de código repetidos:
{% if criteria %}
{% with 'foo' as some_option %}
{% include "some_template_partial.html" %}
{% endwith %}
{% else %}
{% with 'bar' as some_option %}
{% include "some_template_partial.html" %}
{% endwith %}
{% endif %}
bien como está ahora, pero esto degradará en una horrible desastre a medida que proliferan los casos. Así, este código fue escrito:
from django import template
from django.conf import settings
import logging
import re
register = template.Library()
NAMESPACE_PROTECTION = settings.DEBUG
class define_node(template.Node):
def __init__(self, value, key, parse):
self.value = value
self.key = key
self.parse = parse
def render(self, context):
if NAMESPACE_PROTECTION:
if self.key in context:
raise Exception("EPIC NAMESPACE FAIL, CONTEXT HAZ A %s" % self.key)
if self.parse:
context[self.key] = context[self.value]
else:
context[self.key] = self.value
return ''
@register.tag
def define(parser, token):
"""Definition template tag. Use to define variables in your context within the template.
Sorta like the {% with "blah" as blah %} tag, but without the {% endwith %} mess.
Supports two modes:
Literal mode: argument is encapsulated with quotes (e.g. "blah" or 'blah')
variable, is set to the string literal, ex:
{% define "fish" as foo %}
Variable mode: argument is prefixed with a $ (e.g. $blah or $monkey)
variable is copied from another context variable, ex:
{% define $fish as foo %}
Namespace protection is also provided if django.conf.settings.DEBUG is True.
You will get an epic namespace fail if that occurs (please fix it before you deploy)
TODO:
* define override nomenclature if you REALLY want to overwrite a variable
- should decide what nomeclature to use first
* expand on variables so that {% define $array.blah as foo %} will work
(this currently WILL NOT)
"""
try:
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
value, key = m.groups()
if (value[0] == value[-1] and value[0] in ('"', "'")):
ret = value[1:-1]
parse = False
elif (value[0] == '$'):
ret = value[1:]
parse = True
else:
raise template.TemplateSyntaxError, "%r tag's first argument indeciperable" % tag_name
return define_node(ret, key, parse)
ve bien para mí. Tenga una etiqueta similar, la única diferencia es que utilicé register.tag ('define', define), pero la anotación no debería marcar la diferencia que usted esperaría. –
¿Quizás te encuentres con un conflicto de nombres? 'definir' parece peligroso ... –