def do_random(parser, token): """ Output the contents of a random block. The `random` block tag must contain one or more `or` tags, which separate possible choices; a choice in this context is everything between a `random` and `or` tag, between two `or` tags, or between an `or` and an `endrandom` tag. Sample usage:: {% random %} You will see me half the time. {% or %} You will see <em>me</em> the other half. {% endrandom %} """ options = NodeList() while True: option = parser.parse(('or', 'endrandom')) token = parser.next_token() options.append(option) if token.contents == 'or': continue parser.delete_first_token() break if len(options) < 2: raise TemplateSyntaxError return RandomNode(options)
def angularjs(parser, token): """ Conditionally switch between AngularJS and Django variable expansion. Usage:: {% angularjs 1 %} or simply {% angularjs %} {% process variables through the AngularJS template engine %} {% endangularjs %} {% angularjs 0 %} {% process variables through the Django template engine %} {% endangularjs %} Instead of 0 and 1, it is possible to use a context variable. """ bits = token.contents.split() if len(bits) < 2: bits.append('1') values = [parser.compile_filter(bit) for bit in bits[1:]] django_nodelist = parser.parse(('endangularjs', )) angular_nodelist = NodeList() for node in django_nodelist: # convert all occurrences of VariableNode into a TextNode using the # AngularJS double curly bracket notation if isinstance(node, VariableNode): node = TextNode('{{ %s }}' % node.filter_expression.token) angular_nodelist.append(node) parser.delete_first_token() return AngularJsNode(django_nodelist, angular_nodelist, values[0])
def render(self, context): if 'forloop' in context: parentloop = context['forloop'] else: parentloop = {} context.push() try: values = self.sequence.resolve(context, True) except VariableDoesNotExist: values = [] if values is None: values = [] if not hasattr(values, '__len__'): values = list(values) len_values = len(values) if len_values < 1: context.pop() return self.nodelist_empty.render(context) nodelist = NodeList() if self.is_reversed: values = reversed(values) unpack = len(self.loopvars) > 1 # Create a forloop value in the context. We'll update counters on each # iteration just below. loop_dict = context['forloop'] = {'parentloop': parentloop} for i, item in enumerate(values): # Shortcuts for current loop iteration number. loop_dict['counter0'] = i loop_dict['counter'] = i+1 # Reverse counter iteration numbers. loop_dict['revcounter'] = len_values - i loop_dict['revcounter0'] = len_values - i - 1 # Boolean values designating first and last times through loop. loop_dict['first'] = (i == 0) loop_dict['last'] = (i == len_values - 1) pop_context = False if unpack: # If there are multiple loop variables, unpack the item into # them. try: unpacked_vars = dict(zip(self.loopvars, item)) except TypeError: pass else: pop_context = True context.update(unpacked_vars) else: context[self.loopvars[0]] = item for node in self.nodelist_loop: nodelist.append(node.render(context)) if pop_context: # The loop variables were pushed on to the context so pop them # off again. This is necessary because the tag lets the length # of loopvars differ to the length of each set of items and we # don't want to leave any vars from the previous loop on the # context. context.pop() context.pop() return nodelist.render(context)
def angularjs(parser, token): """ Conditionally switch between AngularJS and Django variable expansion. Usage:: {% angularjs 1 %} or simply {% angularjs %} {% process variables through the AngularJS template engine %} {% endangularjs %} {% angularjs 0 %} {% process variables through the Django template engine %} {% endangularjs %} Instead of 0 and 1, it is possible to use a context variable. """ bits = token.contents.split() if len(bits) < 2: bits.append('1') values = [parser.compile_filter(bit) for bit in bits[1:]] django_nodelist = parser.parse(('endangularjs',)) angular_nodelist = NodeList() for node in django_nodelist: # convert all occurrences of VariableNode into a TextNode using the # AngularJS double curly bracket notation if isinstance(node, VariableNode): node = TextNode('{{ %s }}' % node.filter_expression.token) angular_nodelist.append(node) parser.delete_first_token() return AngularJsNode(django_nodelist, angular_nodelist, values[0])
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 render(self, context): if 'forloop' in context: parentloop = context['forloop'] else: parentloop = {} context.push() try: values = self.sequence.resolve(context, True) except VariableDoesNotExist: values = [] if values is None: values = [] if not hasattr(values, '__len__'): values = list(values) len_values = len(values) if len_values < 1: context.pop() return self.nodelist_empty.render(context) nodelist = NodeList() if self.is_reversed: values = reversed(values) unpack = len(self.loopvars) > 1 # Create a forloop value in the context. We'll update counters on each # iteration just below. loop_dict = context['forloop'] = {'parentloop': parentloop} for i, item in enumerate(values): # Shortcuts for current loop iteration number. loop_dict['counter0'] = i loop_dict['counter'] = i + 1 # Reverse counter iteration numbers. loop_dict['revcounter'] = len_values - i loop_dict['revcounter0'] = len_values - i - 1 # Boolean values designating first and last times through loop. loop_dict['first'] = (i == 0) loop_dict['last'] = (i == len_values - 1) pop_context = False if unpack: # If there are multiple loop variables, unpack the item into # them. try: unpacked_vars = dict(zip(self.loopvars, item)) except TypeError: pass else: pop_context = True context.update(unpacked_vars) else: context[self.loopvars[0]] = item for node in self.nodelist_loop: nodelist.append(node.render(context)) if pop_context: # The loop variables were pushed on to the context so pop them # off again. This is necessary because the tag lets the length # of loopvars differ to the length of each set of items and we # don't want to leave any vars from the previous loop on the # context. context.pop() context.pop() return nodelist.render(context)
def slots_in_template(self, template): nodelist = NodeList() for node in template.template.nodelist: if (node.token.token_type == TokenType.BLOCK and node.token.split_contents()[0] == "slot"): nodelist.append(node) return nodelist
def __init__(self, loopvars, sequence, is_reversed, nodelist_headers, nodelist_loop, nodelist_empty=None): self.loopvars, self.sequence = loopvars, sequence self.is_reversed = is_reversed self.nodelist_headers, self.nodelist_loop = nodelist_headers, nodelist_loop if nodelist_empty is None: self.nodelist_empty = NodeList() else: self.nodelist_empty = nodelist_empty
def render(self, slots_filled=None, *args, **kwargs): slots_filled = slots_filled or [] context_args_variables = getfullargspec(self.context).args[1:] context_args = { key: kwargs[key] for key in context_args_variables if key in kwargs } context = self.context(**context_args) template = get_template(self.template(context)) slots_in_template = self.slots_in_template(template) if slots_in_template: valid_slot_names = set([slot.name for slot in slots_in_template]) nodelist = NodeList() for node in template.template.nodelist: if (node.token.token_type == TokenType.BLOCK and node.token.split_contents()[0] == "slot"): if node.name in valid_slot_names and node.name in slots_filled: nodelist.append(TextNode(slots_filled[node.name])) else: for node in node.nodelist: nodelist.append(node) else: nodelist.append(node) render_context = Context(context) with render_context.bind_template(template.template): return nodelist.render(render_context) return template.render(context)
def render(self, context): context.push(); kwargs = self.resolve_kwargs(context) items = Item.objects(type=kwargs['type']).order_by('-itemMeta.versionCreated')[:kwargs['length']] nodelist = NodeList() for item in items: context['item'] = item for node in self.nodelist: nodelist.append(node.render(context)) context.pop() return nodelist.render(context)
def render(self, context): context.push() nodelist = NodeList() kwargs = self.resolve_kwargs(context) limit = kwargs.get('limit', 55) start = kwargs.get('start', 0) order = kwargs.get('order', '-versionCreated') items = Item.objects(itemClass=kwargs['class'],publishedOn__ne=None).order_by(order)[start:limit] for item in items: context['item'] = item for node in self.nodelist: nodelist.append(node.render(context)) context.pop() return nodelist.render(context)
def render(self, context): context.push() items = self.get_items(context) nodelist = NodeList() context['package'] = context['item'] first = True for item in items: context['item'] = item context['first'] = first for node in self.nodelist: nodelist.append(node.render(context)) first = False context.pop() return nodelist.render(context)
def do_component_block(parser, token): """ To give the component access to the template context: {% component_block "name" positional_arg keyword_arg=value ... %} To render the component in an isolated context: {% component_block "name" positional_arg keyword_arg=value ... only %} Positional and keyword arguments can be literals or template variables. The component name must be a single- or double-quotes string and must be either the first positional argument or, if there are no positional arguments, passed as 'name'. """ bits = token.split_contents() bits, isolated_context = check_for_isolated_context_keyword(bits) tag_name, token = next_block_token(parser) component, context_args, context_kwargs = parse_component_with_args( parser, bits, 'component_block') slots_filled = NodeList() while tag_name != "endcomponent_block": if tag_name == "slot": slots_filled += do_slot(parser, token, component=component) tag_name, token = next_block_token(parser) return ComponentNode(component, context_args, context_kwargs, slots=slots_filled, isolated_context=isolated_context)
def do_if_can_change(parser, token): """ The ``{% if_can_change ocl_resource %}`` tag evaluates whether the current user has access to the specified OCL resource. The OCL resource can be an org, user, or any resource that contains "owner" and "owner_type" fields. Meaning sources, source versions, concepts, mappings are fine, but not extras, concept names/descriptions, concept versions, etc. :: {% if_can_change ocl_resource %} {% endif_can_change %} """ # NOTE: the obj_var can also be a source, org, mapping or concept obj_var = token.split_contents()[1] nodelist_true = parser.parse(('else', 'endif_can_change')) token = parser.next_token() if token.contents == 'else': nodelist_false = parser.parse(('endif_can_change', )) parser.delete_first_token() else: nodelist_false = NodeList() return IfCanChangeNode(nodelist_true, nodelist_false, obj_var)
def acl_app_filter(parser, token): """Templatetag for acl checking on applications.""" try: contents = token.split_contents() tag_name = contents[0] app_name = contents[1:] except ValueError: raise template.TemplateSyntaxError( "%r tag require 1 argument: an application" % token.contents.split()[0]) for name in app_name: if name not in sys.modules.keys(): raise template.TemplateSyntaxError( "%r is not a registered application for acl." % name) callback = get_callback(tag_name, app_name) oknodes = parser.parse(('acl_else', 'acl_end')) token = parser.next_token() if token.contents == 'acl_else': konodes = parser.parse(('acl_end')) token = parser.next_token() else: konodes = NodeList() assert token.contents == 'acl_end' return AclNode(callback, oknodes, konodes)
def acl_change_filter(parser, token): """Templatetag for acl checking a can_change_xxx function""" try: tag_content = token.split_contents() # tag_name = tag_content[0] model_name = tag_content[1] field_name = tag_content[2] args = tag_content[3:] except ValueError: raise template.TemplateSyntaxError( "%r tag require at least 2 argument: the model and the field" % token.contents.split()[0]) model = get_model(model_name) callback = getattr(model, 'can_change_' + field_name) # {% can_create %} oknodes = parser.parse(('acl_else', 'acl_end')) token = parser.next_token() # {% can_create_else %} if token.contents == 'acl_else': konodes = parser.parse(('acl_end')) token = parser.next_token() else: konodes = NodeList() # {% can_create_end %} assert token.contents == 'acl_end' return AclNode(callback, oknodes, konodes, *args)
def has_permission_to_url(parser, token): bits = list(token.split_contents()) if len(bits) < 2: raise TemplateSyntaxError( '"has_permission_to_url" takes minimal one argument') end_tag = 'end' + bits[0] kwargs = {} for bit in bits[2:]: match = kwarg_re.match(bit) if not match: raise TemplateSyntaxError( 'Malformed arguments to has_permission_to_url tag') name, value = match.groups() if name: kwargs[name] = parser.compile_filter(value) else: raise TemplateSyntaxError( 'Malformed arguments to has_permission_to_url tag') nodelist_true = parser.parse(('else', end_tag)) token = parser.next_token() if token.contents == 'else': nodelist_false = parser.parse((end_tag, )) parser.delete_first_token() else: nodelist_false = NodeList() return PermissionURLNode(parser.compile_filter(bits[1]), kwargs, nodelist_true, nodelist_false)
def acl_model_filter(parser, token): """Generic definition of an acl templatetag for acl based on model""" try: tag_content = token.split_contents() tag_name = tag_content[0] model_name = tag_content[1] args = tag_content[2:] except ValueError: raise template.TemplateSyntaxError( "%r tag require at least 1 argument: the model" % token.contents.split()[0]) model = get_model(model_name) callback = get_callback(tag_name, model) # {% can_create %} oknodes = parser.parse(('acl_else', 'acl_end')) token = parser.next_token() # {% can_create_else %} if token.contents == 'acl_else': konodes = parser.parse(('acl_end')) token = parser.next_token() else: konodes = NodeList() # {% can_create_end %} assert token.contents == 'acl_end' return AclNode(callback, oknodes, konodes, *args)
def acl_instance_filter(parser, token): """Generic definition of an acl templatetag for acl based on instance""" try: tag_content = token.split_contents() tag_name = tag_content[0] instance_name = tag_content[1] args = tag_content[2:] except ValueError: raise template.TemplateSyntaxError( "%r tag require at least 1 argument: the instance" % token.contents.split()[0]) # {% can_create %} oknodes = parser.parse(('acl_else', 'acl_end')) token = parser.next_token() # {% can_create_else %} if token.contents == 'acl_else': konodes = parser.parse(('acl_end')) token = parser.next_token() else: konodes = NodeList() # {% can_create_end %} assert token.contents == 'acl_end' return AclInstanceNode(tag_name, instance_name, oknodes, konodes, *args)
def render(self, context, slots_filled=None): slots_filled = slots_filled or {} template = get_template(self.template(context)) slots_in_template = self.slots_in_template(template) defined_slot_names = set(slots_in_template.keys()) filled_slot_names = set(slots_filled.keys()) unexpected_slots = filled_slot_names - defined_slot_names if unexpected_slots: if settings.DEBUG: warnings.warn( "Component {} was provided with unexpected slots: {}". format(self.__component_name, unexpected_slots)) for unexpected_slot in unexpected_slots: del slots_filled[unexpected_slot] combined_slots = dict(slots_in_template, **slots_filled) if combined_slots: # Replace slot nodes with their nodelists, then combine into a single, flat nodelist node_iterator = ([node] if not is_slot_node(node) else combined_slots[node.name] for node in template.template.nodelist) template = copy(template.template) template.nodelist = NodeList(chain.from_iterable(node_iterator)) else: template = template.template return template.render(context)
def compile_instance_template(self, template_name): """Use component's base template and the slots used for this instance to compile a unified template for this instance.""" component_template = get_template(template_name) slots_in_template = Component.slots_in_template(component_template) defined_slot_names = set(slots_in_template.keys()) filled_slot_names = set(self.slots.keys()) unexpected_slots = filled_slot_names - defined_slot_names if unexpected_slots: if settings.DEBUG: warnings.warn( "Component {} was provided with unexpected slots: {}".format( self._component_name, unexpected_slots ) ) for unexpected_slot in unexpected_slots: del self.slots[unexpected_slot] combined_slots = dict(slots_in_template, **self.slots) if combined_slots: # Replace slot nodes with their nodelists, then combine into a single, flat nodelist node_iterator = ([node] if not Component.is_slot_node(node) else combined_slots[node.name] for node in component_template.template.nodelist) instance_template = copy(component_template.template) instance_template.nodelist = NodeList(chain.from_iterable(node_iterator)) else: instance_template = component_template.template return instance_template
def render(self, context): from core.helper import get_request request = get_request() context['request'] = request context['wepo'] = request.wepo nodelist = NodeList() for node in self.nodelist_field: try: nodelist.append(node.render(context)) except Exception as e: if not hasattr(e, 'django_template_source'): e.django_template_source = node.source raise return nodelist.render(context)
def __init__(self, loopvars, sequence, is_reversed, nodelist_loop, nodelist_empty=None): self.loopvars, self.sequence = loopvars, sequence self.is_reversed = is_reversed self.nodelist_loop = nodelist_loop if nodelist_empty is None: self.nodelist_empty = NodeList() else: self.nodelist_empty = nodelist_empty
def get_node_list(parser, token, tag_name): nodelist_true = parser.parse(('else', 'end' + tag_name)) token = parser.next_token() if token.contents == 'else': nodelist_false = parser.parse(('end' + tag_name, )) parser.delete_first_token() else: nodelist_false = NodeList() return nodelist_true, nodelist_false
def if_local_session(parser, token): nodelist_true = parser.parse(('else', 'endif')) token = parser.next_token() if token.contents == 'else': nodelist_false = parser.parse(('endif',)) parser.delete_first_token() else: nodelist_false = NodeList() return IfLocalSession(nodelist_true, nodelist_false)
def _render_nodelist(self, nodelist, context): for node in nodelist: if self._can_render_node(node): node.render(context) elif hasattr(node, 'conditions_nodelists'): node.conditions_nodelists = [ (condition, NodeList([ node for node in nodelist if self._can_render_node(node) ])) for condition, nodelist in node.conditions_nodelists ] node.render(context) elif hasattr(node, 'nodelist'): node.nodelist = NodeList([ node for node in node.nodelist if self._can_render_node(node) ]) node.render(context)
def render(self, context): kwargs = {key: value.resolve(context) for key, value in self.kwargs.items()} try: if 'template_name_var' in kwargs: extending_template = get_template(kwargs.get('template_name_var')) else: extending_template = get_template(self.template_name.resolve()) except: return '' if self.only: flattened_context = kwargs else: flattened_context = context.flatten() flattened_context.update(kwargs) nodelist_changed = False new_nodelist = self.get_node_list(extending_template.template.nodelist) if 'block' in kwargs: block_nodes = self.get_all_blocks(new_nodelist) new_nodelist = NodeList( [node for node in block_nodes if node.name == kwargs.get('block')] ) new_nodelist.contains_nontext = True nodelist_changed = True if self.multiline: blocks = {node.name: node for node in self.nodelist if isinstance(node, BlockNode)} self.rearrange_blocks(new_nodelist, blocks) nodelist_changed = True # This is because there can also be cache loader for template. And if in template loaded with such loader nodes # are changed, they are changed in next iteration also. # So now I load template from empty string and give him changed nodelist. So I don't change original template if nodelist_changed: extending_template = template_from_string('', None) extending_template.template.nodelist = new_nodelist content = extending_template.render(flattened_context) content = mark_safe(content) return content
def _if_feature(parser, token, enabled_first): """Common implementation for feature-based if statements. This constructs a :py:class:`IfFeatureNode` for the consuming template tag, allowing for "if" and "if not" checks. Args: parser (django.template.Parser): The parser being used to parse this template tag. token (django.template.Token): The token representing this template tag. enabled_first (bool): If ``True``, this behaves as an "if enabled" check. If ``False``, this behaves as a "if disabled' check. Returns: IfFeatureNode: The feature checker node to use for the template. """ bits = token.split_contents() tag = bits[0] end_tag = 'end%s' % tag if len(bits) < 2: raise TemplateSyntaxError('%r requires a feature ID argument' % tag) nodelist_1 = parser.parse(('else', end_tag)) token = parser.next_token() if token.contents == 'else': nodelist_2 = parser.parse((end_tag, )) parser.delete_first_token() else: nodelist_2 = NodeList() if enabled_first: nodelist_enabled = nodelist_1 nodelist_disabled = nodelist_2 else: nodelist_disabled = nodelist_1 nodelist_enabled = nodelist_2 feature_id = parser.compile_filter(bits[1]) remaining_bits = bits[2:] extra_kwargs = token_kwargs(remaining_bits, parser) if remaining_bits: raise TemplateSyntaxError('%r received an invalid token: %r' % (tag, remaining_bits[0])) return IfFeatureNode(nodelist_enabled, nodelist_disabled, feature_id, extra_kwargs)
def open_registration(parser, token): nodelist_true = parser.parse(('else', 'endopen_registration')) token = parser.next_token() if token.contents == 'else': nodelist_false = parser.parse(('endopen_registration', )) parser.delete_first_token() else: nodelist_false = NodeList() return OpenRegistrationNode(OPEN_REG, nodelist_true, nodelist_false)
def do_component(parser, token): """ {% component_block "name" variable="value" variable2="value2" ... %} """ bits = token.split_contents() tag_args, tag_kwargs = parse_bits( parser=parser, bits=bits, params=["tag_name", "component_name"], takes_context=False, name="component_block", **PARSE_BITS_DEFAULTS ) tag_name = tag_args.pop(0) if len(bits) < 2: raise TemplateSyntaxError( "Call the '%s' tag with a component name as the first parameter" % tag_name ) component_name = bits[1] if not component_name.startswith(('"', "'")) or not component_name.endswith( ('"', "'") ): raise TemplateSyntaxError( "Component name '%s' should be in quotes" % component_name ) component_name = component_name.strip('"\'') component_class = registry.get(component_name) component = component_class() extra_context = {} if len(bits) > 2: extra_context = component.context(**token_kwargs(bits[2:], parser)) slots_filled = NodeList() tag_name = bits[0] while tag_name != "endcomponent_block": token = parser.next_token() if token.token_type != TokenType.BLOCK: continue tag_name = token.split_contents()[0] if tag_name == "slot": slots_filled += do_slot(parser, token, component=component) elif tag_name == "endcomponent_block": break return ComponentNode(component, extra_context, slots_filled)
def render(self, context): section = self.section.resolve(context, True) page = self.page.resolve(context, True) import json page_blocks = page.blocks if page and page.blocks else [] page_section = page_blocks[section] if section in page_blocks else [] nodelist = NodeList() context[self.output_var] = page_section for node in self.nodelist_field: try: nodelist.append(node.render(context)) except Exception as e: if not hasattr(e, 'django_template_source'): e.django_template_source = node.source raise return nodelist.render(context)
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 render(self, context): permissions = [permission.resolve(context, True) for permission in self.permissions] # # check if has permissions # from core.helper import get_request from core.permission import check_permissions status, action = check_permissions(get_request(), permissions) nodelist = NodeList() if status: for node in self.nodelist_permission: try: nodelist.append(node.render(context)) except Exception as e: if not hasattr(e, 'django_template_source'): e.django_template_source = node.source raise else: if self.nodelist_nopermission: for node in self.nodelist_nopermission: try: nodelist.append(node.render(context)) except Exception as e: if not hasattr(e, 'django_template_source'): e.django_template_source = node.source raise return nodelist.render(context)
def do_ifinstalled(parser, token, negate): bits = list(token.split_contents()) if len(bits) != 2: raise TemplateSyntaxError("%r takes one argument" % bits[0]) end_tag = 'end' + bits[0] nodelist_true = parser.parse(('else', end_tag)) token = parser.next_token() if token.contents == 'else': nodelist_false = parser.parse((end_tag, )) parser.delete_first_token() else: nodelist_false = NodeList() app = parser.compile_filter(bits[1]) return IfInstalledNode(app, nodelist_true, nodelist_false, negate)
def do_ifequal(parser, token, negate): bits = list(token.split_contents()) if len(bits) != 3: raise TemplateSyntaxError("%r takes two arguments" % bits[0]) end_tag = 'end' + bits[0] nodelist_true = parser.parse(('else', end_tag)) token = parser.next_token() if token.contents == 'else': nodelist_false = parser.parse((end_tag, )) parser.delete_first_token() else: nodelist_false = NodeList() val1 = parser.compile_filter(bits[1]) val2 = parser.compile_filter(bits[2]) return IfEqualNode(val1, val2, nodelist_true, nodelist_false, negate)
def do_ifgroupperm(parser, token): bits = list(token.split_contents()) if len(bits) != 3: raise TemplateSyntaxError("%r takes two arguments" % bits[0]) end_tag = 'end' + bits[0] nodelist_true = parser.parse(('else', end_tag)) token = parser.next_token() if token.contents == 'else': nodelist_false = parser.parse((end_tag,)) parser.delete_first_token() else: nodelist_false = NodeList() group_obj = parser.compile_filter(bits[1]) perm_id = parser.compile_filter(bits[2]) return IfGroupPermNode(group_obj, perm_id, nodelist_true, nodelist_false)
def acl_history_filter(parser, token): """Templatetag for acl checking on history.""" tag_name, = token.split_contents() callback = get_callback(tag_name) oknodes = parser.parse(('acl_else', 'acl_end')) token = parser.next_token() if token.contents == 'acl_else': konodes = parser.parse(('acl_end')) token = parser.next_token() else: konodes = NodeList() assert token.contents == 'acl_end' return AclNode(callback, oknodes, konodes)
def parse_through(self, parse_until=None): if parse_until is None: parse_until = [] nodelist = NodeList() while self.tokens: token = self.next_token() if six.PY2: contents = token.contents.encode('utf8') else: contents = token.contents if token.token_type == TokenType.TEXT: self.dest_stream.write(contents) elif token.token_type == TokenType.VAR: self.dest_stream.write("{{%s}}" % contents) elif token.token_type == TokenType.BLOCK: try: command = token.contents.split()[0] except IndexError: self.empty_block_tag(token) if command in parse_until: # put token back on token list so calling # code knows why it terminated self.prepend_token(token) return nodelist if command == 'assets': try: # XXX This should work but for some reason debug does # not get propagated. # Lost in webassets.bundle.resolve_contents token.contents += ' debug=False' assets_string = str( assets(self, token).render(self.context)) self.dest_stream.write(assets_string) except TemplateSyntaxError as err: if hasattr(self, 'error'): raise self.error(token, err) # Django < 1.8 if not self.compile_function_error(token, err): raise elif command == 'static': self.dest_stream.write( do_static(self, token).render(self.context)) else: self.dest_stream.write("{%% %s %%}" % contents) elif token.token_type == TokenType.COMMENT: pass
def has_permission(parser, token): bits = list(token.split_contents()) if len(bits) < 2: raise TemplateSyntaxError("%r takes minimal one argument" % bits[0]) end_tag = 'end' + bits[0] vals = [] for bit in bits[2:]: vals.append(parser.compile_filter(bit)) nodelist_true = parser.parse(('else', end_tag)) token = parser.next_token() if token.contents == 'else': nodelist_false = parser.parse((end_tag, )) parser.delete_first_token() else: nodelist_false = NodeList() return PermissionNode(parser.compile_filter(bits[1]), vals, nodelist_true, nodelist_false)
def parse_token(cls, parser, token): bits = token.split_contents() tag_name = bits[0] args, kwargs = cls.parse_arguments(parser, tag_name, bits[1:]) if cls.literal_content: content = ''.join(cls.parse_literals(parser, tag_name)) nodelist = NodeList() else: content = '' nodelist = cls.parse_nodelist(parser, tag_name) return { 'tag_name': tag_name, 'args': args, 'kwargs': kwargs, 'content': content, 'nodelist': nodelist, }
def render(self, context): if "forloop" in context: parentloop = context["forloop"] else: parentloop = {} context.push() try: values = self.sequence.resolve(context, True) except VariableDoesNotExist: values = [] if values is None: values = [] if not hasattr(values, "__len__"): values = list(values) len_values = len(values) if len_values < 1: context.pop() return self.nodelist_empty.render(context) nodelist = NodeList() if self.is_reversed: values = reversed(values) unpack = len(self.loopvars) > 1 # Create a forloop value in the context. We'll update counters on each # iteration just below. loop_dict = context["forloop"] = {"parentloop": parentloop} for i, item in enumerate(values): # Shortcuts for current loop iteration number. loop_dict["counter0"] = i loop_dict["counter"] = i + 1 # Reverse counter iteration numbers. loop_dict["revcounter"] = len_values - i loop_dict["revcounter0"] = len_values - i - 1 # Boolean values designating first and last times through loop. loop_dict["first"] = i == 0 loop_dict["last"] = i == len_values - 1 pop_context = False if unpack: # If there are multiple loop variables, unpack the item into # them. try: unpacked_vars = dict(zip(self.loopvars, item)) except TypeError: pass else: pop_context = True context.update(unpacked_vars) else: context[self.loopvars[0]] = item # In TEMPLATE_DEBUG mode provide source of the node which # actually raised the exception if settings.TEMPLATE_DEBUG: for node in self.nodelist_loop: try: nodelist.append(node.render(context)) except Exception as e: if not hasattr(e, "django_template_source"): e.django_template_source = node.source raise else: for node in self.nodelist_loop: nodelist.append(node.render(context)) if pop_context: # The loop variables were pushed on to the context so pop them # off again. This is necessary because the tag lets the length # of loopvars differ to the length of each set of items and we # don't want to leave any vars from the previous loop on the # context. context.pop() context.pop() return nodelist.render(context)
class ForNode(Node): child_nodelists = ("nodelist_loop", "nodelist_empty") def __init__(self, loopvars, sequence, is_reversed, nodelist_loop, nodelist_empty=None): self.loopvars, self.sequence = loopvars, sequence self.is_reversed = is_reversed self.nodelist_loop = nodelist_loop if nodelist_empty is None: self.nodelist_empty = NodeList() else: self.nodelist_empty = nodelist_empty def __repr__(self): reversed_text = self.is_reversed and " reversed" or "" return "<For Node: for %s in %s, tail_len: %d%s>" % ( ", ".join(self.loopvars), self.sequence, len(self.nodelist_loop), reversed_text, ) def __iter__(self): for node in self.nodelist_loop: yield node for node in self.nodelist_empty: yield node def render(self, context): if "forloop" in context: parentloop = context["forloop"] else: parentloop = {} context.push() try: values = self.sequence.resolve(context, True) except VariableDoesNotExist: values = [] if values is None: values = [] if not hasattr(values, "__len__"): values = list(values) len_values = len(values) if len_values < 1: context.pop() return self.nodelist_empty.render(context) nodelist = NodeList() if self.is_reversed: values = reversed(values) unpack = len(self.loopvars) > 1 # Create a forloop value in the context. We'll update counters on each # iteration just below. loop_dict = context["forloop"] = {"parentloop": parentloop} for i, item in enumerate(values): # Shortcuts for current loop iteration number. loop_dict["counter0"] = i loop_dict["counter"] = i + 1 # Reverse counter iteration numbers. loop_dict["revcounter"] = len_values - i loop_dict["revcounter0"] = len_values - i - 1 # Boolean values designating first and last times through loop. loop_dict["first"] = i == 0 loop_dict["last"] = i == len_values - 1 pop_context = False if unpack: # If there are multiple loop variables, unpack the item into # them. try: unpacked_vars = dict(zip(self.loopvars, item)) except TypeError: pass else: pop_context = True context.update(unpacked_vars) else: context[self.loopvars[0]] = item for node in self.nodelist_loop: nodelist.append(node.render(context)) if pop_context: # The loop variables were pushed on to the context so pop them # off again. This is necessary because the tag lets the length # of loopvars differ to the length of each set of items and we # don't want to leave any vars from the previous loop on the # context. context.pop() context.pop() return nodelist.render(context)
class ForNode(Node): child_nodelists = ('nodelist_loop', 'nodelist_empty') def __init__(self, loopvars, sequence, is_reversed, nodelist_loop, nodelist_empty=None): self.loopvars, self.sequence = loopvars, sequence self.is_reversed = is_reversed self.nodelist_loop = nodelist_loop if nodelist_empty is None: self.nodelist_empty = NodeList() else: self.nodelist_empty = nodelist_empty def __repr__(self): reversed_text = ' reversed' if self.is_reversed else '' return "<For Node: for %s in %s, tail_len: %d%s>" % \ (', '.join(self.loopvars), self.sequence, len(self.nodelist_loop), reversed_text) def __iter__(self): for node in self.nodelist_loop: yield node for node in self.nodelist_empty: yield node def render(self, context): if 'forloop' in context: parentloop = context['forloop'] else: parentloop = {} with context.push(): try: values = self.sequence.resolve(context, True) except VariableDoesNotExist: values = [] if values is None: values = [] if not hasattr(values, '__len__'): values = list(values) len_values = len(values) if len_values < 1: return self.nodelist_empty.render(context) nodelist = [] if self.is_reversed: values = reversed(values) unpack = len(self.loopvars) > 1 # Create a forloop value in the context. We'll update counters on each # iteration just below. loop_dict = context['forloop'] = {'parentloop': parentloop} for i, item in enumerate(values): # Shortcuts for current loop iteration number. loop_dict['counter0'] = i loop_dict['counter'] = i + 1 # Reverse counter iteration numbers. loop_dict['revcounter'] = len_values - i loop_dict['revcounter0'] = len_values - i - 1 # Boolean values designating first and last times through loop. loop_dict['first'] = (i == 0) loop_dict['last'] = (i == len_values - 1) pop_context = False if unpack: # If there are multiple loop variables, unpack the item into # them. try: unpacked_vars = dict(zip(self.loopvars, item)) except TypeError: pass else: pop_context = True context.update(unpacked_vars) else: context[self.loopvars[0]] = item # In TEMPLATE_DEBUG mode provide source of the node which # actually raised the exception if settings.TEMPLATE_DEBUG: for node in self.nodelist_loop: try: nodelist.append(node.render(context)) except Exception as e: if not hasattr(e, 'django_template_source'): e.django_template_source = node.source raise else: for node in self.nodelist_loop: nodelist.append(node.render(context)) if pop_context: # The loop variables were pushed on to the context so pop them # off again. This is necessary because the tag lets the length # of loopvars differ to the length of each set of items and we # don't want to leave any vars from the previous loop on the # context. context.pop() return mark_safe(''.join(force_text(n) for n in nodelist))