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)