Ticket #9154: #9154 - templates_optimizations.diff
File #9154 - templates_optimizations.diff, 5.5 KB (added by , 16 years ago) |
---|
-
django/template/loader_tags.py
1 import copy 2 1 3 from django.template import TemplateSyntaxError, TemplateDoesNotExist, Variable 2 from django.template import Library, Node, TextNode3 from django.template.loader import get_template , get_template_from_string, find_template_source4 from django.template import Library, Node, NodeList, TextNode 5 from django.template.loader import get_template 4 6 from django.conf import settings 5 7 from django.utils.safestring import mark_safe 6 8 … … 43 45 self.nodelist = nodelist 44 46 self.parent_name, self.parent_name_expr = parent_name, parent_name_expr 45 47 self.template_dirs = template_dirs 48 if self.parent_name_expr is None: 49 self.compiled_parent = copy.deepcopy(self.get_parent(context=None)) 50 else: 51 self.compiled_parent = None 46 52 47 53 def __repr__(self): 48 54 if self.parent_name_expr: … … 61 67 if hasattr(parent, 'render'): 62 68 return parent # parent is a Template object 63 69 try: 64 source, origin = find_template_source(parent, self.template_dirs)70 return get_template(parent, self.template_dirs) 65 71 except TemplateDoesNotExist: 66 72 raise TemplateSyntaxError, "Template %r cannot be extended, because it doesn't exist" % parent 67 else:68 return get_template_from_string(source, origin, parent)69 73 70 74 def render(self, context): 71 compiled_parent = self.get_parent(context) 75 if self.compiled_parent is not None: 76 compiled_parent = self.compiled_parent 77 else: 78 compiled_parent = self.get_parent(context) 72 79 parent_blocks = dict([(n.name, n) for n in compiled_parent.nodelist.get_nodes_by_type(BlockNode)]) 80 old_parent_nodelists = {} 81 added_extended_blocknodes = [] 73 82 for block_node in self.nodelist.get_nodes_by_type(BlockNode): 74 83 # Check for a BlockNode with this node's name, and replace it if found. 75 84 try: … … 86 95 # If the first non-text node is an extends, handle it. 87 96 if isinstance(node, ExtendsNode): 88 97 node.nodelist.append(block_node) 98 added_extended_blocknodes.append(block_node.name) 89 99 # Extends must be the first non-text node, so once you find 90 100 # the first non-text node you can stop looking. 91 101 break … … 93 103 # Keep any existing parents and add a new one. Used by BlockNode. 94 104 parent_block.parent = block_node.parent 95 105 parent_block.add_parent(parent_block.nodelist) 106 old_parent_nodelists[block_node.name] = parent_block.nodelist 96 107 parent_block.nodelist = block_node.nodelist 97 return compiled_parent.render(context) 108 rendered_string = compiled_parent.render(context) 109 # Restore every original parent nodelist to the state prior rendering it 110 for node_name, nodelist in old_parent_nodelists.items(): 111 parent_blocks[node_name].nodelist = nodelist 112 # Remove added BlockNodes to the parent's ExtendsNode 113 for node in compiled_parent.nodelist: 114 if not isinstance(node, TextNode): 115 if isinstance(node, ExtendsNode): 116 node.nodelist = NodeList(filter(lambda n: not isinstance(n, BlockNode) or n.name not in added_extended_blocknodes, node.nodelist)) 117 break 118 return rendered_string 98 119 99 120 class ConstantIncludeNode(Node): 100 121 def __init__(self, template_path): … … 156 177 uses the literal value "base" as the name of the parent template to extend, 157 178 or ``{% extends variable %}`` uses the value of ``variable`` as either the 158 179 name of the parent template to extend (if it evaluates to a string) or as 159 the parent temp ate itelf (if it evaluates to a Template object).180 the parent template itself (if it evaluates to a Template object). 160 181 """ 161 182 bits = token.split_contents() 162 183 if len(bits) != 2: -
django/template/loader.py
27 27 28 28 template_source_loaders = None 29 29 30 _template_cache = {} 31 30 32 class LoaderOrigin(Origin): 31 33 def __init__(self, display_name, loader, name, dirs): 32 34 super(LoaderOrigin, self).__init__(display_name) … … 73 75 pass 74 76 raise TemplateDoesNotExist, name 75 77 76 def get_template(template_name ):78 def get_template(template_name, dirs=None): 77 79 """ 78 80 Returns a compiled Template object for the given template name, 79 81 handling template inheritance recursively. 80 82 """ 81 source, origin = find_template_source(template_name) 82 template = get_template_from_string(source, origin, template_name) 83 if not settings.TEMPLATE_DEBUG and template_name in _template_cache: 84 template = _template_cache[template_name] 85 else: 86 source, origin = find_template_source(template_name, dirs) 87 template = get_template_from_string(source, origin, template_name) 88 _template_cache[template_name] = template 83 89 return template 84 90 85 91 def get_template_from_string(source, origin=None, name=None):