Beispiel #1
0
 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)
Beispiel #2
0
def do_include_with(parser, token):
    """
    Include template with object attributes injected to context.
    It takes object and template path as arguments.
    Object should have template_exposed_attributes list defined.

    .. code-block:: text

        {% include_with obj 'path/to/included/template.html' %}

    It is also possible to overvrite / add additional kwaegs.

    .. code-block:: text

        {% include_with obj 'path/to/included/template.html' foo='bar'%}

    """
    bits = token.split_contents()

    if django_version[0] >= 2:
        options = parse_bits(
            parser,
            bits[1:],
            ['with_object', 'template_name'],
            False,
            True,
            None,
            [],
            None,
            False,
            'include_with',
        )
    else:
        options = parse_bits(
            parser,
            bits[1:],
            ['with_object', 'template_name'],
            False,
            True,
            None,
            False,
            'include_with',
        )

    bits[2] = construct_relative_path(parser.origin.template_name, bits[2])
    template_filter = parser.compile_filter(bits[2])

    return IncludeWithNode(bits[1], template_filter, extra_context=options[1])
Beispiel #3
0
    def compile_func(parser, token):
      bits = token.split_contents()[1:]

      # When there is an "as"
      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(function_name, takes_context, args, kwargs, target_var)
      else:
        args, kwargs = parse_bits(
          parser, bits, params, varargs, varkw, defaults, takes_context, function_name
        )
        return SimpleNode(function_name, takes_context, args, kwargs)
      def compile_func(parser,token):
          bits = token.split_contents()[1:]

          nodelist = parser.parse((f"end{function_name}",))
          parser.delete_first_token()

          args, kwargs = parse_bits(
              parser, bits, params, varargs, varkw, defaults,
              kwonly, kwonly_defaults, takes_context, function_name,
          )
          def _func(context,*args,**kwargs):
              if takes_context:
                  ret = func(context, *args,**kwargs)
              else:
                  ret = func(*args,**kwargs)

              return {
                  **ret,
                  "content": nodelist.render(context)
              }

          return InclusionNode(
              _func,
              True, # takes_context, there are 2 different kinds of context here
              args,
              kwargs,
              filename
          )
Beispiel #5
0
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)
Beispiel #6
0
 def parse_bits(parser, bits, params, varargs, varkw, defaults,
                takes_context, name):
     from django.template import library
     return library.parse_bits(
         parser=parser, bits=bits, params=params, varargs=varargs,
         varkw=varkw, defaults=defaults, kwonly=(), kwonly_defaults=(),
         takes_context=takes_context, name=name)
Beispiel #7
0
    def parse_content(self, parser, token):
        """
        This is called to parse the incoming context.

        It's return value will be set to self.args, self.kwargs, self.variable
        """
        bits = token.split_contents()[1:]
        target_var = None

        if len(bits) >= 2 and bits[-2] == 'as':
            target_var = bits[-1]
            bits = bits[:-2]

        params, varargs, varkw, defaults = inspect.signature(self.component.render)

        if params[0] == 'context':
            takes_context = True
        else:
            takes_context = False
        self.takes_context = takes_context

        function_name = self.component.name
        args, kwargs = parse_bits(
            parser, bits, params, varargs, varkw, defaults,
            takes_context, function_name
        )
        return args, kwargs, target_var
        def compile_func(parser, token):
            bits = token.split_contents()[1:]
            args, kwargs = parse_bits(
                parser,
                bits,
                params,
                varargs,
                varkw,
                defaults,
                kwonly,
                kwonly_defaults,
                takes_context,
                function_name,
            )

            kwargs[context_text_name] = parser.parse((end_tag_name, tag_name))
            parser.delete_first_token()

            return CustomNode(
                func,
                takes_context,
                args,
                kwargs,
                filename,
            )
Beispiel #9
0
 def parse_bits(parser, bits, params, varargs, varkw, defaults,
                takes_context, name):
     from django.template import library
     return library.parse_bits(
         parser=parser, bits=bits, params=params, varargs=varargs,
         varkw=varkw, defaults=defaults, kwonly=(), kwonly_defaults=(),
         takes_context=takes_context, name=name)
Beispiel #10
0
 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] + ["_asvar=True"]
     args, kwargs = parse_bits(parser, bits, params, varargs, varkw,
                               defaults, takes_context, function_name)
     return SimpleNode(func, takes_context, args, kwargs, target_var)
Beispiel #11
0
 def __init__(self, parser, token, func, template_name, takes_context=True):
     self.template_name = template_name
     params, varargs, varkw, defaults, kwonly, kwonly_defaults, _ = getfullargspec(func)
     bits = token.split_contents()
     args, kwargs = parse_bits(
         parser, bits[1:], params, varargs, varkw, defaults, kwonly,
         kwonly_defaults, takes_context, bits[0],
     )
     super().__init__(func, takes_context, args, kwargs, filename=None)
Beispiel #12
0
 def __init__(self, parser, token, func, template_name, takes_context=True):
     self.template_name = template_name
     params, varargs, varkw, defaults, kwonly, kwonly_defaults, _ = getfullargspec(func)
     bits = token.split_contents()
     args, kwargs = parse_bits(
         parser, bits[1:], params, varargs, varkw, defaults, kwonly,
         kwonly_defaults, takes_context, bits[0],
     )
     super().__init__(func, takes_context, args, kwargs, filename=None)
 def compile_func(parser, token):
     bits = token.split_contents()[1:]
     args, kwargs = parse_bits(
         parser, bits, params, varargs, varkw, defaults,
         kwonly, kwonly_defaults, takes_context, function_name,
     )
     return InclusionNode(
         func, takes_context, args, kwargs, filename
     )
Beispiel #14
0
        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=takes_context, name=name)
            return CachedNode(func, takes_context, args, kwargs, nodelist)
        def compile_func(parser,token):
            bits = token.split_contents()[1:]
  
            # TODO: figure out if this is lazy/thread-safe
            # parser.delete_first_token()
            
            token = parser.next_token()
            
            nodelists_by_name = {}
            
            end_tag_token = f"end{function_name}"

            blocks_left = len(block_names) + 1 # +1 for the eng_tag_token
            while blocks_left:
                useless = parser.parse(("blockarg",end_tag_token))
                token = parser.next_token()
                if token.contents.startswith(end_tag_token):
                    blocks_left = 0
                    for name in block_names:
                        if name not in nodelists_by_name:
                            nodelists_by_name[name] = None
                else: # {% block_arg <block_name> %}
                    block_name = token.split_contents()[1][1:-1] # TODO: make it clear that this needs to be a literal string ""/ '' and not a variable
                    block_nodelist = parser.parse(f"endblockarg")
                    nodelists_by_name[block_name] = block_nodelist
                    token = parser.next_token()
                    blocks_left = blocks_left - 1
                            
  
            args, kwargs = parse_bits(
                parser, bits, params, varargs, varkw, defaults,
                kwonly, kwonly_defaults, takes_context, function_name,
            )
            def _func(context,*args,**kwargs):
                if takes_context:
                    ret = func(context, *args,**kwargs)
                else:
                    ret = func(*args,**kwargs)
  
                return {
                    **ret,
                    **{
                        name: nodelist and nodelist.render(context)
                        for (name,nodelist) in nodelists_by_name.items() 
                    }
                }
  
            return InclusionNode(
                _func,
                True, # takes_context, there are 2 different kinds of context here
                args,
                kwargs,
                filename
            )
Beispiel #16
0
 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 = parse_bits(parser, bits, params, varargs, varkw,
                               defaults, kwonly, kwonly_defaults,
                               takes_context, function_name)
     return AssignmentNode(takes_context, args, kwargs, target_var)
Beispiel #17
0
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)
Beispiel #18
0
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)
Beispiel #19
0
    def generic_tag_compiler(parser, token, params, varargs, varkw, defaults,
                             name, takes_context, node_class):
        """
        Returns a template.Node subclass.

        This got inlined into django.template.library since Django since 1.9, this here
        is a copypasta replacement:
        https://github.com/django/django/blob/stable/1.8.x/django/template/base.py#L1089
        """
        bits = token.split_contents()[1:]
        args, kwargs = parse_bits(parser, bits, params, varargs, varkw,
                                  defaults, takes_context, name)
        return node_class(takes_context, args, kwargs)
 def compile_func(parser, token):
     takes_context = True
     bits = token.split_contents()[1:]
     args, kwargs = library.parse_bits(parser, bits, params, varargs, varkw,
                                       defaults, takes_context, tag_name)
     nodelist = parser.parse(('end' + tag_name,))
     parser.delete_first_token()
     try:
         # Django<1.9
         return InlineCompileNode(nodelist, takes_context, args, kwargs)
     except TypeError:
         # Django>=1.9
         return InlineCompileNode(nodelist, func, takes_context, args, kwargs)
Beispiel #21
0
    def __init__(self, parser, token, func, template_name, takes_context=True):
        self.template_name = template_name

        params, varargs, varkw, defaults, kwonly, kwonly_defaults, _ = getfullargspec(func)
        if len(params) > 0 and params[0] == 'self':
            params = params[1:]  # ignore 'self'
        bits = token.split_contents()
        args, kwargs = parse_bits(
            parser, bits[1:], params, varargs, varkw, defaults, kwonly, kwonly_defaults, takes_context, bits[0]
        )
        super().__init__(
            func=func, takes_context=takes_context, args=args, kwargs=kwargs, filename=None
        )
Beispiel #22
0
    def generic_tag_compiler(parser, token, params, varargs, varkw, defaults,
                             name, takes_context, node_class):
        """
        Returns a template.Node subclass.

        This got inlined into django.template.library since Django since 1.9, this here
        is a copypasta replacement:
        https://github.com/django/django/blob/stable/1.8.x/django/template/base.py#L1089
        """
        bits = token.split_contents()[1:]
        args, kwargs = parse_bits(parser, bits, params, varargs, varkw,
                                  defaults, takes_context, name)
        return node_class(takes_context, args, kwargs)
Beispiel #23
0
 def compile_func(parser, token):
     takes_context = True
     bits = token.split_contents()[1:]
     args, kwargs = library.parse_bits(parser, bits, params, varargs,
                                       varkw, defaults, takes_context,
                                       tag_name)
     nodelist = parser.parse(('end' + tag_name, ))
     parser.delete_first_token()
     try:
         # Django<1.9
         return InlineCompileNode(nodelist, takes_context, args, kwargs)
     except TypeError:
         # Django>=1.9
         return InlineCompileNode(nodelist, func, takes_context, args,
                                  kwargs)
 def compile_func(parser, token):
     bits = token.split_contents()[1:]
     args, kwargs = parse_bits(
         parser,
         bits,
         params,
         varargs,
         varkw,
         defaults,
         kwonly,
         kwonly_defaults,
         takes_context,
         function_name,
     )
     return InclusionNode(func, takes_context, args, kwargs, filename)
Beispiel #25
0
    def __init__(self, parser, token, func, template_name, takes_context=True):
        self.template_name = template_name

        params, varargs, varkw, defaults, kwonly, kwonly_defaults, _ = getfullargspec(
            func)
        if len(params) > 0 and params[0] == 'self':
            params = params[1:]  # ignore 'self'
        bits = token.split_contents()
        args, kwargs = parse_bits(parser, bits[1:], params, varargs, varkw,
                                  defaults, kwonly, kwonly_defaults,
                                  takes_context, bits[0])
        super().__init__(func=func,
                         takes_context=takes_context,
                         args=args,
                         kwargs=kwargs,
                         filename=None)
Beispiel #26
0
        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=takes_context,
                                      name=name)
            return CachedNode(func, takes_context, args, kwargs, nodelist)
Beispiel #27
0
    def handler_parser(cls, parser, token, name, handler):
        """
        Returns a wrapped partial of ``handler`` with the arguments supplied by the calling
        template.  Errors will bubble up for invalid or missing arguments to the handler.
        """
        params, varargs, varkw, defaults = getargspec(handler)
        wrapped = cls.wrap_handler(handler)
        params.pop(0)  # removes inspected 'self' from required tag arguments

        special_params = ['context', 'nodelist']  # Rendering params that aren't given by template
        for param in special_params:
            if param in params:
                params.pop(params.index(param))

        bits = token.split_contents()[1:]
        args, kwargs = parse_bits(parser, bits, params, varargs, varkw, defaults, None, name)
        kwargs.update(zip(params, args))
        return partial(wrapped, **kwargs)
Beispiel #28
0
def parse_component_with_args(parser, bits, tag_name):
    tag_args, tag_kwargs = parse_bits(
        parser=parser,
        bits=bits,
        params=["tag_name", "name"],
        takes_context=False,
        name=tag_name,
        varargs=True,
        varkw=[],
        defaults=None,
        kwonly=[],
        kwonly_defaults=None,
    )

    assert (
        tag_name == tag_args[0].token
    ), "Internal error: Expected tag_name to be {}, but it was {}".format(
        tag_name, tag_args[0].token)
    if (
            len(tag_args) > 1
    ):  # At least one position arg, so take the first as the component name
        component_name = tag_args[1].token
        context_args = tag_args[2:]
        context_kwargs = tag_kwargs
    else:  # No positional args, so look for component name as keyword arg
        try:
            component_name = tag_kwargs.pop("name").token
            context_args = []
            context_kwargs = tag_kwargs
        except IndexError:
            raise TemplateSyntaxError(
                "Call the '%s' tag with a component name as the first parameter"
                % tag_name)

    if not is_wrapped_in_quotes(component_name):
        raise TemplateSyntaxError("Component name '%s' should be in quotes" %
                                  component_name)

    trimmed_component_name = component_name[1:-1]
    component_class = registry.get(trimmed_component_name)
    component = component_class(trimmed_component_name)

    return component, context_args, context_kwargs
Beispiel #29
0
def flowurl(parser, token):
    """
        Returns flow url::

            {% flowurl ref [urlname] [user=]  [as varname]%}

        Usage 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__(func=None,
                                          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)