Example #1
0
def impressions(context, *fields):
    if not fields:
        raise TemplateSyntaxError(
            f"'impression' requires a queryset"
        )
    fields = list(fields)
    queryset = fields[0]
    if not isinstance(queryset, QuerySet):
        raise TemplateSyntaxError(
            f"'impression' requires a queryset as first argument"
        )

    remaining_bits = fields[1:]
    if not remaining_bits:
        raise TemplateSyntaxError(
            "'impressions' requires a set of fields to use from the quersyet"
        )

    values = queryset.values(*remaining_bits)
    values_list = list(values)
    new_values_list = values_list
    for index, value in enumerate(new_values_list):
        value['position'] = index
    s = str(json.dumps(new_values_list))
    return mark_safe(s)
Example #2
0
def do_include_with(parser, token):
    """
    Load a template and render it with the current context. You can pass
    additional context using keyword arguments.

    Example::

        {% include_with "foo/some_include" %}
        {% include_with "foo/some_include" with bar="BAZZ!" baz="BING!" %}

    Use the ``only`` argument to exclude the current context when rendering
    the included template::

        {% include_with "foo/some_include" only %}
        {% include_with "foo/some_include" with bar="1" only %}

    This method is mostly ripped out of django.template.loader_tags.do_include(...).
    """
    bits = token.split_contents()
    if len(bits) < 2:
        raise TemplateSyntaxError(
            "%r tag takes at least one argument: the name of the template to "
            "be included." % bits[0])
    template_name = bits[1]
    remaining_bits = bits[2:]
    options = {}
    match = Holder()
    while remaining_bits:
        option = remaining_bits.pop(0)
        if option in options:
            raise TemplateSyntaxError(
                'The %r option was specified more than once.' % option)
        if option == 'with':
            value = token_kwargs_better(remaining_bits,
                                        parser,
                                        support_legacy=False)
            if not value:
                raise TemplateSyntaxError(
                    '"with" in %r tag needs at least one keyword argument.' %
                    bits[0])
        elif option == 'only':
            value = True
        elif match.set() and match.get().group(1):
            for key in parser.compile_filter(value):
                options[key] = value
        else:
            raise TemplateSyntaxError('Unknown argument for %r tag: %r.' %
                                      (bits[0], option))
        options[option] = value
    isolated_context = options.get('only', False)
    name_map = options.get('with', {})
    template_name = parser.compile_filter(
        template_name)  # resolve `"string"` vs `variable`
    return IncludeWithNode(  # as we don't have the context available we need to return object having `.render(context)`
        template_name=template_name,
        isolated_context=isolated_context,
        name_map=name_map,
        origin_template_name=parser.origin.template_name,
    )
Example #3
0
 def get_template(self, template_name):
     try:
         return TemplateJinja2(self.env.get_template(template_name), self)
     except jinja2.TemplateNotFound as exc:
         raise TemplateDoesNotExist(exc.name, backend=self) from exc
     except jinja2.TemplateSyntaxError as exc:
         new = TemplateSyntaxError(exc.args)
         new.template_debug = get_exception_info(exc)
         raise new from exc
Example #4
0
def do_embed(parser, token):
    """{% embed %} template tag. Allows to include a template and optionally override its slots, in a similar fashion
    to block tags in extended templates.

    Example::

        {% embed 'section.html' %}
            {% slot title %}<h1>Title</h1>{% endslot %}
            {% slot content %}<p>Content</p>{% endslot %}
        {% endembed %}

    You may use the ``only`` argument and keyword arguments using ``with`` like when using ``{% include %}``
    """

    # Exact copy from do_include_node()
    bits = token.split_contents()
    if len(bits) < 2:
        raise TemplateSyntaxError(
            "%r tag takes at least one argument: the name of the template to "
            "be included." % bits[0])
    options = {}
    remaining_bits = bits[2:]
    while remaining_bits:
        option = remaining_bits.pop(0)
        if option in options:
            raise TemplateSyntaxError("The %r option was specified more "
                                      "than once." % option)
        if option == "with":
            value = token_kwargs(remaining_bits, parser, support_legacy=False)
            if not value:
                raise TemplateSyntaxError('"with" in %r tag needs at least '
                                          "one keyword argument." % bits[0])
        elif option == "only":
            value = True
        else:
            raise TemplateSyntaxError(
                f"Unknown argument for {bits[0]!r} tag: {option!r}.")
        options[option] = value
    isolated_context = options.get("only", False)
    namemap = options.get("with", {})
    bits[1] = construct_relative_path(parser.origin.template_name, bits[1])
    # End exact copy from do_include_node()

    nodelist = parser.parse(("endembed", ))
    parser.delete_first_token()

    return EmbedNode(
        parser.compile_filter(bits[1]),
        nodelist,
        extra_context=namemap,
        isolated_context=isolated_context,
    )
Example #5
0
def font_awesome_icon(parser, token):
    bits = token.split_contents()
    remaining_bits = bits[1:]
    extra_context = token_kwargs(bits, parser, support_legacy=False)
    if not extra_context:
        raise TemplateSyntaxError(
            format_lazy('{bit} accepts one argument', bit=bits[0]))
Example #6
0
 def render(self, context):
     if not self.variable in context:
         raise TemplateSyntaxError(
             f"Counter {self.variable} does not exist: Expected {{% counter {self.variable} %}} before."
         )
     del context[self.variable]
     return ""
Example #7
0
def clarity(parser, token):
    bits = token.split_contents()
    remaining_bits = bits[1:]
    if len(remaining_bits) < 1:
        raise TemplateSyntaxError('This tag requires at least one argument')
    tags = token_kwargs(remaining_bits, parser, support_legacy=False)
    return SimpleAnalyticNode(tags)
Example #8
0
def template_variable(parser, token):
    bits = token.split_contents()
    remaining_bits = bits[1:]
    extra_context = token_kwargs(remaining_bits, parser, support_legacy=False)
    if not extra_context:
        raise TemplateSyntaxError(
            f"'{bits[0]}' expects at least one key word variable")
    return MacroNode(remaining_bits, extra_context=extra_context)
Example #9
0
def price_to_text(price, currency=None, autoescape=True):
    currencies = ['$', '£', '€']
    if currency is None:
        currency = '€'
    if currency not in currencies:
        raise TemplateSyntaxError(f"Currency is not valid: {currency}")
    if currency != '€':
        return format_html('{}{}', currency, price)
    return format_html('{}{}', price, currency)
Example #10
0
def price_to_text(price, currency=None, autoescape=True):
    currencies = ['$', '£', '€']
    if currency is None:
        currency = '€'
    if currency not in currencies:
        raise TemplateSyntaxError(f"Currency is not valid: {currency}")
    if currency != '€':
        return f"{currency}{price}"
    return f"{price}{currency}"
Example #11
0
 def render(self, context):
     authorized_keys = ['analytics', 'optimize', 'gtm', 'remarketing']
     extra_context = {}
     for key, value in self.tags.items():
         if key not in authorized_keys:
             raise TemplateSyntaxError(
                 f"The following key '{key}' is not in the list of authorized keys. Use either: {', '.join(authorized_keys)}"
             )
         extra_context.update({key: value.resolve(context)})
     context.push(extra_context)
     return ''
Example #12
0
def grouping(parser, token):
    """regroupタグと以下の点を除いて同じ機能。
    ・3つ目の引数(グループ化するキー)は文字列ではなく、式として解釈される
    ・自動でソートされてからグループ化される
    """
    bits = token.split_contents()
    if len(bits) != 6:
        raise TemplateSyntaxError(
            "'grouping' は5つの引数を持つ必要があります。")  # pragma: no cover
    if bits[2] != "by":
        raise TemplateSyntaxError(
            "'grouping' の2つ目の引数は 'by' でなければなりません。")  # pragma: no cover
    if bits[4] != "as":
        raise TemplateSyntaxError(
            "'grouping' の4つ目の引数は 'as' でなければなりません。")  # pragma: no cover

    target = parser.compile_filter(bits[1])
    var_name = bits[5]
    group_by_name = parser.compile_filter(bits[3])
    return GroupingNode(target, group_by_name, var_name)
Example #13
0
    def render_tag(self, context, plugin):
        if not plugin:
            raise TemplateSyntaxError("Plugin is missing")

        content_renderer = context['cms_content_renderer']
        content = content_renderer.render_plugin(
            instance=plugin,
            context=context,
            editable=content_renderer.user_is_on_edit_mode(),
        )
        return content
Example #14
0
def impressions_for_cart(parser, token):
    """
    {% analytics_impressions queryset=queryset brand="Nawoka" metrics="a b c" %}
    """
    bits = token.split_contents()
    remaining_bits = bits[1:]
    extra_context = token_kwargs(remaining_bits, parser, support_legacy=False)
    if not extra_context:
        raise TemplateSyntaxError(
            f"'{bits[0]}' expects at least one key word variable")
    return AnalyticsNode(extra_context=extra_context)
Example #15
0
    def parse(cls, parser, token):
        """Parse a {% pageurlblock %} and make a PageUrlBlockNode instance."""
        usage = 'Use like {{% {} page as var_name %}}"'.format(cls.start_tag)

        bits = token.split_contents()
        if len(bits) != 4:
            raise TemplateSyntaxError(usage)
        if bits[-2] != 'as':
            raise TemplateSyntaxError(usage)
        _pageurlblock, page_var, _as, href_name = bits

        href_nodelist = parser.parse([cls.empty_tag, cls.end_tag])
        token = parser.next_token()
        if token.contents == cls.empty_tag:
            empty_nodelist = parser.parse([cls.end_tag])
            parser.delete_first_token()
        else:
            empty_nodelist = None

        return cls(href_nodelist, empty_nodelist,
                   parser.compile_filter(page_var), href_name)
Example #16
0
def check_template(template_source, using=None):
    """
    Loads and returns a template for the given name.

    Raises TemplateDoesNotExist if no such template exists.
    """
    errs = {}
    engines = _engine_list(using)
    # We should find at least one engine that does not raise an error.
    for engine in engines:
        try:
            try:
                return engine.from_string(template_source)
            except jinja2.TemplateSyntaxError as exc:
                new = TemplateSyntaxError(exc.args)
                new.template_debug = get_exception_info(exc)
                six.reraise(TemplateSyntaxError, new, sys.exc_info()[2])
        except TemplateSyntaxError as err:
            errs.update({engine: err})
    if errs:
        raise TemplateSyntaxError(errs)
Example #17
0
    def render(self, context):
        """Heavily inspired/borrowed from IncludeNode.render()"""

        # Exact copy from IncludeNode.render()
        template = self.template.resolve(context)
        # Does this quack like a Template?
        if not callable(getattr(template, "render", None)):
            # If not, try the cache and select_template().
            template_name = template or ()
            if isinstance(template_name, str):
                template_name = (template_name, )
            else:
                template_name = tuple(template_name)
            cache = context.render_context.dicts[0].setdefault(self, {})
            template = cache.get(template_name)
            if template is None:
                template = context.template.engine.select_template(
                    template_name)
                cache[template_name] = template
        # Use the base.Template of a backends.django.Template.
        elif hasattr(template, "template"):
            template = template.template
        values = {
            name: var.resolve(context)
            for name, var in self.extra_context.items()
        }
        # End exact copy from IncludeNode.render()

        # First, make sure that we only have valid slot nodes in the node list or empty text nodes as children
        try:
            invalid_node = next(n for n in self.nodelist
                                if not (is_valid_embedded_node(n)))

            raise TemplateSyntaxError(
                'Invalid node "%s" found within the embed tag (only "Slot" nodes are allowed)'
                % invalid_node.__class__.__name__)
        except StopIteration:
            slot_nodes = [n for n in self.nodelist if isinstance(n, SlotNode)]

        # Finally, render the node, taking isolated_context into account
        # (This is similar to IncludeNode.render() but we also need to store overridden slot values in th context)
        embedded_context = context.new() if self.isolated_context else context
        with embedded_context.push(values):
            slot_values = {
                SLOT_CONTEXT_KEY_PREFIX + n.name: n.render(embedded_context)
                for n in slot_nodes
            }
            with context.push(**slot_values):
                return template.render(context)
Example #18
0
    def test_fetch_custom_template_returns_default_if_syntax_error(
            self, mock_get_template, mocker):
        mock_get_template.side_effect = [
            TemplateSyntaxError("hello"),
            mocker.Mock()
        ]
        custom_name = "hello"
        default_name = "djangosaml2idp/login.html"

        mixin = IdPHandlerViewMixin()

        _ = mixin._fetch_custom_template(custom_name, default_name)

        first_call = mocker.call(custom_name, using=None)
        second_call = mocker.call('djangosaml2idp/login.html', using=None)
        mock_get_template.assert_has_calls((first_call, second_call))
Example #19
0
    def prepare_text(self, obj):
        """Return text for indexing.

        Args:
            obj (GeneralPage): Object for indexing.

        Returns:
            String for indexing.
        """
        rendered = render_to_string(obj.template, {"LANGUAGE_CODE": "en"})
        html = fromstring(rendered)
        selector = CSSSelector("#general-page-content")
        try:
            contents = selector(html)[0].text_content()
        except IndexError:
            raise TemplateSyntaxError(CONTENT_NOT_FOUND_ERROR_MESSAGE)
        return contents
Example #20
0
def company_details(key, urlize=False):
    try:
        value = company[key]
    except KeyError:
        available_keys = company.keys()
        raise TemplateSyntaxError(
            ('Could not get the following key "%s".'
             ' Available keys are %s' % (key, ', '.join(available_keys))))
    else:
        if key == 'domain':
            value = f"https://{value}/"

        if key == 'email' and urlize:
            value = mark_safe(f"<a href='mailto:{value}'>{value}</a>")

        if key == 'domain' and urlize == True:
            value = mark_safe(f"<a href='{value}'>{value}</a>")

        return value
Example #21
0
def do_slot(parser, token):
    """{% slot %} template tag.

    Example::

        {% embed 'section.html' %}
            {% slot title %}<h1>Title</h1>{% endslot %}
            {% slot content %}<p>Content</p>{% endslot %}
        {% endembed %}
    """

    nodelist = parser.parse(("endslot", ))
    parser.delete_first_token()

    bits = token.split_contents()
    if len(bits) < 2:
        raise TemplateSyntaxError(
            "%r tag takes at least one argument: the name of the template to "
            "be embedded." % bits[0])

    return SlotNode(bits[1], nodelist)
Example #22
0
def paginator(context, adjacent_pages=2, align='initial', no_margin=False):
    """
    Adds pagination context variables for use in displaying first, adjacent and last page links in addition
    to those created by the object_list generic view.

    Based on:
     http://www.djangosnippets.org/snippets/73/
     http://www.tummy.com/Community/Articles/django-pagination/

        :param context: Current page context
        :type context: django.template.context.RequestContext

        :param adjacent_pages: Adjacent page links to current page link, defaults to 2
        :type adjacent_pages: int, optional

        :param align: Element alignment. Valid values are ``left``, ``right``, ``center``, ``initial``.
            Defaults to ``initial``
        :type align: str, optional

        :param no_margin: Toggle to remove margin around element, defaults to ``False``.
        :type no_margin: bool, optional

        :return: Paginator page context:

            * page_obj     - paginated list objects
            * paginator    - paginator object
            * current_page - current page number
            * last_page    - last page number
            * page_numbers - total number of pages
            * has_prev     - toggle to show previous page link
            * has_next     - toggle to show next page link
            * prev_page    - previous page number
            * next_page    - next page number
            * show_first   - toggle to show first page link
            * show_last    - toggle to show last page link
        :rtype: dict
    """
    page_obj = context['page_obj']
    paginator = context['paginator']
    current_page = page_obj.number
    number_of_pages = paginator.num_pages

    if align == const.PAGINATOR_ALIGN_INITIAL:
        align = ''
    elif align == const.PAGINATOR_ALIGN_CENTER:
        align = 'text-center'
    elif align == const.PAGINATOR_ALIGN_LEFT:
        align = 'pull-left'
    elif align == const.PAGINATOR_ALIGN_RIGHT:
        align = 'pull-right'
    else:
        raise TemplateSyntaxError(
            '"align" parameter valid values are: {}'.format(', '.join(const.PAGINATOR_ALIGN_CHOICES)))

    start_page = max(current_page - adjacent_pages, 1)

    end_page = current_page + adjacent_pages + 1
    if end_page > number_of_pages:
        end_page = number_of_pages + 1

    page_numbers = [n for n in range(start_page, end_page) if 0 < n <= number_of_pages]

    return {
        'page_obj': page_obj,
        'paginator': paginator,
        'current_page': current_page,
        'last_page': number_of_pages,
        'page_numbers': page_numbers,
        'has_prev': page_obj.has_previous(),
        'has_next': page_obj.has_next(),
        'prev_page': page_obj.previous_page_number,
        'next_page': page_obj.next_page_number,
        'show_first': 1 != current_page,
        'show_last': number_of_pages != current_page,
        'align': align,
        'no_margin': no_margin,
    }
Example #23
0
def gravatar_url(context, user=None, size=None, default=None, force_default=None, rating=None):
    """
    Generate a Gravatar image URL based on the current user

    Based on:
     https://github.com/adamcharnock/django-adminlte2/tree/master/django_adminlte/templatetags.

    References:
     https://en.gravatar.com/site/implement/images/
     https://en.gravatar.com/site/implement/images/python/

    :param context: Current page context
    :type context: django.template.context.RequestContext

    :param user: User object, defaults to None (uses User object from context)
    :type user: django.contrib.auth.models.User, optional

    :param size: Image size. You may request images anywhere from 1px up to 2048px. Defaults to 80.
    :type size: int, optional

    :param default: Default image. Available options are:
        * <url>: Image URL path
        * 404: do not load any image if none is associated with the email hash, instead return an HTTP 404 response
        * mp: a simple, cartoon-style silhouetted outline of a person (does not vary by email hash)
        * identicon: a geometric pattern based on an email hash
        * monsterid: a generated 'monster' with different colors, faces, etc
        * wavatar: generated faces with differing features and backgrounds
        * retro: awesome generated, 8-bit arcade-style pixelated faces
        * robohash: a generated robot with different colors, faces, etc
        * blank: a transparent PNG image
    :type default: str, optional

    :param force_default: Toggle to force load default image, defaults to False
    :type force_default: bool, optional

    :param rating: Image rating:
        * g: suitable for display on all websites with any audience type
        * pg: may contain rude gestures, provocatively dressed individuals, the lesser swear words, or mild violence
        * r: may contain such things as harsh profanity, intense violence, nudity, or hard drug use
        * x: may contain hardcore sexual imagery or extremely disturbing violence
    :type rating: str, optional

    :return: Gravatar image URL string
    :rtype: str
    """
    size = size or get_settings('ADMINLTE_GRAVATAR_SIZE')
    default = default or get_settings('ADMINLTE_GRAVATAR_DEFAULT')
    rating = rating or get_settings('ADMINLTE_GRAVATAR_RATING')
    user = context['request'].user if not user else user

    if not const.GRAVATAR_SIZE_MINIMUM <= size <= const.GRAVATAR_SIZE_MAXIMUM:
        raise TemplateSyntaxError('"size" parameter only allows int values from {} to {}'.format(
            const.GRAVATAR_SIZE_MINIMUM, const.GRAVATAR_SIZE_MAXIMUM
        ))

    if default not in const.GRAVATAR_DEFAULT_CHOICES:
        raise TemplateSyntaxError(
            '"default" parameter valid values are: {}'.format(', '.join(const.GRAVATAR_DEFAULT_CHOICES)))

    if rating not in const.GRAVATAR_RATING_CHOICES:
        raise TemplateSyntaxError(
            '"rating" parameter valid values are: {}'.format(', '.join(const.GRAVATAR_RATING_CHOICES)))

    if force_default is None:
        force_default = get_settings('ADMINLTE_GRAVATAR_FORCE_DEFAULT')

    params = [
        ('s', size),
        ('d', default),
        ('r', rating),
    ]

    if force_default:
        params.append(('f', 'y'))

    params = urlencode(params)

    return mark_safe('https://www.gravatar.com/avatar/{hash}?{params}'.format(  # nosec
        hash=hashlib.md5(user.email.encode('utf-8').lower()).hexdigest() if user.is_authenticated else '',  # nosec
        params=params,
    ))
Example #24
0
 def __mod__(self, ref):
     raise TemplateSyntaxError(f'Invalid reference in template: {ref}')
Example #25
0
def parse_bits(parser, bits, params, varargs, varkw, defaults, kwonly,
               kwonly_defaults, takes_context, name):
    """
    Parse bits for template tag helpers simple_tag and inclusion_tag, in
    particular by detecting syntax errors and by extracting positional and
    keyword arguments.
    """
    if takes_context:
        if params[0] == 'context':
            params = params[1:]
        else:
            raise TemplateSyntaxError(
                "'%s' is decorated with takes_context=True so it must "
                "have a first argument of 'context'" % name)
    args = []
    kwargs = {}
    unhandled_params = list(params)
    unhandled_kwargs = [
        kwarg for kwarg in kwonly
        if not kwonly_defaults or kwarg not in kwonly_defaults
    ]
    for bit in bits:
        # First we try to extract a potential kwarg from the bit
        kwarg = token_kwargs([bit], parser)
        if kwarg:
            # The kwarg was successfully extracted
            param, value = kwarg.popitem()
            if param not in params and param not in unhandled_kwargs and varkw is None:
                # An unexpected keyword argument was supplied
                raise TemplateSyntaxError(
                    "'%s' received unexpected keyword argument '%s'" %
                    (name, param))
            elif param in kwargs:
                # The keyword argument has already been supplied once
                raise TemplateSyntaxError(
                    "'%s' received multiple values for keyword argument '%s'" %
                    (name, param))
            else:
                # All good, record the keyword argument
                kwargs[str(param)] = value
                if param in unhandled_params:
                    # If using the keyword syntax for a positional arg, then
                    # consume it.
                    unhandled_params.remove(param)
                elif param in unhandled_kwargs:
                    # Same for keyword-only arguments
                    unhandled_kwargs.remove(param)
        else:
            if kwargs:
                raise TemplateSyntaxError(
                    "'%s' received some positional argument(s) after some "
                    "keyword argument(s)" % name)
            else:
                # Record the positional argument
                args.append(parser.compile_filter(bit))
                try:
                    # Consume from the list of expected positional arguments
                    unhandled_params.pop(0)
                except IndexError:
                    if varargs is None:
                        raise TemplateSyntaxError(
                            "'%s' received too many positional arguments" %
                            name)
    if defaults is not None:
        # Consider the last n params handled, where n is the
        # number of defaults.
        unhandled_params = unhandled_params[:-len(defaults)]
    if unhandled_params or unhandled_kwargs:
        # Some positional arguments were not supplied
        raise TemplateSyntaxError(
            "'%s' did not receive value(s) for the argument(s): %s" %
            (name, ", ".join("'%s'" % p
                             for p in unhandled_params + unhandled_kwargs)))
    return args, kwargs
Example #26
0
def get_product_variant(product, size=None):
    if size is None:
        raise TemplateSyntaxError('size required for fetching product price')
    return product.variants.filter(size=size).first()
 def from_string(self, template_code):
     raise TemplateSyntaxError(
         "The from_string() method is not implemented")
Example #28
0
def branded_url(parser, token):
    r"""
    Return an absolute URL matching the given view with its parameters.

    This is a way to define links that aren't tied to a particular URL
    configuration::

        {% url "url_name" arg1 arg2 %}

        or

        {% url "url_name" name1=value1 name2=value2 %}

    The first argument is a URL pattern name. Other arguments are
    space-separated values that will be filled in place of positional and
    keyword arguments in the URL. Don't mix positional and keyword arguments.
    All arguments for the URL must be present.

    For example, if you have a view ``app_name.views.client_details`` taking
    the client's id and the corresponding line in a URLconf looks like this::

        path('client/<int:id>/', views.client_details, name='client-detail-view')

    and this app's URLconf is included into the project's URLconf under some
    path::

        path('clients/', include('app_name.urls'))

    then in a template you can create a link for a certain client like this::

        {% url "client-detail-view" client.id %}

    The URL will look like ``/clients/client/123/``.

    The first argument may also be the name of a template variable that will be
    evaluated to obtain the view name or the URL name, e.g.::

        {% with url_name="client-detail-view" %}
        {% url url_name client.id %}
        {% endwith %}
    """
    bits = token.split_contents()
    if len(bits) < 2:
        raise TemplateSyntaxError(
            "'%s' takes at least one argument, a URL pattern name." % bits[0])
    viewname = parser.compile_filter(bits[1])
    args = []
    kwargs = {}
    asvar = None
    bits = bits[2:]

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

    for bit in bits:
        match = kwarg_re.match(bit)
        if not match:
            raise TemplateSyntaxError("Malformed arguments to url tag")
        name, value = match.groups()
        if name:
            kwargs[name] = parser.compile_filter(value)
        else:
            args.append(parser.compile_filter(value))

    return URLNode(viewname, args, kwargs, asvar)