 72b33ddbcd
			
		
	
	72b33ddbcd
	
	
	
		
			
			FAILED (failures=15, errors=15, skipped=1) AssertionError: 2 != 12 OfflineGenerationError: ... key "XYZ" missing ...
		
			
				
	
	
		
			155 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			155 lines
		
	
	
		
			5.8 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
| from __future__ import absolute_import
 | |
| from copy import copy
 | |
| 
 | |
| import django
 | |
| from django import template
 | |
| from django.conf import settings
 | |
| from django.template import Context
 | |
| from django.template.base import Node, VariableNode, TextNode, NodeList
 | |
| from django.template.defaulttags import IfNode
 | |
| from django.template.loader import get_template
 | |
| from django.template.loader_tags import ExtendsNode, BlockNode, BlockContext
 | |
| 
 | |
| 
 | |
| from compressor.exceptions import TemplateSyntaxError, TemplateDoesNotExist
 | |
| from compressor.templatetags.compress import CompressorNode
 | |
| 
 | |
| 
 | |
| def handle_extendsnode(extendsnode, block_context=None, original=None):
 | |
|     """Create a copy of Node tree of a derived template replacing
 | |
|     all blocks tags with the nodes of appropriate blocks.
 | |
|     Also handles {{ block.super }} tags.
 | |
|     """
 | |
|     if block_context is None:
 | |
|         block_context = BlockContext()
 | |
|     blocks = dict((n.name, n) for n in
 | |
|                   extendsnode.nodelist.get_nodes_by_type(BlockNode))
 | |
|     block_context.add_blocks(blocks)
 | |
| 
 | |
|     context = Context(settings.COMPRESS_OFFLINE_CONTEXT)
 | |
|     if original is not None:
 | |
|         context.template = original
 | |
| 
 | |
|     compiled_parent = extendsnode.get_parent(context)
 | |
|     parent_nodelist = compiled_parent.nodelist
 | |
|     # If the parent template has an ExtendsNode it is not the root.
 | |
|     for node in parent_nodelist:
 | |
|         # The ExtendsNode has to be the first non-text node.
 | |
|         if not isinstance(node, TextNode):
 | |
|             if isinstance(node, ExtendsNode):
 | |
|                 return handle_extendsnode(node, block_context, original)
 | |
|             break
 | |
|     # Add blocks of the root template to block context.
 | |
|     blocks = dict((n.name, n) for n in
 | |
|                   parent_nodelist.get_nodes_by_type(BlockNode))
 | |
|     block_context.add_blocks(blocks)
 | |
| 
 | |
|     block_stack = []
 | |
|     new_nodelist = remove_block_nodes(parent_nodelist, block_stack, block_context)
 | |
|     return new_nodelist
 | |
| 
 | |
| 
 | |
| def remove_block_nodes(nodelist, block_stack, block_context):
 | |
|     new_nodelist = NodeList()
 | |
|     for node in nodelist:
 | |
|         if isinstance(node, VariableNode):
 | |
|             var_name = node.filter_expression.token.strip()
 | |
|             if var_name == 'block.super':
 | |
|                 if not block_stack:
 | |
|                     continue
 | |
|                 node = block_context.get_block(block_stack[-1].name)
 | |
|                 if not node:
 | |
|                     continue
 | |
|         if isinstance(node, BlockNode):
 | |
|             expanded_block = expand_blocknode(node, block_stack, block_context)
 | |
|             new_nodelist.extend(expanded_block)
 | |
|         else:
 | |
|             # IfNode has nodelist as a @property so we can not modify it
 | |
|             if isinstance(node, IfNode):
 | |
|                 node = copy(node)
 | |
|                 for i, (condition, sub_nodelist) in enumerate(node.conditions_nodelists):
 | |
|                     sub_nodelist = remove_block_nodes(sub_nodelist, block_stack, block_context)
 | |
|                     node.conditions_nodelists[i] = (condition, sub_nodelist)
 | |
|             else:
 | |
|                 for attr in node.child_nodelists:
 | |
|                     sub_nodelist = getattr(node, attr, None)
 | |
|                     if sub_nodelist:
 | |
|                         sub_nodelist = remove_block_nodes(sub_nodelist, block_stack, block_context)
 | |
|                         node = copy(node)
 | |
|                         setattr(node, attr, sub_nodelist)
 | |
|             new_nodelist.append(node)
 | |
|     return new_nodelist
 | |
| 
 | |
| 
 | |
| def expand_blocknode(node, block_stack, block_context):
 | |
|     popped_block = block = block_context.pop(node.name)
 | |
|     if block is None:
 | |
|         block = node
 | |
|     block_stack.append(block)
 | |
|     expanded_nodelist = remove_block_nodes(block.nodelist, block_stack, block_context)
 | |
|     block_stack.pop()
 | |
|     if popped_block is not None:
 | |
|         block_context.push(node.name, popped_block)
 | |
|     return expanded_nodelist
 | |
| 
 | |
| 
 | |
| class DjangoParser(object):
 | |
|     def __init__(self, charset):
 | |
|         self.charset = charset
 | |
| 
 | |
|     def parse(self, template_name):
 | |
|         try:
 | |
|             if django.VERSION < (1, 8):
 | |
|                 return get_template(template_name)
 | |
|             else:
 | |
|                 return get_template(template_name).template
 | |
|         except template.TemplateSyntaxError as e:
 | |
|             raise TemplateSyntaxError(str(e))
 | |
|         except template.TemplateDoesNotExist as e:
 | |
|             raise TemplateDoesNotExist(str(e))
 | |
| 
 | |
|     def process_template(self, template, context):
 | |
|         return True
 | |
| 
 | |
|     def get_init_context(self, offline_context):
 | |
|         return offline_context
 | |
| 
 | |
|     def process_node(self, template, context, node):
 | |
|         pass
 | |
| 
 | |
|     def render_nodelist(self, template, context, node):
 | |
|         if django.VERSION >= (1, 8):
 | |
|             context.template = template
 | |
|         return node.nodelist.render(context)
 | |
| 
 | |
|     def render_node(self, template, context, node):
 | |
|         return node.render(context, forced=True)
 | |
| 
 | |
|     def get_nodelist(self, node, original=None):
 | |
|         if isinstance(node, ExtendsNode):
 | |
|             try:
 | |
|                 return handle_extendsnode(node, block_context=None, original=original)
 | |
|             except template.TemplateSyntaxError as e:
 | |
|                 raise TemplateSyntaxError(str(e))
 | |
|             except template.TemplateDoesNotExist as e:
 | |
|                 raise TemplateDoesNotExist(str(e))
 | |
| 
 | |
|         # Check if node is an ```if``` switch with true and false branches
 | |
|         nodelist = []
 | |
|         if isinstance(node, Node):
 | |
|             for attr in node.child_nodelists:
 | |
|                 nodelist += getattr(node, attr, [])
 | |
|         else:
 | |
|             nodelist = getattr(node, 'nodelist', [])
 | |
|         return nodelist
 | |
| 
 | |
|     def walk_nodes(self, node, original=None):
 | |
|         if django.VERSION >= (1, 8) and original is None:
 | |
|             original = node
 | |
|         for node in self.get_nodelist(node, original):
 | |
|             if isinstance(node, CompressorNode) and node.is_offline_compression_enabled(forced=True):
 | |
|                 yield node
 | |
|             else:
 | |
|                 for node in self.walk_nodes(node, original):
 | |
|                     yield node
 |