Ejemplo n.º 1
0
def url(parser, token):
	"""
	Returns an absolute URL matching given view with its parameters.

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

		{% url "path.to.some_view" arg1 arg2 %}

		or

		{% url "path.to.some_view" name1=value1 name2=value2 %}

	The first argument is a path to a view. It can be an absolute python path
	or just ``app_name.view_name`` without the project name if the view is
	located inside the project.  Other arguments are comma-separated values
	that will be filled in place of positional and keyword arguments in the
	URL. All arguments for the URL should be present.

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

		('^client/(\d+)/$', 'app_name.client')

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

		('^clients/', include('project_name.app_name.urls'))

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

		{% url "app_name.client" client.id %}

	The URL will look like ``/clients/client/123/``.
	"""
	bits = token.split_contents()
	if len(bits) < 2:
		raise TemplateSyntaxError("'%s' takes at least one argument"
								  " (path to a view)" % 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]

	if len(bits):
		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, legacy_view_name=False)
Ejemplo n.º 2
0
def render_view(parser, token):
    """
    Return an string version of a View with as_string method.
    First argument is the name of the view. Any other arguments
    should be keyword arguments and will be passed to the view.

    Example:

    {% render_view viewname var1=xx var2=yy %}
    """
    bits = token.split_contents()

    n = len(bits)
    if n < 2:
        raise TemplateSyntaxError("'%s' takes at least one view as argument")

    viewname = bits[1]

    kwargs = {}
    if n > 2:
        for bit in bits[2:]:
            match = kwarg_re.match(bit)
            if not match:
                raise TemplateSyntaxError("Malformed arguments to render_view tag")
            name, value = match.groups()
            if name:
                kwargs[name] = parser.compile_filter(value)

    return StringNode(viewname, kwargs)
Ejemplo n.º 3
0
def goblog_blogurl(parser, token):
    # syntax: goblog_blogurl VIEWNAME BLOGID arg1 arg2 kwarg1=val1 kwarg2=val2
    bits = token.split_contents()
    format = '{% goblog_blogurl VIEWNAME BLOGID [arg ...] [kwarg=val ...] %}'
    if len(bits) < 3:
        raise template.TemplateSyntaxError("goblog_blogurl "
            "tag should be in format: {0}".format(format))
    viewname = parser.compile_filter(bits[1])
    blogid = parser.compile_filter(bits[2])
    args = []
    kwargs = {}
    asvar = None
    
    bits = bits[3:]
    for bit in bits:
        match = kwarg_re.match(bit)
        if not match:
            raise template.TemplateSyntaxError("Malformed arguments to goblog_blogurl tag")
        name, value = match.groups()
        if name:
            kwargs[name] = parser.compile_filter(value)
        else:
            args.append(parser.compile_filter(value))

    return BlogUrlNode(viewname, blogid, args, kwargs, asvar)
Ejemplo n.º 4
0
def parse_price_tag(parser, token):
    bits = token.split_contents()
    tag_name = bits[0]
    if len(bits) < 3:
        raise template.TemplateSyntaxError(
                "'%s' syntax is {%% %s <instance> [currency='<iso-code>'] as <variable-name> %%}" % (
                    tag_name, tag_name))
    item = parser.compile_filter(bits[1])
    kwargs = {}
    asvar = None
    bits = bits[2:]
    if len(bits) >= 2 and bits[-2] == 'as':
        asvar = bits[-1]
        bits = bits[:-2]
    if len(bits):
        for bit in bits:
            match = kwarg_re.match(bit)
            if not match:
                raise template.TemplateSyntaxError("Malformed arguments to '%s' tag" % (tag_name,))
            name, value = match.groups()
            if name:
                kwargs[name] = parser.compile_filter(value)
            else:
                raise template.TemplateSyntaxError("'%s' takes only named arguments" % (tag_name,))
    return item, kwargs, asvar
Ejemplo n.º 5
0
def active_url(parser, token):
    bits = token.split_contents()
    if len(bits) < 2:
        raise TemplateSyntaxError("'%s' takes at least one argument"
                                  " (path to a view)" % 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]

    if len(bits):
        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 ActiveURLNode(viewname, args, kwargs, asvar)
Ejemplo n.º 6
0
def _loginza_widget(parser, token, html_template):
    def unquote(s):
        if s[0] in ('"', "'"): s = s[1:]
        if s[-1] in ('"', "'"): s = s[:-1]
        return s

    bits = token.split_contents()
    if len(bits) < 2:
        if html_template != iframe_template:
            raise TemplateSyntaxError("'%s' takes at least one argument"
                                      " (caption)" % bits[0])
        else:
            caption = ''
    else:
        caption = unquote(bits[1])

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

    # Now all the bits are parsed into new format,
    # process them as template vars
    if len(bits):
        for bit in bits:
            match = kwarg_re.match(bit)
            if not match:
                raise TemplateSyntaxError("Malformed arguments to loginza widget tag")
            name, value = match.groups()
            kwargs[name] = parser.compile_filter(value)

    return LoginzaWidgetNode(html_template, caption, kwargs, asvar)
Ejemplo n.º 7
0
def channel_url(parser, token):
    bits = token.split_contents()

    if len(bits) < 3:
        raise template.TemplateSyntaxError("'%s' takes at least one argument" " (channel and view name)" % bits[0])

    channel = parser.compile_filter(bits[1])
    viewname = parser.compile_filter(bits[2])
    bits = bits[3:]

    args = []
    kwargs = {}

    if len(bits):
        for bit in bits:
            match = kwarg_re.match(bit)
            if not match:
                raise template.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 ChannelURLNode(channel, viewname, args, kwargs)
Ejemplo n.º 8
0
def app_reverse(parser, token):
    """
    Returns an absolute URL for applications integrated with ApplicationContent

    The tag mostly works the same way as Django's own {% url %} tag::

        {% load applicationcontent_tags %}
        {% app_reverse "mymodel_detail" "myapp.urls" arg1 arg2 %}

        or

        {% load applicationcontent_tags %}
        {% app_reverse "mymodel_detail" "myapp.urls" name1=value1 %}

    The first argument is a path to a view. The second argument is the URLconf
    under which this app is known to the ApplicationContent. The second
    argument may also be a request object if you want to reverse an URL
    belonging to the current application content.

    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.

    If you want to store the URL in a variable instead of showing it right away
    you can do so too::

        {% app_reverse "mymodel_detail" "myapp.urls" arg1 arg2 as url %}
    """
    bits = token.split_contents()
    if len(bits) < 3:
        raise TemplateSyntaxError(
            "'%s' takes at least two arguments"
            " (path to a view and a urlconf)" % bits[0])
    viewname = parser.compile_filter(bits[1])
    urlconf = parser.compile_filter(bits[2])
    args = []
    kwargs = {}
    asvar = None
    bits = bits[3:]
    if len(bits) >= 2 and bits[-2] == 'as':
        asvar = bits[-1]
        bits = bits[:-2]

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

    return AppReverseNode(viewname, urlconf, args, kwargs, asvar)
Ejemplo n.º 9
0
def url(parser, token):
    bits = token.split_contents()
    if len(bits) < 2:
        raise TemplateSyntaxError("'%s' takes at least one argument"
                                  " (path to a view)" % bits[0])
    viewname = bits[1]
    args = []
    kwargs = {}
    asvar = None
    bits = bits[2:]
    if len(bits) >= 2 and bits[-2] == 'as':
        asvar = bits[-1]
        bits = bits[:-2]

    if bits and ',' in bits[0]:
        check_old_format = True
        for bit in bits[1:-1]:
            if ',' not in bit:
                check_old_format = False
                break
    else:
        check_old_format = False

    if check_old_format:
        match = kwarg_re.match(bits[0])
        if match:
            value = match.groups()[1]
            try:
                parser.compile_filter(value)
            except TemplateSyntaxError:
                bits = ''.join(bits).split(',')

    if len(bits):
        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)
Ejemplo n.º 10
0
def search_query(parser, token):
    bits = token.split_contents()[1:]
    kwargs = {}
    if len(bits):
        for bit in bits:
            match = kwarg_re.match(bit)
            if not match:
                raise TemplateSyntaxError("Malformed arguments to search_query tag")
            name, value = match.groups()
            kwargs[name] = parser.compile_filter(value)

    return SearchQueryNode(kwargs)
Ejemplo n.º 11
0
def node_url(parser, token):
	"""
	The :ttag:`node_url` tag allows access to :meth:`.View.reverse` from a template for a :class:`.Node`. By default, the :class:`.Node` that is used for the call is pulled from the context variable ``node``; however, this can be overridden with the ``[for <node>]`` option.
	
	Usage::
	
		{% node_url [for <node>] [as <var>] %}
		{% node_url with <obj> [for <node>] [as <var>] %}
		{% node_url <view_name> [<arg1> [<arg2> ...] ] [for <node>] [as <var>] %}
		{% node_url <view_name> [<key1>=<value1> [<key2>=<value2> ...] ] [for <node>] [as <var>] %}
	
	"""
	params = token.split_contents()
	tag = params[0]
	as_var = None
	with_obj = None
	node = None
	params = params[1:]
	
	if len(params) >= 2 and params[-2] == 'as':
		as_var = params[-1]
		params = params[:-2]
	
	if len(params) >= 2 and params[-2] == 'for':
		node = parser.compile_filter(params[-1])
		params = params[:-2]
	
	if len(params) >= 2 and params[-2] == 'with':
		with_obj = parser.compile_filter(params[-1])
		params = params[:-2]
	
	if with_obj is not None:
		if params:
			raise template.TemplateSyntaxError('`%s` template tag accepts no arguments or keyword arguments if with <obj> is specified.' % tag)
		return NodeURLNode(with_obj=with_obj, node=node, as_var=as_var)
	
	if params:
		args = []
		kwargs = {}
		view_name = params.pop(0)
		for param in params:
			match = kwarg_re.match(param)
			if not match:
				raise TemplateSyntaxError("Malformed arguments to `%s` tag" % tag)
			name, value = match.groups()
			if name:
				kwargs[name] = parser.compile_filter(value)
			else:
				args.append(parser.compile_filter(value))
		return NodeURLNode(view_name=view_name, args=args, kwargs=kwargs, node=node, as_var=as_var)
	
	return NodeURLNode(node=node, as_var=as_var)
Ejemplo n.º 12
0
def bundle_url(parser, token):
    """
    Returns an a url for given a bundle and a view name.
    This is done by calling the `get_view_url` method
    of the provided bundle.

    This tag expects that the request object as well as the
    the original url_params are available in the context.

    Requires two arguments bundle and the name of the view
    you want to render. In addition, this tag also accepts
    the 'as xxx' syntax.

    By default this tag will follow references to
    parent bundles. To stop this from happening pass
    `follow_parent=False`. Any other keyword arguments
    will be used as url keyword arguments.

    If no match is found a blank string will be returned.

    Example:

    {% bundle_url bundle "edit" obj=obj as html %}
    """

    bits = token.split_contents()
    if len(bits) < 3:
        raise TemplateSyntaxError("'%s' takes at least two arguments"
                                  " bundle and view_name" % bits[0])

    bundle = parser.compile_filter(bits[1])
    viewname = parser.compile_filter(bits[2])

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

    if len(bits):
        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)

    return URLNode(bundle, viewname, kwargs, asvar)
Ejemplo n.º 13
0
def _get_kwargs(parser, tag_name, bits):
	"""Helper function to get kwargs from a list of bits."""
	valid_kwargs = ('width', 'height', 'max_width', 'max_height', 'adjustment', 'crop')
	kwargs = {}
	
	for bit in bits:
		match = kwarg_re.match(bit)
		if not match:
			raise template.TemplateSyntaxError("Malformed arguments to `%s` tag" % tag_name)
		name, value = match.groups()
		if name not in valid_kwargs:
			raise template.TemplateSyntaxError("Invalid argument to `%s` tag: %s" % (tag_name, name))
		kwargs[str(name)] = parser.compile_filter(value)

	return kwargs
def parse_args_kwargs(parser, bits):
    args = []
    kwargs = {}

    for bit in bits:
        match = kwarg_re.match(bit)
        if not match:
            raise TemplateSyntaxError("Malformed arguments to domain_url tag")

        name, value = match.groups()
        if name:
            kwargs[name] = parser.compile_filter(value)
        else:
            args.append(parser.compile_filter(value))

    return args, kwargs
Ejemplo n.º 15
0
def app_reverse(parser, token):
    """
    Returns an absolute URL for applications integrated with ApplicationContent
    The tag mostly works the same way as Django's own {% url %} tag::
        {% load leonardo_tags %}
        {% app_reverse "mymodel_detail" "myapp.urls" arg1 arg2 %}
        or
        {% load leonardo_tags %}
        {% app_reverse "mymodel_detail" "myapp.urls" name1=value1 %}
    The first argument is a path to a view. The second argument is the URLconf
    under which this app is known to the ApplicationContent. The second
    argument may also be a request object if you want to reverse an URL
    belonging to the current application content.
    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.
    If you want to store the URL in a variable instead of showing it right away
    you can do so too::
        {% app_reverse "mymodel_detail" "myapp.urls" arg1 arg2 as url %}
    """
    bits = token.split_contents()
    if len(bits) < 3:
        raise TemplateSyntaxError("'%s' takes at least two arguments"
                                  " (path to a view and a urlconf)" % bits[0])
    viewname = parser.compile_filter(bits[1])
    urlconf = parser.compile_filter(bits[2])
    args = []
    kwargs = {}
    asvar = None
    bits = bits[3:]
    if len(bits) >= 2 and bits[-2] == 'as':
        asvar = bits[-1]
        bits = bits[:-2]

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

    return AppReverseNode(viewname, urlconf, args, kwargs, asvar)
def revision (parser, token, ) :
    """
{% url version_control_revision project=object.code path=None to_revision=object.version_control.latest_revision.number %}
    """

    _kw = dict()
    _bits = list(token.split_contents())
    for _b in _bits:
        _match = kwarg_re.match(_b)
        if not _match:
            raise TemplateSyntaxError("Malformed arguments to url tag")

        _n, _v = _match.groups()
        if _n:
            _kw[str(_n)] = parser.compile_filter(_v)

    return RevisionNode(**_kw)
Ejemplo n.º 17
0
def make_url(parser, token):
    """
    Just like {% url %} but takes an app/model/section-name trio to
    build a standard name lookup for an url.

    """
    bits = token.split_contents()
    verbose_name = None

    if 'as' in bits:
        verbose_name = parser.compile_filter(bits.pop())
        bits.pop()

    if len(bits) < 3:
        raise TemplateSyntaxError("'%s' takes at least two arguments"
                                  " (app, module)" % bits[0])
    elif len(bits) == 3:
        bits += ['index',]

    elif len(bits) > 4:
        raise TemplateSyntaxError("'%s' takes two or three arguments,"
                                  " you provided %s" % (bits[0], len(bits)))

    app, module, section = bits[1], bits[2], bits[3]

    view_name_bits = [parser.compile_filter(bit) for bit in (app, module, section)]

    args = []
    kwargs = {}
    bits = bits[4:]

    if len(bits):
        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))

    result = MenuURLNode(view_name_bits, verbose_name, args, kwargs)

    return result
Ejemplo n.º 18
0
def spurl(parser, token):
    bits = token.split_contents()
    if len(bits) < 2:
        raise TemplateSyntaxError("'spurl' takes at least one argument")

    args = []
    asvar = None
    bits = bits[1:]

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

    for bit in bits:
        name, value = kwarg_re.match(bit).groups()
        if not (name and value):
            raise TemplateSyntaxError("Malformed arguments to spurl tag")
        args.append((name, parser.compile_filter(value)))
    return SpurlNode(args, parser.tags, parser.filters, asvar)
Ejemplo n.º 19
0
def spurl(parser, token):
    bits = token.split_contents()
    if len(bits) < 2:
        raise TemplateSyntaxError("'spurl' takes at least one argument")

    args = []
    asvar = None
    bits = bits[1:]

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

    for bit in bits:
        name, value = kwarg_re.match(bit).groups()
        if not (name and value):
            raise TemplateSyntaxError("Malformed arguments to spurl tag")
        args.append((name, parser.compile_filter(value)))
    return SpurlNode(args, parser.tags, parser.filters, asvar)
Ejemplo n.º 20
0
def diagram(parser, token):
    bits = token.split_contents()
    if len(bits) < 2:
        raise TemplateSyntaxError("'%s' takes at least one argument"
                                  " (path to a view)" % bits[0])
    viewname = bits[1]
    args = []
    kwargs = {}
    bits = bits[2:]
    if len(bits):
        for bit in bits:
            match = kwarg_re.match(bit)
            if not match:
                raise TemplateSyntaxError("Malformed arguments to diagram tag")
            name, value = match.groups()
            if name:
                kwargs[name] = parser.compile_filter(value)
            else:
                args.append(parser.compile_filter(value))
    return DiagramNode(viewname, args, kwargs)
Ejemplo n.º 21
0
def parse_args(parser, bits):
    # see django.templatetags.future: url, line 80
    args = []
    kwargs = {}
    asvar = None
    if len(bits) >= 2 and bits[-2] == 'as':
        asvar = bits[-1]
        bits = bits[:-2]

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

    return args, kwargs, asvar
Ejemplo n.º 22
0
 def handle(cls, parser, token):
     bits = token.split_contents()
     if len(bits) < 2:
         raise template.TemplateSyntaxError(
             "'box' takes at least one argument (label of the content to display)"
         )
     args = []
     kwargs = {}
     label = parser.compile_filter(bits[1])
     bits = bits[2:]
     if len(bits):
         for bit in bits:
             match = kwarg_re.match(bit)
             if not match:
                 raise template.TemplateSyntaxError("Malformed arguments to 'box' tag")
             name, value = match.groups()
             if name:
                 kwargs[name] = parser.compile_filter(value)
             else:
                 args.append(parser.compile_filter(value))
     return cls(label, args, kwargs)
Ejemplo n.º 23
0
def urle(parser, token):
    from django.template.defaulttags import kwarg_re, URLNode
    bits = token.split_contents()
    if len(bits) < 2:
        raise TemplateSyntaxError("'%s' takes at least one argument"
                                  " (path to a view)" % bits[0])
    viewname = bits[1]
    args = []
    kwargs = {}
    asvar = None
    bits = bits[2:]

    if len(bits):
        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 + '|urlencodeall')
            else:
                args.append(parser.compile_filter(value))
    return URLNode(viewname, args, kwargs, asvar)
Ejemplo n.º 24
0
def bootstrap_field(parser,token):
    
    bits = token.split_contents()
    if len(bits) < 2:
        raise TemplateSyntaxError("'%s' takes at least one argument - a field" % bits[0])
    args = []
    kwargs = {}
    bits = bits[1:]
    if len(bits):
        for bit in bits:
            match = kwarg_re.match(bit)
            if not match:
                raise TemplateSyntaxError("Malformed arguments")
            name, value = match.groups()
            if name:
                kwargs[name] = parser.compile_filter(value)
            else:
                args.append(parser.compile_filter(value))
    
    if not len(args):
        return ''

    return BootstrapFieldNode(args,kwargs)
Ejemplo n.º 25
0
def bootstrap_field(parser, token):

    bits = token.split_contents()
    if len(bits) < 2:
        raise TemplateSyntaxError(
            "'%s' takes at least one argument - a field" % bits[0])
    args = []
    kwargs = {}
    bits = bits[1:]
    if len(bits):
        for bit in bits:
            match = kwarg_re.match(bit)
            if not match:
                raise TemplateSyntaxError("Malformed arguments")
            name, value = match.groups()
            if name:
                kwargs[name] = parser.compile_filter(value)
            else:
                args.append(parser.compile_filter(value))

    if not len(args):
        return ''

    return BootstrapFieldNode(args, kwargs)
def do_thumbnail(parser, token):
    """
    Creates a thumbnail if needed and displays its url.

    Usage::

        {% thumbnail source width height [destination] [processor] %}

    Or with keyword arguments::

        {% thumbnail source width height desc=destination proc=processor %}

    Keyword arguments specifying a processor and some custom options for it::

        {% thumbnail source width height proc=custom option1=var option2='str' %}

    Source and destination can be a file like object or a path as a string.
    """

    split_token = token.split_contents()
    args = []
    kwargs = {}
    as_var = None
    started_kwargs = False
    for k, v in enumerate(split_token[1:]):
        if v == 'as':
            try:
                as_var = split_token[k+2]
            except IndexError:
                raise template.TemplateSyntaxError(
                    "%r tag requires a variable name to attach to" \
                    % split_token[0]
                )
            break
        else:
            match = kwarg_re.match(v)
            if not match:
                raise template.TemplateSyntaxError(
                    "Malformed arguments to %r tag" % split_token[0]
                )
            name, value = match.groups()
            if name:
                # Python < 2.7 does not accept unicode keywords.
                # http://bugs.python.org/issue2646
                kwargs[name.encode('utf-8')] = value
                started_kwargs = True
            else:
                if started_kwargs:
                    raise template.TemplateSyntaxError(
                        "Positional arguments cannot come after keyword arguments"
                    )
                args.append(value)
    kwargs['as_var'] = as_var

    required_args = ['height', 'width', 'source']
    for i in range(0, len(args)):
        if required_args:
            required_args.pop()
    for arg in required_args:
        if arg not in kwargs:
            raise template.TemplateSyntaxError(
                "%r tag requires a source, a width and a height" \
                % split_token[0]
            )

    if len(args) > 5:
        kwargs['extra_args'] = args[5:]
        args = args[0:5]
    return ThumbnailNode(*args, **kwargs)
Ejemplo n.º 27
0
def url(parser, token):
    """
    Returns an absolute URL matching given view with its parameters.

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

        {% url path.to.some_view arg1 arg2 %}

        or

        {% url path.to.some_view name1=value1 name2=value2 %}

    The first argument is a path to a view. It can be an absolute python path
    or just ``app_name.view_name`` without the project name if the view is
    located inside the project.  Other arguments are comma-separated values
    that will be filled in place of positional and keyword arguments in the
    URL. All arguments for the URL should be present.

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

        ('^client/(\d+)/$', 'app_name.client')

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

        ('^clients/', include('project_name.app_name.urls'))

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

        {% url app_name.client client.id %}

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

    import warnings

    warnings.warn(
        "The syntax for the url template tag is changing. Load the `url` tag from the `future` tag library to start using the new behavior.",
        category=DeprecationWarning,
    )

    bits = token.split_contents()
    if len(bits) < 2:
        raise TemplateSyntaxError("'%s' takes at least one argument" " (path to a view)" % bits[0])
    viewname = bits[1]
    args = []
    kwargs = {}
    asvar = None
    bits = bits[2:]
    if len(bits) >= 2 and bits[-2] == "as":
        asvar = bits[-1]
        bits = bits[:-2]

    # Backwards compatibility: check for the old comma separated format
    # {% url urlname arg1,arg2 %}
    # Initial check - that the first space separated bit has a comma in it
    if bits and "," in bits[0]:
        check_old_format = True
        # In order to *really* be old format, there must be a comma
        # in *every* space separated bit, except the last.
        for bit in bits[1:-1]:
            if "," not in bit:
                # No comma in this bit. Either the comma we found
                # in bit 1 was a false positive (e.g., comma in a string),
                # or there is a syntax problem with missing commas
                check_old_format = False
                break
    else:
        # No comma found - must be new format.
        check_old_format = False

    if check_old_format:
        # Confirm that this is old format by trying to parse the first
        # argument. An exception will be raised if the comma is
        # unexpected (i.e. outside of a static string).
        match = kwarg_re.match(bits[0])
        if match:
            value = match.groups()[1]
            try:
                parser.compile_filter(value)
            except TemplateSyntaxError:
                bits = "".join(bits).split(",")

    # Now all the bits are parsed into new format,
    # process them as template vars
    if len(bits):
        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, legacy_view_name=True)
Ejemplo n.º 28
0
def url(parser, token):
    """
    Returns an absolute URL matching given view with its parameters.

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

        {% url "path.to.some_view" arg1 arg2 %}

        or

        {% url "path.to.some_view" name1=value1 name2=value2 %}

    The first argument is a path to a view. It can be an absolute Python path
    or just ``app_name.view_name`` without the project name if the view is
    located inside the project.

    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 should be present.

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

        ('^client/(\d+)/$', 'app_name.client')

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

        ('^clients/', include('project_name.app_name.urls'))

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

        {% url "app_name.client" client.id %}

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

    The first argument can also be a named URL instead of the Python path to
    the view callable. For example if the URLconf entry looks like this::

        url('^client/(\d+)/$', name='client-detail-view')

    then in the template you can use::

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

    There is even another possible value type for the first argument. It can be
    the name of a template variable that will be evaluated to obtain the view
    name or the URL name, e.g.::

        {% with view_path="app_name.client" %}
        {% url view_path client.id %}
        {% endwith %}

        or,

        {% 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"
                                  " (path to a view)" % 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]

    if len(bits):
        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, legacy_view_name=False)