from django.template import Library, Variable, Node
from django.template.loader import get_template
from django.template import TemplateSyntaxError
register = Library()
"""
Combines 'with' and 'include' to something useful:
For example:
{% partial "table_list.html" hot as urls and 1 as listid and "Hot items" as title %}
Will include the "table_list.html" file -- using the same include rules a django
and have the 'listid', 'urls', and 'title' variables set in the include context.
"""
class PartialNode(Node):
def __init__(self, path, is_constant, params):
self.params = params
self.tmpl = None
self.vtmpl = None
if is_constant :
try :
self.tmpl = get_template(path)
except :
if settings.TEMPLATE_DEBUG :
raise
else :
self.vtmpl = Variable(path)
def render(self, context):
tmpl = None
if self.tmpl :
tmpl = self.tmpl
elif self.vtmpl :
try :
t = self.vtmpl.resolve(context)
tmpl = get_template(t)
except TemplateSyntaxError, e :
if settings.TEMPLATE_DEBUG :
raise
return ''
except :
return '' # Fail silently for invalid included templates.
if not tmpl :
return ''
update = {}
for k, v in self.params.items() :
val = v.resolve(context)
print "V = ", v, val
update[k] = val
context.push()
context.update(update)
output = tmpl.render(context)
context.pop()
return output
def render_partial(parser, token):
params = {}
bits = token.split_contents()
if len(bits) < 2 :
raise TemplateSyntaxError("%r tag takes at least one argument: the name of the template to be included" % bits[0])
try:
path = bits[1]
state = 0
val = None
for p in bits[2:] :
if state == 0 :
val = p
state += 1
elif state == 1 :
if p.lower() != 'as' :
raise TemplateSyntaxError("%r expected format is 'value as name'" % bits[0])
state += 1
elif state == 2 :
params[p] = Variable(val)
state += 1
elif state == 3 :
if p.lower() != 'and' :
raise TemplateSyntaxError("%r expected format is 'value as name and'" % bits[0])
state = 0
except ValueError:
raise template.TemplateSyntaxError, '%r tag requires at least a single argument and no spaces in name:value list' % parts[0]
if path[0] in ('"', "'") and path[0] == path[-1] :
return PartialNode(path[1:-1], True, params)
return PartialNode(path, False, params)
render_partial = register.tag('partial', render_partial)
Comments