Generated: Wed 2013-03-13 10:33 CET
Source file: /media/Envs/Envs/filer-gallery/lib/python2.7/site-packages/sekizai/helpers.py
Stats: 0 executed, 83 missed, 5 excluded, 48 ignored
# -*- coding: utf-8 -*-from django.conf import settingsfrom django.template import VariableNode, Variablefrom django.template.loader import get_templatefrom django.template.loader_tags import BlockNode, ExtendsNodedef is_variable_extend_node(node): if hasattr(node, 'parent_name_expr') and node.parent_name_expr: return True if hasattr(node, 'parent_name') and hasattr(node.parent_name, 'filters'): if node.parent_name.filters or isinstance(node.parent_name.var, Variable): return True return Falsedef _extend_blocks(extend_node, blocks): """ Extends the dictionary `blocks` with *new* blocks in the parent node (recursive) """ # we don't support variable extensions if is_variable_extend_node(extend_node): return parent = extend_node.get_parent(None) # Search for new blocks for node in parent.nodelist.get_nodes_by_type(BlockNode): if not node.name in blocks: blocks[node.name] = node else: # set this node as the super node (for {{ block.super }}) block = blocks[node.name] seen_supers = [] while hasattr(block.super, 'nodelist') and block.super not in seen_supers: seen_supers.append(block.super) block = block.super block.super = node # search for further ExtendsNodes for node in parent.nodelist.get_nodes_by_type(ExtendsNode): _extend_blocks(node, blocks) breakdef _extend_nodelist(extend_node): """ Returns a list of namespaces found in the parent template(s) of this ExtendsNode """ # we don't support variable extensions (1.3 way) if is_variable_extend_node(extend_node): return [] blocks = extend_node.blocks _extend_blocks(extend_node, blocks) found = [] for block in blocks.values(): found += _scan_namespaces(block.nodelist, block, blocks.keys()) parent_template = extend_node.get_parent({}) # if this is the topmost template, check for namespaces outside of blocks if not parent_template.nodelist.get_nodes_by_type(ExtendsNode): found += _scan_namespaces(parent_template.nodelist, None, blocks.keys()) else: found += _scan_namespaces(parent_template.nodelist, extend_node, blocks.keys()) return founddef _scan_namespaces(nodelist, current_block=None, ignore_blocks=None): from sekizai.templatetags.sekizai_tags import RenderBlock if ignore_blocks is None: ignore_blocks = [] found = [] for node in nodelist: # check if this is RenderBlock node if isinstance(node, RenderBlock): # resolve it's name against a dummy context found.append(node.kwargs['name'].resolve({})) found += _scan_namespaces(node.blocks['nodelist'], node) # handle {% extends ... %} tags if check_inheritance is True elif isinstance(node, ExtendsNode): found += _extend_nodelist(node) # in block nodes we have to scan for super blocks elif isinstance(node, VariableNode) and current_block: if node.filter_expression.token == 'block.super': if hasattr(current_block.super, 'nodelist'): found += _scan_namespaces(current_block.super.nodelist, current_block.super) return founddef get_namespaces(template): compiled_template = get_template(template) return _scan_namespaces(compiled_template.nodelist)def validate_template(template, namespaces): """ Validates that a template (or it's parents if check_inheritance is True) contain all given namespaces """ if getattr(settings, 'SEKIZAI_IGNORE_VALIDATION', False): return True found = get_namespaces(template) for namespace in namespaces: if namespace not in found: return False return Truedef get_varname(): return getattr(settings, 'SEKIZAI_VARNAME', 'SEKIZAI_CONTENT_HOLDER')class Watcher(object): """ Watches a context for changes to the sekizai data, so it can be replayed later. This is useful for caching. NOTE: This class assumes you ONLY ADD, NEVER REMOVE data from the context! """ def __init__(self, context): self.context = context self.frozen = dict((key, list(value)) for key, value in self.data.items()) @property def data(self): return self.context.get(get_varname(), {}) def get_changes(self): sfrozen = set(self.frozen) sdata = set(self.data) new_keys = sfrozen ^ sdata changes = {} for key in new_keys: changes[key] = list(self.data[key]) shared_keys = sfrozen & sdata for key in shared_keys: old_set = set(self.frozen[key]) new_values = [item for item in self.data[key] if item not in old_set] changes[key] = new_values return changes