Ticket #2606: 2606.3.diff

File 2606.3.diff, 3.0 KB (added by Ivan Sagalaev <Maniac@…>, 9 years ago)

Support for referring views outside project

  • django/template/defaulttags.py

     
    303303    def render(self, context):
    304304        return self.mapping.get(self.tagtype, '')
    305305
     306class URLNode(Node):
     307    def __init__(self, view_name, args, kwargs):
     308        self.view_name = view_name
     309        self.args = args
     310        self.kwargs = kwargs
     311     
     312    def render(self, context):
     313        from django.core.urlresolvers import reverse, NoReverseMatch
     314        args = [arg.resolve(context) for arg in self.args]
     315        kwargs = dict([(k, v.resolve(context)) for k, v in self.kwargs.items()])
     316        try:
     317            return reverse(self.view_name, args=args, kwargs=kwargs)
     318        except NoReverseMatch:
     319            try:
     320                project_name = settings.SETTINGS_MODULE.split('.')[0]
     321                return reverse(project_name + '.' + self.view_name, args=args, kwargs=kwargs)
     322            except NoReverseMatch:
     323                return ''
     324
    306325class WidthRatioNode(Node):
    307326    def __init__(self, val_expr, max_expr, max_width):
    308327        self.val_expr = val_expr
     
    843862    return TemplateTagNode(tag)
    844863templatetag = register.tag(templatetag)
    845864
     865def url(parser, token):
     866    """
     867    Returns an absolute URL matching given view with its parameters. This is a mean to
     868    define links that aren't tied to a particular url configuration:
     869   
     870        {% url path.to.some_view arg1,arg2,name1=value1 %}
     871   
     872    The first argument is a path to a view. It can be an absolute python path or just
     873    ``app_name.view_name`` without the project name if the view is inside the project.
     874    Other arguments are comma-separated values that will be filled in place of
     875    positional and keyword arguments in the URL. All arguments for the URL should be
     876    present.
     877   
     878    For example if you have a view ``app_name.client`` taking client's id and the
     879    corresponding line in the urlconf looks like this:
     880   
     881        ('^client/(\d+)/$', 'app_name.client')
     882   
     883    ... and this app's urlconf is included into the project's urlconf under some path:
     884   
     885        ('^clients/', include('project_name.app_name.urls'))
     886   
     887    ... then in a template you can create a link for a certain client like this:
     888   
     889        {% url app_name.client client.id %}
     890   
     891    The URL will look like ``/clients/client/123/``.
     892    """
     893    bits = token.contents.split(' ', 2)
     894    if len(bits) < 2:
     895        raise TemplateSyntaxError, "'url' takes at least one argument (path to a view)"
     896    args = []
     897    kwargs = {}
     898    if len(bits) > 2:
     899        for arg in bits[2].split(','):
     900            if '=' in arg:
     901                k, v = arg.split('=', 1)
     902                kwargs[k] = parser.compile_filter(v)
     903            else:
     904                args.append(parser.compile_filter(arg))
     905    return URLNode(bits[1], args, kwargs)
     906url = register.tag(url)
     907
    846908#@register.tag
    847909def widthratio(parser, token):
    848910    """
Back to Top