Здесь пример самодельного тега шаблонизатора django, выполняющего роль if-else-endif. Мой код подразумевает переменную 'current_statuskey' в контексте (кладётся напрямую или с помощью middleware). Писал для очень сложной страницы с кучей частей, имеющих разный вид в зависимости от статуса. Вообще там ещё у меня дополнительная логика, но это минимальный пример здесь. Использование в шаблоне:
{% ifstatus one,five,blabla %}
...
{% else %}
...
{% endifstatus %}
Можно было описать в десяток строк, но здесь больше и код очень сильно похож на стандартные теги ifequals и сопутствующие, откуда я его и адаптировал, чтобы получить более правильную и канонiчную реализацию.
from django.template.base import Node, NodeList, TemplateSyntaxError, Library
register = Library()
class IfStatusNode(Node):
child_nodelists = ('nodelist_true', 'nodelist_false')
def __init__(self, varlist, nodelist_true, nodelist_false, negate):
self.varlist = varlist
self.nodelist_true, self.nodelist_false = nodelist_true, nodelist_false
self.negate = negate
def __repr__(self):
return ""
def render(self, context):
current_statuskey = context.get('current_statuskey', None)
if (self.negate and current_statuskey not in self.varlist) or (not self.negate and current_statuskey in self.varlist):
return self.nodelist_true.render(context)
return self.nodelist_false.render(context)
def do_ifequal(parser, token, negate):
bits = list(token.split_contents())
if len(bits) != 2:
raise TemplateSyntaxError("%r takes one arguments" % bits[0])
end_tag = 'end' + bits[0]
nodelist_true = parser.parse(('else', end_tag))
token = parser.next_token()
if token.contents == 'else':
nodelist_false = parser.parse((end_tag,))
parser.delete_first_token()
else:
nodelist_false = NodeList()
#status1,status2
#"status1,status2, status3"
stats = bits[1]
if stats.startswith('"') and stats.endswith('"'):
stats = stats[1:-1]
varlist = [x.strip() for x in stats.split(',')]
return IfStatusNode(varlist, nodelist_true, nodelist_false, negate)
@register.tag
def ifstatus(parser, token):
"""
current_statuskey must be in request.
check that the status is one of the values separated by commas.
"""
return do_ifequal(parser, token, False)
@register.tag
def ifnotstatus(parser, token):
return do_ifequal(parser, token, True)
Комментариев нет:
Отправить комментарий