This tag will invoke the specified method with the passed arguments.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | def iftrue(parser, token):
'''
call the given method with the specified arguments.
{% iftrue object.method arg, ... %}
....
{% else %}
....
{% endiftrue %}
{% iftrue object.method arg1=arg1,arg2=arg2 ... %}
....
'''
bits = list(token.split_contents())
if len(bits) < 2:
raise TemplateSyntaxError, "%r takes at least two 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()
object = bits[1]
args = []
kwargs = {}
bits = iter(bits[2:])
for bit in bits:
for arg in bit.split(","):
if '=' in arg:
k, v = arg.split('=', 1)
k = k.strip()
kwargs[k] = parser.compile_filter(v)
elif arg:
args.append(parser.compile_filter(arg))
return IfTrueNode(object, args, kwargs, nodelist_true, nodelist_false)
iftrue = register.tag(iftrue)
class IfTrueNode(Node):
def __init__(self, object, args, kwargs, nodelist_true, nodelist_false):
self.object, self.args, self.kwargs = object, args, kwargs
self.nodelist_true, self.nodelist_false = nodelist_true, nodelist_false
def __repr__(self):
return "<IfTrueNode>"
def render(self, context):
args = [arg.resolve(context) for arg in self.args]
kwargs = dict([(smart_str(k,'ascii'), v.resolve(context))
for k, v in self.kwargs.items()])
obj_p = self.object.split('.')
object = '.'.join(obj_p[:-1])
method = ''.join(obj_p[-1:])
obj = resolve_variable(object,context)
func = getattr(obj,method)
if func(*args, **kwargs):
return self.nodelist_true.render(context)
else:
return self.nodelist_false.render(context)
|
More like this
- Template tag - list punctuation for a list of items by shapiromatron 9 months ago
- JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 9 months, 1 week ago
- Serializer factory with Django Rest Framework by julio 1 year, 4 months ago
- Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 4 months ago
- Help text hyperlinks by sa2812 1 year, 5 months ago
Comments
This is cool; needed in core, I'd even say. It seems to be a staple of other templating systems, and separation of concerns aside, there's no shortage of uses for evaluating an "if" function that only affects the UI in the template itself. It took me a while to track down all of the imports for this, but while doing so I noticed that "resolve_variable" is deprecated (line 60). Locally I replaced it with obj = Variable(object).resolve(context) (where "Variable" is from django.templates), and it works as well, though I don't know if its better or worse yet.
#
Please login first before commenting.