Django

Code

Ticket #2606: 2606.3.diff

File 2606.3.diff, 3.0 kB (added by Ivan Sagalaev <Maniac@SoftwareManiacs.Org>, 3 years ago)

Support for referring views outside project

  • django/template/defaulttags.py

    old new  
    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    """