mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	Backed out the changes in [5482] for a bit whilst some more investigation into
side-effects is done. Refs #4565. git-svn-id: http://code.djangoproject.com/svn/django/trunk@5511 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
		| @@ -55,7 +55,6 @@ times with multiple contexts) | ||||
| '\n<html>\n\n</html>\n' | ||||
| """ | ||||
| import re | ||||
| import types | ||||
| from inspect import getargspec | ||||
| from django.conf import settings | ||||
| from django.template.context import Context, RequestContext, ContextPopException | ||||
| @@ -168,12 +167,9 @@ class Template(object): | ||||
|             for subnode in node: | ||||
|                 yield subnode | ||||
|  | ||||
|     def iter_render(self, context): | ||||
|         "Display stage -- can be called many times" | ||||
|         return self.nodelist.iter_render(context) | ||||
|  | ||||
|     def render(self, context): | ||||
|         return ''.join(self.iter_render(context)) | ||||
|         "Display stage -- can be called many times" | ||||
|         return self.nodelist.render(context) | ||||
|  | ||||
| def compile_string(template_string, origin): | ||||
|     "Compiles template_string into NodeList ready for rendering" | ||||
| @@ -699,26 +695,10 @@ def resolve_variable(path, context): | ||||
|             del bits[0] | ||||
|     return current | ||||
|  | ||||
| class NodeBase(type): | ||||
|     def __new__(cls, name, bases, attrs): | ||||
|         """ | ||||
|         Ensures that either a 'render' or 'render_iter' method is defined on | ||||
|         any Node sub-class. This avoids potential infinite loops at runtime. | ||||
|         """ | ||||
|         if not (isinstance(attrs.get('render'), types.FunctionType) or | ||||
|                 isinstance(attrs.get('iter_render'), types.FunctionType)): | ||||
|             raise TypeError('Unable to create Node subclass without either "render" or "iter_render" method.') | ||||
|         return type.__new__(cls, name, bases, attrs) | ||||
|  | ||||
| class Node(object): | ||||
|     __metaclass__ = NodeBase | ||||
|  | ||||
|     def iter_render(self, context): | ||||
|         return (self.render(context),) | ||||
|  | ||||
|     def render(self, context): | ||||
|         "Return the node rendered as a string" | ||||
|         return ''.join(self.iter_render(context)) | ||||
|         pass | ||||
|  | ||||
|     def __iter__(self): | ||||
|         yield self | ||||
| @@ -734,12 +714,13 @@ class Node(object): | ||||
|  | ||||
| class NodeList(list): | ||||
|     def render(self, context): | ||||
|         return ''.join(self.iter_render(context)) | ||||
|  | ||||
|     def iter_render(self, context): | ||||
|         bits = [] | ||||
|         for node in self: | ||||
|             for chunk in node.iter_render(context): | ||||
|                 yield chunk | ||||
|             if isinstance(node, Node): | ||||
|                 bits.append(self.render_node(node, context)) | ||||
|             else: | ||||
|                 bits.append(node) | ||||
|         return ''.join(bits) | ||||
|  | ||||
|     def get_nodes_by_type(self, nodetype): | ||||
|         "Return a list of all nodes of the given type" | ||||
| @@ -748,25 +729,24 @@ class NodeList(list): | ||||
|             nodes.extend(node.get_nodes_by_type(nodetype)) | ||||
|         return nodes | ||||
|  | ||||
|     def render_node(self, node, context): | ||||
|         return(node.render(context)) | ||||
|  | ||||
| class DebugNodeList(NodeList): | ||||
|     def iter_render(self, context): | ||||
|         for node in self: | ||||
|             if not isinstance(node, Node): | ||||
|                 yield node | ||||
|                 continue | ||||
|             try: | ||||
|                 for chunk in node.iter_render(context): | ||||
|                     yield chunk | ||||
|             except TemplateSyntaxError, e: | ||||
|                 if not hasattr(e, 'source'): | ||||
|                     e.source = node.source | ||||
|                 raise | ||||
|             except Exception, e: | ||||
|                 from sys import exc_info | ||||
|                 wrapped = TemplateSyntaxError('Caught an exception while rendering: %s' % e) | ||||
|                 wrapped.source = node.source | ||||
|                 wrapped.exc_info = exc_info() | ||||
|                 raise wrapped | ||||
|     def render_node(self, node, context): | ||||
|         try: | ||||
|             result = node.render(context) | ||||
|         except TemplateSyntaxError, e: | ||||
|             if not hasattr(e, 'source'): | ||||
|                 e.source = node.source | ||||
|             raise | ||||
|         except Exception, e: | ||||
|             from sys import exc_info | ||||
|             wrapped = TemplateSyntaxError('Caught an exception while rendering: %s' % e) | ||||
|             wrapped.source = node.source | ||||
|             wrapped.exc_info = exc_info() | ||||
|             raise wrapped | ||||
|         return result | ||||
|  | ||||
| class TextNode(Node): | ||||
|     def __init__(self, s): | ||||
| @@ -775,9 +755,6 @@ class TextNode(Node): | ||||
|     def __repr__(self): | ||||
|         return "<Text Node: '%s'>" % self.s[:25] | ||||
|  | ||||
|     def iter_render(self, context): | ||||
|         return (self.s,) | ||||
|  | ||||
|     def render(self, context): | ||||
|         return self.s | ||||
|  | ||||
| @@ -801,9 +778,6 @@ class VariableNode(Node): | ||||
|         else: | ||||
|             return output | ||||
|  | ||||
|     def iter_render(self, context): | ||||
|         return (self.render(context),) | ||||
|  | ||||
|     def render(self, context): | ||||
|         output = self.filter_expression.resolve(context) | ||||
|         return self.encode_output(output) | ||||
| @@ -892,9 +866,6 @@ class Library(object): | ||||
|             def __init__(self, vars_to_resolve): | ||||
|                 self.vars_to_resolve = vars_to_resolve | ||||
|  | ||||
|             #def iter_render(self, context): | ||||
|             #    return (self.render(context),) | ||||
|  | ||||
|             def render(self, context): | ||||
|                 resolved_vars = [resolve_variable(var, context) for var in self.vars_to_resolve] | ||||
|                 return func(*resolved_vars) | ||||
| @@ -917,7 +888,7 @@ class Library(object): | ||||
|                 def __init__(self, vars_to_resolve): | ||||
|                     self.vars_to_resolve = vars_to_resolve | ||||
|  | ||||
|                 def iter_render(self, context): | ||||
|                 def render(self, context): | ||||
|                     resolved_vars = [resolve_variable(var, context) for var in self.vars_to_resolve] | ||||
|                     if takes_context: | ||||
|                         args = [context] + resolved_vars | ||||
| @@ -933,7 +904,7 @@ class Library(object): | ||||
|                         else: | ||||
|                             t = get_template(file_name) | ||||
|                         self.nodelist = t.nodelist | ||||
|                     return self.nodelist.iter_render(context_class(dict)) | ||||
|                     return self.nodelist.render(context_class(dict)) | ||||
|  | ||||
|             compile_func = curry(generic_tag_compiler, params, defaults, getattr(func, "_decorated_function", func).__name__, InclusionNode) | ||||
|             compile_func.__doc__ = func.__doc__ | ||||
|   | ||||
| @@ -15,11 +15,12 @@ if not hasattr(__builtins__, 'reversed'): | ||||
|         for index in xrange(len(data)-1, -1, -1): | ||||
|             yield data[index] | ||||
|  | ||||
|  | ||||
| register = Library() | ||||
|  | ||||
| class CommentNode(Node): | ||||
|     def iter_render(self, context): | ||||
|         return () | ||||
|     def render(self, context): | ||||
|         return '' | ||||
|  | ||||
| class CycleNode(Node): | ||||
|     def __init__(self, cyclevars, variable_name=None): | ||||
| @@ -28,9 +29,6 @@ class CycleNode(Node): | ||||
|         self.counter = -1 | ||||
|         self.variable_name = variable_name | ||||
|  | ||||
|     def iter_render(self, context): | ||||
|         return (self.render(context),) | ||||
|  | ||||
|     def render(self, context): | ||||
|         self.counter += 1 | ||||
|         value = self.cyclevars[self.counter % self.cyclevars_len] | ||||
| @@ -39,32 +37,29 @@ class CycleNode(Node): | ||||
|         return value | ||||
|  | ||||
| class DebugNode(Node): | ||||
|     def iter_render(self, context): | ||||
|     def render(self, context): | ||||
|         from pprint import pformat | ||||
|         for val in context: | ||||
|             yield pformat(val) | ||||
|         yield "\n\n" | ||||
|         yield pformat(sys.modules) | ||||
|         output = [pformat(val) for val in context] | ||||
|         output.append('\n\n') | ||||
|         output.append(pformat(sys.modules)) | ||||
|         return ''.join(output) | ||||
|  | ||||
| class FilterNode(Node): | ||||
|     def __init__(self, filter_expr, nodelist): | ||||
|         self.filter_expr, self.nodelist = filter_expr, nodelist | ||||
|  | ||||
|     def iter_render(self, context): | ||||
|     def render(self, context): | ||||
|         output = self.nodelist.render(context) | ||||
|         # apply filters | ||||
|         context.update({'var': output}) | ||||
|         filtered = self.filter_expr.resolve(context) | ||||
|         context.pop() | ||||
|         return (filtered,) | ||||
|         return filtered | ||||
|  | ||||
| class FirstOfNode(Node): | ||||
|     def __init__(self, vars): | ||||
|         self.vars = vars | ||||
|  | ||||
|     def iter_render(self, context): | ||||
|         return (self.render(context),) | ||||
|  | ||||
|     def render(self, context): | ||||
|         for var in self.vars: | ||||
|             try: | ||||
| @@ -100,7 +95,8 @@ class ForNode(Node): | ||||
|         nodes.extend(self.nodelist_loop.get_nodes_by_type(nodetype)) | ||||
|         return nodes | ||||
|  | ||||
|     def iter_render(self, context): | ||||
|     def render(self, context): | ||||
|         nodelist = NodeList() | ||||
|         if 'forloop' in context: | ||||
|             parentloop = context['forloop'] | ||||
|         else: | ||||
| @@ -108,12 +104,12 @@ class ForNode(Node): | ||||
|         context.push() | ||||
|         try: | ||||
|             values = self.sequence.resolve(context, True) | ||||
|             if values is None: | ||||
|                 values = () | ||||
|             elif not hasattr(values, '__len__'): | ||||
|                 values = list(values) | ||||
|         except VariableDoesNotExist: | ||||
|             values = () | ||||
|             values = [] | ||||
|         if values is None: | ||||
|             values = [] | ||||
|         if not hasattr(values, '__len__'): | ||||
|             values = list(values) | ||||
|         len_values = len(values) | ||||
|         if self.reversed: | ||||
|             values = reversed(values) | ||||
| @@ -132,17 +128,12 @@ class ForNode(Node): | ||||
|                 'parentloop': parentloop, | ||||
|             } | ||||
|             if unpack: | ||||
|                 # If there are multiple loop variables, unpack the item into | ||||
|                 # them. | ||||
|                 # If there are multiple loop variables, unpack the item into them. | ||||
|                 context.update(dict(zip(self.loopvars, item))) | ||||
|             else: | ||||
|                 context[self.loopvars[0]] = item | ||||
|  | ||||
|             # We inline this to avoid the overhead since ForNode is pretty | ||||
|             # common. | ||||
|             for node in self.nodelist_loop: | ||||
|                 for chunk in node.iter_render(context): | ||||
|                     yield chunk | ||||
|                 nodelist.append(node.render(context)) | ||||
|             if unpack: | ||||
|                 # The loop variables were pushed on to the context so pop them | ||||
|                 # off again. This is necessary because the tag lets the length | ||||
| @@ -151,6 +142,7 @@ class ForNode(Node): | ||||
|                 # context. | ||||
|                 context.pop() | ||||
|         context.pop() | ||||
|         return nodelist.render(context) | ||||
|  | ||||
| class IfChangedNode(Node): | ||||
|     def __init__(self, nodelist, *varlist): | ||||
| @@ -158,7 +150,7 @@ class IfChangedNode(Node): | ||||
|         self._last_seen = None | ||||
|         self._varlist = varlist | ||||
|  | ||||
|     def iter_render(self, context): | ||||
|     def render(self, context): | ||||
|         if 'forloop' in context and context['forloop']['first']: | ||||
|             self._last_seen = None | ||||
|         try: | ||||
| @@ -176,9 +168,11 @@ class IfChangedNode(Node): | ||||
|             self._last_seen = compare_to | ||||
|             context.push() | ||||
|             context['ifchanged'] = {'firstloop': firstloop} | ||||
|             for chunk in self.nodelist.iter_render(context): | ||||
|                 yield chunk | ||||
|             content = self.nodelist.render(context) | ||||
|             context.pop() | ||||
|             return content | ||||
|         else: | ||||
|             return '' | ||||
|  | ||||
| class IfEqualNode(Node): | ||||
|     def __init__(self, var1, var2, nodelist_true, nodelist_false, negate): | ||||
| @@ -189,7 +183,7 @@ class IfEqualNode(Node): | ||||
|     def __repr__(self): | ||||
|         return "<IfEqualNode>" | ||||
|  | ||||
|     def iter_render(self, context): | ||||
|     def render(self, context): | ||||
|         try: | ||||
|             val1 = resolve_variable(self.var1, context) | ||||
|         except VariableDoesNotExist: | ||||
| @@ -199,8 +193,8 @@ class IfEqualNode(Node): | ||||
|         except VariableDoesNotExist: | ||||
|             val2 = None | ||||
|         if (self.negate and val1 != val2) or (not self.negate and val1 == val2): | ||||
|             return self.nodelist_true.iter_render(context) | ||||
|         return self.nodelist_false.iter_render(context) | ||||
|             return self.nodelist_true.render(context) | ||||
|         return self.nodelist_false.render(context) | ||||
|  | ||||
| class IfNode(Node): | ||||
|     def __init__(self, bool_exprs, nodelist_true, nodelist_false, link_type): | ||||
| @@ -225,7 +219,7 @@ class IfNode(Node): | ||||
|         nodes.extend(self.nodelist_false.get_nodes_by_type(nodetype)) | ||||
|         return nodes | ||||
|  | ||||
|     def iter_render(self, context): | ||||
|     def render(self, context): | ||||
|         if self.link_type == IfNode.LinkTypes.or_: | ||||
|             for ifnot, bool_expr in self.bool_exprs: | ||||
|                 try: | ||||
| @@ -233,8 +227,8 @@ class IfNode(Node): | ||||
|                 except VariableDoesNotExist: | ||||
|                     value = None | ||||
|                 if (value and not ifnot) or (ifnot and not value): | ||||
|                     return self.nodelist_true.iter_render(context) | ||||
|             return self.nodelist_false.iter_render(context) | ||||
|                     return self.nodelist_true.render(context) | ||||
|             return self.nodelist_false.render(context) | ||||
|         else: | ||||
|             for ifnot, bool_expr in self.bool_exprs: | ||||
|                 try: | ||||
| @@ -242,8 +236,8 @@ class IfNode(Node): | ||||
|                 except VariableDoesNotExist: | ||||
|                     value = None | ||||
|                 if not ((value and not ifnot) or (ifnot and not value)): | ||||
|                     return self.nodelist_false.iter_render(context) | ||||
|             return self.nodelist_true.iter_render(context) | ||||
|                     return self.nodelist_false.render(context) | ||||
|             return self.nodelist_true.render(context) | ||||
|  | ||||
|     class LinkTypes: | ||||
|         and_ = 0, | ||||
| @@ -254,16 +248,16 @@ class RegroupNode(Node): | ||||
|         self.target, self.expression = target, expression | ||||
|         self.var_name = var_name | ||||
|  | ||||
|     def iter_render(self, context): | ||||
|     def render(self, context): | ||||
|         obj_list = self.target.resolve(context, True) | ||||
|         if obj_list == None: # target_var wasn't found in context; fail silently | ||||
|             context[self.var_name] = [] | ||||
|             return () | ||||
|             return '' | ||||
|         # List of dictionaries in the format | ||||
|         # {'grouper': 'key', 'list': [list of contents]}. | ||||
|         context[self.var_name] = [{'grouper':key, 'list':list(val)} for key, val in | ||||
|             groupby(obj_list, lambda v, f=self.expression.resolve: f(v, True))] | ||||
|         return () | ||||
|         return '' | ||||
|  | ||||
| def include_is_allowed(filepath): | ||||
|     for root in settings.ALLOWED_INCLUDE_ROOTS: | ||||
| @@ -275,10 +269,10 @@ class SsiNode(Node): | ||||
|     def __init__(self, filepath, parsed): | ||||
|         self.filepath, self.parsed = filepath, parsed | ||||
|  | ||||
|     def iter_render(self, context): | ||||
|     def render(self, context): | ||||
|         if not include_is_allowed(self.filepath): | ||||
|             if settings.DEBUG: | ||||
|                 return ("[Didn't have permission to include file]",) | ||||
|                 return "[Didn't have permission to include file]" | ||||
|             else: | ||||
|                 return '' # Fail silently for invalid includes. | ||||
|         try: | ||||
| @@ -289,25 +283,23 @@ class SsiNode(Node): | ||||
|             output = '' | ||||
|         if self.parsed: | ||||
|             try: | ||||
|                 return Template(output, name=self.filepath).iter_render(context) | ||||
|                 t = Template(output, name=self.filepath) | ||||
|                 return t.render(context) | ||||
|             except TemplateSyntaxError, e: | ||||
|                 if settings.DEBUG: | ||||
|                     return "[Included template had syntax error: %s]" % e | ||||
|                 else: | ||||
|                     return '' # Fail silently for invalid included templates. | ||||
|         return (output,) | ||||
|         return output | ||||
|  | ||||
| class LoadNode(Node): | ||||
|     def iter_render(self, context): | ||||
|         return () | ||||
|     def render(self, context): | ||||
|         return '' | ||||
|  | ||||
| class NowNode(Node): | ||||
|     def __init__(self, format_string): | ||||
|         self.format_string = format_string | ||||
|  | ||||
|     def iter_render(self, context): | ||||
|         return (self.render(context),) | ||||
|  | ||||
|     def render(self, context): | ||||
|         from datetime import datetime | ||||
|         from django.utils.dateformat import DateFormat | ||||
| @@ -336,9 +328,6 @@ class TemplateTagNode(Node): | ||||
|     def __init__(self, tagtype): | ||||
|         self.tagtype = tagtype | ||||
|  | ||||
|     def iter_render(self, context): | ||||
|         return (self.render(context),) | ||||
|  | ||||
|     def render(self, context): | ||||
|         return self.mapping.get(self.tagtype, '') | ||||
|  | ||||
| @@ -348,18 +337,18 @@ class URLNode(Node): | ||||
|         self.args = args | ||||
|         self.kwargs = kwargs | ||||
|  | ||||
|     def iter_render(self, context): | ||||
|     def render(self, context): | ||||
|         from django.core.urlresolvers import reverse, NoReverseMatch | ||||
|         args = [arg.resolve(context) for arg in self.args] | ||||
|         kwargs = dict([(k, v.resolve(context)) for k, v in self.kwargs.items()]) | ||||
|         try: | ||||
|             return (reverse(self.view_name, args=args, kwargs=kwargs),) | ||||
|             return reverse(self.view_name, args=args, kwargs=kwargs) | ||||
|         except NoReverseMatch: | ||||
|             try: | ||||
|                 project_name = settings.SETTINGS_MODULE.split('.')[0] | ||||
|                 return reverse(project_name + '.' + self.view_name, args=args, kwargs=kwargs) | ||||
|             except NoReverseMatch: | ||||
|                 return () | ||||
|                 return '' | ||||
|  | ||||
| class WidthRatioNode(Node): | ||||
|     def __init__(self, val_expr, max_expr, max_width): | ||||
| @@ -367,9 +356,6 @@ class WidthRatioNode(Node): | ||||
|         self.max_expr = max_expr | ||||
|         self.max_width = max_width | ||||
|  | ||||
|     def iter_render(self, context): | ||||
|         return (self.render(context),) | ||||
|  | ||||
|     def render(self, context): | ||||
|         try: | ||||
|             value = self.val_expr.resolve(context) | ||||
| @@ -393,13 +379,13 @@ class WithNode(Node): | ||||
|     def __repr__(self): | ||||
|         return "<WithNode>" | ||||
|  | ||||
|     def iter_render(self, context): | ||||
|     def render(self, context): | ||||
|         val = self.var.resolve(context) | ||||
|         context.push() | ||||
|         context[self.name] = val | ||||
|         for chunk in self.nodelist.iter_render(context): | ||||
|             yield chunk | ||||
|         output = self.nodelist.render(context) | ||||
|         context.pop() | ||||
|         return output | ||||
|  | ||||
| #@register.tag | ||||
| def comment(parser, token): | ||||
|   | ||||
| @@ -87,12 +87,14 @@ def get_template_from_string(source, origin=None, name=None): | ||||
|     """ | ||||
|     return Template(source, origin, name) | ||||
|  | ||||
| def _render_setup(template_name, dictionary=None, context_instance=None): | ||||
| def render_to_string(template_name, dictionary=None, context_instance=None): | ||||
|     """ | ||||
|     Common setup code for render_to_string and render_to_iter. | ||||
|     Loads the given template_name and renders it with the given dictionary as | ||||
|     context. The template_name may be a string to load a single template using | ||||
|     get_template, or it may be a tuple to use select_template to find one of | ||||
|     the templates in the list. Returns a string. | ||||
|     """ | ||||
|     if dictionary is None: | ||||
|         dictionary = {} | ||||
|     dictionary = dictionary or {} | ||||
|     if isinstance(template_name, (list, tuple)): | ||||
|         t = select_template(template_name) | ||||
|     else: | ||||
| @@ -101,28 +103,7 @@ def _render_setup(template_name, dictionary=None, context_instance=None): | ||||
|         context_instance.update(dictionary) | ||||
|     else: | ||||
|         context_instance = Context(dictionary) | ||||
|     return t, context_instance | ||||
|  | ||||
| def render_to_string(template_name, dictionary=None, context_instance=None): | ||||
|     """ | ||||
|     Loads the given template_name and renders it with the given dictionary as | ||||
|     context. The template_name may be a string to load a single template using | ||||
|     get_template, or it may be a tuple to use select_template to find one of | ||||
|     the templates in the list. Returns a string. | ||||
|     """ | ||||
|     t, c = _render_setup(template_name, dictionary=dictionary, context_instance=context_instance) | ||||
|     return t.render(c) | ||||
|  | ||||
| def render_to_iter(template_name, dictionary=None, context_instance=None): | ||||
|     """ | ||||
|     Loads the given template_name and renders it with the given dictionary as | ||||
|     context. The template_name may be a string to load a single template using | ||||
|     get_template, or it may be a tuple to use select_template to find one of | ||||
|     the templates in the list. Returns a string. | ||||
|     """ | ||||
|     t, c = _render_setup(template_name, dictionary=dictionary, context_instance=context_instance) | ||||
|     return t.iter_render(c) | ||||
|  | ||||
|     return t.render(context_instance) | ||||
|  | ||||
| def select_template(template_name_list): | ||||
|     "Given a list of template names, returns the first that can be loaded." | ||||
|   | ||||
| @@ -15,14 +15,14 @@ class BlockNode(Node): | ||||
|     def __repr__(self): | ||||
|         return "<Block Node: %s. Contents: %r>" % (self.name, self.nodelist) | ||||
|  | ||||
|     def iter_render(self, context): | ||||
|     def render(self, context): | ||||
|         context.push() | ||||
|         # Save context in case of block.super(). | ||||
|         self.context = context | ||||
|         context['block'] = self | ||||
|         for chunk in self.nodelist.iter_render(context): | ||||
|             yield chunk | ||||
|         result = self.nodelist.render(context) | ||||
|         context.pop() | ||||
|         return result | ||||
|  | ||||
|     def super(self): | ||||
|         if self.parent: | ||||
| @@ -59,7 +59,7 @@ class ExtendsNode(Node): | ||||
|         else: | ||||
|             return get_template_from_string(source, origin, parent) | ||||
|  | ||||
|     def iter_render(self, context): | ||||
|     def render(self, context): | ||||
|         compiled_parent = self.get_parent(context) | ||||
|         parent_is_child = isinstance(compiled_parent.nodelist[0], ExtendsNode) | ||||
|         parent_blocks = dict([(n.name, n) for n in compiled_parent.nodelist.get_nodes_by_type(BlockNode)]) | ||||
| @@ -79,7 +79,7 @@ class ExtendsNode(Node): | ||||
|                 parent_block.parent = block_node.parent | ||||
|                 parent_block.add_parent(parent_block.nodelist) | ||||
|                 parent_block.nodelist = block_node.nodelist | ||||
|         return compiled_parent.iter_render(context) | ||||
|         return compiled_parent.render(context) | ||||
|  | ||||
| class ConstantIncludeNode(Node): | ||||
|     def __init__(self, template_path): | ||||
| @@ -91,26 +91,27 @@ class ConstantIncludeNode(Node): | ||||
|                 raise | ||||
|             self.template = None | ||||
|  | ||||
|     def iter_render(self, context): | ||||
|     def render(self, context): | ||||
|         if self.template: | ||||
|             return self.template.iter_render(context) | ||||
|         return () | ||||
|             return self.template.render(context) | ||||
|         else: | ||||
|             return '' | ||||
|  | ||||
| class IncludeNode(Node): | ||||
|     def __init__(self, template_name): | ||||
|         self.template_name = template_name | ||||
|  | ||||
|     def iter_render(self, context): | ||||
|     def render(self, context): | ||||
|         try: | ||||
|             template_name = resolve_variable(self.template_name, context) | ||||
|             t = get_template(template_name) | ||||
|             return t.iter_render(context) | ||||
|             return t.render(context) | ||||
|         except TemplateSyntaxError, e: | ||||
|             if settings.TEMPLATE_DEBUG: | ||||
|                 raise | ||||
|             return () | ||||
|             return '' | ||||
|         except: | ||||
|             return () # Fail silently for invalid included templates. | ||||
|             return '' # Fail silently for invalid included templates. | ||||
|  | ||||
| def do_block(parser, token): | ||||
|     """ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user