def compile_func(parser, token): bits = token.split_contents()[1:] if len(bits) > 2 and bits[-2] == 'as': target_var = bits[-1] bits = bits[:-2] args, kwargs = parse_bits(parser, bits, params, varargs, varkw, defaults, takes_context, function_name) return AssignmentNode(takes_context, args, kwargs, target_var) else: args, kwargs = parse_bits(parser, bits, params, varargs, varkw, defaults, takes_context, function_name) return SimpleNode(takes_context, args, kwargs)
def tag(cls, parser, token): # Parse tag args and kwargs bits = token.split_contents()[1:] params = ('uri', 'edit') args, kwargs = parse_bits(parser, bits, params, None, True, (True,), None, 'blocknode') # Assert uri is the only tag arg if len(args) > 1: raise TemplateSyntaxError('Malformed arguments to blocknode tag') # Resolve uri variable uri = args[0].resolve({}) # Parse tag body (default content) tokens = parser.parse(('endblocknode',)) parser.delete_first_token() # Remove endblocknode tag # Render default content tokens and dedent common leading whitespace default = u''.join((token.render({}) for token in tokens)) default = textwrap.dedent(default) # Get node for uri, lacks context variable lookup due to lazy loading. node = api.get(uri, default) return cls(tokens, node, kwargs)
def tabdeck(parser, token): bits = token.split_contents()[1:] args, kwargs = parse_bits(parser, bits, [], 'args', 'kwargs', None, False, 'tabdeck') nodelist = parser.parse(('endtabdeck',)) parser.delete_first_token() # discard the 'endtabdeck' tag return TabDeckNode(nodelist, kwargs)
def dplink(parser, token): ''' Usage: {% dplink OBJ %}CONTENT{% enddplink %} Where: OBJ is a model instance, e.g. an ItemPart CONTENT is some html Output: If OBJ is an object, has a url and user can see it: <a href="LINK TO OBJ">CONTENT</a> Otherwise: CONTENT ''' def get_link_from_obj(obj=None): ret = {'content': u'%s' % obj, 'url': ur''} if obj: f = getattr(obj, 'get_absolute_url') if f: ret['url'] = u'%s' % f() return ret class DPLinkNode(template.base.TagHelperNode): def __init__(self, nodelist, args, kwargs): super(DPLinkNode, self).__init__(takes_context=False, args=args, kwargs=kwargs) self.nodelist = nodelist def render(self, context): ret = self.nodelist.render(context) args, kwargs = self.get_resolved_arguments(context) link = get_link_from_obj(*args, **kwargs) obj = args[0] request = context.get('request', None) if request and not dputils.is_model_visible(obj, request): link['url'] = None ret = ret.strip() or link['content'] if link['url']: ret = u'<a href="%s">%s</a>' % (link['url'], ret) return ret nodelist = parser.parse(('enddplink', )) parser.delete_first_token() bits = token.split_contents()[1:] params, varargs, varkw, defaults = getargspec(get_link_from_obj) args, kwargs = parse_bits(parser, bits, params, varargs, varkw, defaults, takes_context=False, name='dplink') return DPLinkNode(nodelist, args, kwargs)
def _ssi_var_tag(parser, token): """ Creates a SSI variable reference for a request-dependent info. Use as: {% ri_tag args... %} or: {% ri_tag args... as variable %} {{ variable.if }} {{ variable }}, or {% ssi_include 'some-snippet' variable %} {{ variable.else }} Default text {{ variable.endif }} """ bits = token.split_contents()[1:] # Is it the 'as' form? if len(bits) >= 2 and bits[-2] == 'as': asvar = bits[-1] bits = bits[:-2] else: asvar = None # Parse the arguments like Django's generic tags do. args, kwargs = parse_bits(parser, bits, ['context'] + params[1:], varargs, varkw, defaults, takes_context=True, name=function_name) return SsiVariableNode(tagpath, args, kwargs, patch_response, asvar)
def tag(cls, parser, token): # Parse tag args and kwargs bits = token.split_contents()[1:] params = ('uri', 'edit') args, kwargs = parse_bits(parser, bits, params, None, True, (True, ), None, 'blocknode') # Assert uri is the only tag arg if len(args) > 1: raise TemplateSyntaxError('Malformed arguments to blocknode tag') # Resolve uri variable uri = args[0].resolve({}) # Parse tag body (default content) tokens = parser.parse(('endblocknode', )) parser.delete_first_token() # Remove endblocknode tag # Render default content tokens and dedent common leading whitespace default = u''.join((token.render({}) for token in tokens)) default = default.strip('\n\r') default = textwrap.dedent(default) # Get node for uri, lacks context variable lookup due to lazy loading. node = cio.get(uri, default) return cls(tokens, node, kwargs)
def compile_func(parser, token): takes_context = True bits = token.split_contents()[1:] args, kwargs = parse_bits(parser, bits, params, varargs, varkw, defaults, takes_context, tag_name) nodelist = parser.parse(('end' + tag_name,)) parser.delete_first_token() return InlineCompileNode(nodelist, takes_context, args, kwargs)
def compile_func(parser, token): takes_context = True bits = token.split_contents()[1:] args, kwargs = parse_bits(parser, bits, params, varargs, varkw, defaults, takes_context, tag_name) nodelist = parser.parse(('end' + tag_name, )) parser.delete_first_token() return InlineCompileNode(nodelist, takes_context, args, kwargs)
def compile_func(parser, token): bits = token.split_contents()[1:] if len(bits) < 2 or bits[-2] != "as": target_var = None else: target_var = bits[-1] bits = bits[:-2] args, kwargs = base.parse_bits(parser, bits, params, varargs, varkw, defaults, takes_context, function_name) return AssignmentNode(takes_context, args, kwargs, target_var)
def compile_func(parser, token): bits = token.split_contents()[1:] # if len(bits) < 2 or bits[-2] != 'as': # raise TemplateSyntaxError( # "'%s' tag takes at least 2 arguments and the " # "second last argument must be 'as'" % function_name) # replaced above choose between AssignmentNode or SimpleNode if len(bits) > 1 and bits[-2] == 'as': target_var = bits[-1] bits = bits[:-2] args, kwargs = parse_bits(parser, bits, params, varargs, varkw, defaults, takes_context, function_name) return AssignmentNode(takes_context, args, kwargs, target_var) else: args, kwargs = parse_bits(parser, bits, params, varargs, varkw, defaults, takes_context, function_name) return SimpleNode(takes_context, args, kwargs)
def dplink(parser, token): ''' Usage: {% dplink OBJ %}CONTENT{% enddplink %} Where: OBJ is a model instance, e.g. an ItemPart CONTENT is some html Output: If OBJ is an object, has a url and user can see it: <a href="LINK TO OBJ">CONTENT</a> Otherwise: CONTENT ''' def get_link_from_obj(obj=None): ret = {'content': '%s' % obj, 'url': ur''} if obj: f = getattr(obj, 'get_absolute_url') if f: ret['url'] = '%s' % f() return ret class DPLinkNode(template.base.TagHelperNode): def __init__(self, nodelist, args, kwargs): super(DPLinkNode, self).__init__( takes_context=False, args=args, kwargs=kwargs) self.nodelist = nodelist def render(self, context): ret = self.nodelist.render(context) args, kwargs = self.get_resolved_arguments(context) link = get_link_from_obj(*args, **kwargs) obj = args[0] request = context.get('request', None) if request and not dputils.is_model_visible(obj, request): link['url'] = None ret = ret.strip() or link['content'] if link['url']: ret = u'<a href="%s">%s</a>' % (link['url'], ret) return ret nodelist = parser.parse(('enddplink',)) parser.delete_first_token() bits = token.split_contents()[1:] params, varargs, varkw, defaults = getargspec(get_link_from_obj) args, kwargs = parse_bits( parser, bits, params, varargs, varkw, defaults, takes_context=False, name='dplink' ) return DPLinkNode(nodelist, args, kwargs)
def adrest_include(parser, token): """ Include adrest_template for any objects. :return str: Rendered string. """ bits = token.split_contents()[1:] args, kwargs = parse_bits(parser, bits, ['content'], 'args', 'kwargs', tuple(), False, 'adrest_include') return AdrestInclusionNode(False, args, kwargs)
def tag_compiler(parser, token, params, varargs, varkw, defaults, name, takes_context, function_name): bits = token.split_contents()[1:] bits = [''] + bits # add placeholder for content arg args, kwargs = parse_bits(parser, bits, params, varargs, varkw, defaults, takes_context, name) args = args[1:] # remove content placeholder nodelist = parser.parse(('end{}'.format(function_name),)) parser.delete_first_token() return SimpleNode(nodelist, takes_context, args, kwargs)
def generic_tag_compiler(parser, token, params, varargs, varkw, defaults, name, takes_context, node_class): """ Returns a template.Node subclass. """ bits = token.split_contents()[1:] output_context = parser.output_context if parser.output_context is not None else {} args, kwargs = parse_bits(parser, bits, params, varargs, varkw, defaults, takes_context, name) return node_class(takes_context, output_context, args, kwargs)
def _compile(parser, token): # content nodelist = parser.parse(('end' + name,)) parser.delete_first_token() # args bits = token.split_contents()[1:] args, kwargs = parse_bits(parser, bits, params, varargs, varkw, defaults, takes_context=None, name=name) return HelperNode(False, args, kwargs, nodelist)
def tag_compiler(parser, token, params, varargs, varkw, defaults, name, takes_context, function_name): bits = token.split_contents()[1:] bits = [''] + bits # add placeholder for content arg args, kwargs = parse_bits(parser, bits, params, varargs, varkw, defaults, takes_context, name) args = args[1:] # remove content placeholder nodelist = parser.parse(('end{}'.format(function_name), )) parser.delete_first_token() return SimpleNode(nodelist, takes_context, args, kwargs)
def compile_func(parser, token): bits = token.split_contents()[1:] target_var = None if len(bits) >=2 and bits[-2] == 'as': target_var = bits[-1] bits = bits[:-2] args, kwargs = parse_bits(parser, bits, params, varargs, varkw, defaults, takes_context, function_name) return WithAsNode(takes_context, args, kwargs, target_var)
def adrest_include(parser, token): """ Include adrest_template for any objects. :return str: Rendered string. """ bits = token.split_contents()[1:] args, kwargs = parse_bits( parser, bits, ['content'], 'args', 'kwargs', tuple(), False, 'adrest_include') return AdrestInclusionNode(False, args, kwargs)
def compiler(parser, token, params, varargs, varkw, defaults, name, takes_context, node_class): if params[0] == "content": params = params[1:] else: raise TemplateSyntaxError(u'The first argument of "{}" must be "content"'.format(name)) bits = token.split_contents()[1:] args, kwargs = parse_bits(parser, bits, params, varargs, varkw, defaults, takes_context, name) nodelist = parser.parse((u"end" + name,)) parser.delete_first_token() return node_class(takes_context, nodelist, args, kwargs)
def compile_func(parser, token): bits = token.split_contents()[1:] if len(bits) < 2 or bits[-2] != 'as': target_var = None else: target_var = bits[-1] bits = bits[:-2] args, kwargs = base.parse_bits(parser, bits, params, varargs, varkw, defaults, takes_context, function_name) return AssignmentNode(takes_context, args, kwargs, target_var)
def do_pzone(parser, token): """ {% forpzone "homepage" slice=":3" %} <h1> <a href="{{ content.get_absolute_url }}">{{ content.title }}</a> </h1> <span>{{ content.description }}</span> {% endforpzone %} """ bits = token.split_contents() if len(bits) < 2: raise template.TemplateSyntaxError("'pzone' statements should have at least two" " words: %s" % token.contents) nodelist_loop = parser.parse(("endforpzone", "empty")) token = parser.next_token() if token.contents == 'empty': nodelist_empty = parser.parse(('endfor',)) parser.delete_first_token() else: nodelist_empty = None params = ["slice", "name", "apply"] args, kwargs = parse_bits(parser, bits, params, None, None, [], False, "forpzone") pzone_name = kwargs["name"].resolve({}) slice_string = None if "slice" in kwargs: slice_string = kwargs["slice"].resolve({}) slice_bits = [] for x in slice_string.split(':'): if len(x) == 0: slice_bits.append(None) else: slice_bits.append(int(x)) # mparent(2016-06-23): Variable not used, commented out for lint. FIX ME! # slice_object = slice(*slice_bits) apply = False if "apply" in kwargs: apply = kwargs["apply"].resolve({}) sequence = PZoneSequence(pzone_name, slice_string=slice_string, apply=apply) loopvars = ["content"] is_reversed = False return ForNode(loopvars, sequence, is_reversed, nodelist_loop, nodelist_empty)
def tab(parser, token): bits = token.split_contents()[1:] args, kwargs = parse_bits(parser, bits, ['heading_expr'], 'args', 'kwargs', None, False, 'tab') if len(args) != 1: raise template.TemplateSyntaxError("The 'tab' tag requires exactly one unnamed argument (the tab heading).") heading_expr = args[0] nodelist = parser.parse(('endtab',)) parser.delete_first_token() # discard the 'endtab' tag return TabNode(nodelist, heading_expr, kwargs)
def get_args_kwargs(parser, token): """ copied from django.template.(base|library).Library.simple_tag.compile_func """ def to_limit(limit_name, **limit_kwargs): pass params, varargs, varkw, defaults = getargspec(to_limit) function_name = 'djptlimit' bits = token.split_contents()[1:] takes_context = False args, kwargs = parse_bits(parser, bits, params, varargs, varkw, defaults, takes_context, function_name) return args, kwargs
def compiler(parser, token, params, varargs, varkw, defaults, name, takes_context, node_class): if params[0] == 'content': params = params[1:] else: raise TemplateSyntaxError( u'The first argument of "%s" must be "content"' % name) bits = token.split_contents()[1:] args, kwargs = parse_bits(parser, bits, params, varargs, varkw, defaults, takes_context, name) nodelist = parser.parse((u'end' + name, )) parser.delete_first_token() return node_class(takes_context, nodelist, args, kwargs)
def tag(cls, parser, token): # Parse tag args and kwargs bits = token.split_contents()[1:] params = ('uri', 'edit', 'default') args, kwargs = parse_bits(parser, bits, params, None, True, ('', True,), None, 'node') # Assert uri is the only tag arg if len(args) > 1: raise TemplateSyntaxError('Malformed arguments to blocknode tag') # Resolve uri variable uri = args[0].resolve({}) default = kwargs['default'].resolve({}) if 'default' in kwargs else u'' return cls(uri, default, kwargs)
def wrapper(parser, token): bits = token.split_contents() tag_name = bits.pop(0) if len(bits) == 0: raise template.TemplateSyntaxError( '"{0}" tag takes at least 1 argument: the template name'.format(tag_name) ) args, kwargs = parse_bits(parser, bits, ['template_name'], '', '', None, False, 'form') nodelist = parser.parse(('end{0}'.format(tag_name),)) template_name = args.pop(0) parser.delete_first_token() return klass(nodelist, tag_name, template_name, *args, **kwargs)
def _compile(parser, token): # content nodelist = parser.parse(('end' + name, )) parser.delete_first_token() # args bits = token.split_contents()[1:] args, kwargs = parse_bits(parser, bits, params[2:], varargs, varkw, defaults, takes_context=None, name=name) return HelperNode(False, args, kwargs, nodelist)
def compile_func(parser, token): bits = token.split_contents()[1:] if len(bits) < 2 or bits[-2] != 'as': raise template.TemplateSyntaxError( "'%s' tag takes at least 2 arguments and the " "second last argument must be 'as'" % function_name) target_var = bits[-1] bits = bits[:-2] args, kwargs = parse_bits( parser, bits, params, varargs, varkw, defaults, takes_context, function_name ) nodelist = parser.parse((end_name, )) parser.delete_first_token() return AssignmentNode( nodelist, takes_context, args, kwargs, target_var )
def parse_args(parser, token, args, kwargs, defaults_args=(), defaults_kwargs=()): """ Parses the arguments passed to the tag. Returns tuple with args and kwargs, where in both cases the values are stored as FilterExpressions. Please note that providing default_args, default_kwargs or both does not mean that kwargs[<optional-arg>] will always work. The argument only prevents the parser from complaining about arguments being not passed. :param parser: TokenParser to use :param token: token to parse :param args: list of positional arguments :param kwargs: list of keyword arguments :param defaults_args: default values for the arguments :param defaults_kwargs: default values for the keyword arguments :return: args, kwargs tuple with parsed arguments """ bits = token.split_contents() params = args + kwargs return parse_bits(parser, bits[1:], params, args, kwargs, defaults_args + defaults_kwargs, False, bits[0])
def render_form(parser, token): args, kwargs = parse_bits(parser, token.split_contents()[1:], (), varargs=True, varkw=True, defaults=None, takes_context=False, name='render_form') return FormNode(args, kwargs)
def flowurl(parser, token): """ Return flow url. Usage:: {% flowurl ref [urlname] [user=] [as varname]%} Examples:: {% flowurl 'app_label/FlowCls' 'viewflow:index' %} {% flowurl flow_cls 'index' as index_url %} {% flowurl process 'index' %} {% flowurl process 'details' %} {% flowurl task 'assign' user=request.user %} {% flowurl task user=request.user %} """ def geturl(ref, url_name=None, user=None): if isinstance(ref, Flow): url_ref = "{}:{}".format(ref.namespace, url_name if url_name else "index") return reverse(url_ref) elif isinstance(ref, AbstractProcess): kwargs, url_ref = {}, "{}:{}".format(ref.flow_cls.instance.namespace, url_name if url_name else "index") if url_name in ["details", "cancel"]: kwargs["process_pk"] = ref.pk return reverse(url_ref, kwargs=kwargs) elif isinstance(ref, AbstractTask): return ref.flow_task.get_task_url(ref, url_type=url_name if url_name else "guess", user=user) else: try: app_label, flow_cls_path = ref.split("/") except ValueError: raise TemplateSyntaxError( "Flow reference string should looks like 'app_label/FlowCls' but '{}'".format(ref) ) app_package = get_app_package(app_label) if app_package is None: raise TemplateSyntaxError("{} app not found".format(app_label)) flow_cls = import_by_path("{}.flows.{}".format(app_package, flow_cls_path)) url_ref = "{}:{}".format(flow_cls.instance.namespace, url_name if url_name else "index") return reverse(url_ref) class URLNode(TagHelperNode): def __init__(self, args, kwargs, target_var): super(URLNode, self).__init__(takes_context=False, args=args, kwargs=kwargs) self.target_var = target_var def render(self, context): resolved_args, resolved_kwargs = self.get_resolved_arguments(context) url = geturl(*resolved_args, **resolved_kwargs) if self.target_var: context[self.target_var] = url return "" else: return url bits = token.split_contents()[1:] target_var = None if bits[-2] == "as": target_var = bits[-1] bits = bits[:-2] params, varargs, varkw, defaults = getargspec(geturl) args, kwargs = parse_bits(parser, bits, params, varargs, varkw, defaults, takes_context=False, name="flowurl") return URLNode(args, kwargs, target_var)
def flowurl(parser, token): """ Return flow url. Usage:: {% flowurl ref [urlname] [user=] [as varname]%} Examples:: {% flowurl 'app_label/FlowCls' 'viewflow:index' %} {% flowurl flow_cls 'index' as index_url %} {% flowurl process 'index' %} {% flowurl process 'details' %} {% flowurl task 'assign' user=request.user %} {% flowurl task user=request.user %} """ def geturl(ref, url_name=None, user=None): if isinstance(ref, Flow): url_ref = '{}:{}'.format(ref.namespace, url_name if url_name else 'index') return reverse(url_ref) elif isinstance(ref, AbstractProcess): kwargs, url_ref = {}, '{}:{}'.format( ref.flow_cls.instance.namespace, url_name if url_name else 'index') ''' And I thought my code was hacky. ''' if url_name in ['details', 'cancel']: kwargs['process_pk'] = ref.pk return reverse(url_ref, kwargs=kwargs) elif isinstance(ref, AbstractTask): return ref.flow_task.get_task_url( ref, url_type=url_name if url_name else 'guess', user=user) else: try: app_label, flow_cls_path = ref.split('/') except ValueError: raise TemplateSyntaxError( "Flow reference string should looks like 'app_label/FlowCls' but '{}'" .format(ref)) app_package = get_app_package(app_label) if app_package is None: raise TemplateSyntaxError("{} app not found".format(app_label)) flow_cls = import_by_path('{}.flows.{}'.format( app_package, flow_cls_path)) url_ref = '{}:{}'.format(flow_cls.instance.namespace, url_name if url_name else 'index') return reverse(url_ref) class URLNode(TagHelperNode): def __init__(self, args, kwargs, target_var): super(URLNode, self).__init__(takes_context=False, args=args, kwargs=kwargs) self.target_var = target_var def render(self, context): resolved_args, resolved_kwargs = self.get_resolved_arguments( context) url = geturl(*resolved_args, **resolved_kwargs) if self.target_var: context[self.target_var] = url return '' else: return url bits = token.split_contents()[1:] target_var = None if bits[-2] == 'as': target_var = bits[-1] bits = bits[:-2] params, varargs, varkw, defaults = getargspec(geturl) args, kwargs = parse_bits(parser, bits, params, varargs, varkw, defaults, takes_context=False, name='flowurl') return URLNode(args, kwargs, target_var)