Django

Code

Ticket #2606: 2606.4.diff

File 2606.4.diff, 6.2 kB (added by Ivan Sagalaev <Maniac@SoftwareManiacs.Org>, 2 years ago)

Patch + docs + tests

  • django/template/defaulttags.py

    old new  
    315315    def render(self, context): 
    316316        return self.mapping.get(self.tagtype, '') 
    317317 
     318class URLNode(Node): 
     319    def __init__(self, view_name, args, kwargs): 
     320        self.view_name = view_name 
     321        self.args = args 
     322        self.kwargs = kwargs 
     323       
     324    def render(self, context): 
     325        from django.core.urlresolvers import reverse, NoReverseMatch 
     326        args = [arg.resolve(context) for arg in self.args] 
     327        kwargs = dict([(k, v.resolve(context)) for k, v in self.kwargs.items()]) 
     328        try: 
     329            return reverse(self.view_name, args=args, kwargs=kwargs) 
     330        except NoReverseMatch: 
     331            try: 
     332                project_name = settings.SETTINGS_MODULE.split('.')[0] 
     333                return reverse(project_name + '.' + self.view_name, args=args, kwargs=kwargs) 
     334            except NoReverseMatch: 
     335                return '' 
     336 
    318337class WidthRatioNode(Node): 
    319338    def __init__(self, val_expr, max_expr, max_width): 
    320339        self.val_expr = val_expr 
     
    868887    return TemplateTagNode(tag) 
    869888templatetag = register.tag(templatetag) 
    870889 
     890def url(parser, token): 
     891    """ 
     892    Returns an absolute URL matching given view with its parameters. This is a mean to 
     893    define links that aren't tied to a particular url configuration: 
     894     
     895        {% url path.to.some_view arg1,arg2,name1=value1 %} 
     896     
     897    The first argument is a path to a view. It can be an absolute python path or just 
     898    ``app_name.view_name`` without the project name if the view is located inside the project.  
     899    Other arguments are comma-separated values that will be filled in place of  
     900    positional and keyword arguments in the URL. All arguments for the URL should be  
     901    present. 
     902     
     903    For example if you have a view ``app_name.client`` taking client's id and the  
     904    corresponding line in a urlconf looks like this: 
     905     
     906        ('^client/(\d+)/$', 'app_name.client') 
     907     
     908    ... and this app's urlconf is included into the project's urlconf under some path: 
     909     
     910        ('^clients/', include('project_name.app_name.urls')) 
     911     
     912    ... then in a template you can create a link for a certain client like this: 
     913     
     914        {% url app_name.client client.id %} 
     915     
     916    The URL will look like ``/clients/client/123/``. 
     917    """ 
     918    bits = token.contents.split(' ', 2) 
     919    if len(bits) < 2: 
     920        raise TemplateSyntaxError, "'%s' takes at least one argument (path to a view)" % bits[0] 
     921    args = [] 
     922    kwargs = {} 
     923    if len(bits) > 2: 
     924        for arg in bits[2].split(','): 
     925            if '=' in arg: 
     926                k, v = arg.split('=', 1) 
     927                kwargs[k] = parser.compile_filter(v) 
     928            else: 
     929                args.append(parser.compile_filter(arg)) 
     930    return URLNode(bits[1], args, kwargs) 
     931url = register.tag(url) 
     932 
    871933#@register.tag 
    872934def widthratio(parser, token): 
    873935    """ 
  • tests/regressiontests/templates/tests.py

    old new  
    620620            # Compare to a given parameter 
    621621            'timeuntil04' : ('{{ a|timeuntil:b }}', {'a':NOW - timedelta(days=1), 'b':NOW - timedelta(days=2)}, '1 day'), 
    622622            'timeuntil05' : ('{{ a|timeuntil:b }}', {'a':NOW - timedelta(days=2), 'b':NOW - timedelta(days=2, minutes=1)}, '1 minute'), 
     623 
     624            ### URL TAG ######################################################## 
     625            # Successes 
     626            'url01' : ('{% url regressiontests.templates.views.client client.id %}', {'client': {'id': 1}}, '/url_tag/client/1/'), 
     627            'url02' : ('{% url regressiontests.templates.views.client_action client.id,action="update" %}', {'client': {'id': 1}}, '/url_tag/client/1/update/'), 
     628            'url03' : ('{% url regressiontests.templates.views.index %}', {}, '/url_tag/'), 
     629 
     630            # Failures 
     631            'url04' : ('{% url %}', {}, template.TemplateSyntaxError), 
     632            'url05' : ('{% url no_such_view %}', {}, ''), 
     633            'url06' : ('{% url regressiontests.templates.views.client no_such_param="value" %}', {}, ''), 
    623634        } 
    624635 
    625636        # Register our custom template loader. 
  • tests/urls.py

    old new  
    77    # Always provide the auth system login and logout views 
    88    (r'^accounts/login/$', 'django.contrib.auth.views.login', {'template_name': 'login.html'}), 
    99    (r'^accounts/logout/$', 'django.contrib.auth.views.login'), 
     10     
     11    # test urlconf for {% url %} template tag 
     12    (r'^url_tag/', include('regressiontests.templates.urls')), 
    1013) 
  • docs/templates.txt

    old new  
    819819 
    820820Note: ``opencomment`` and ``closecomment`` are new in the Django development version. 
    821821 
     822url 
     823~~~ 
     824 
     825Returns an absolute URL matching given view with its parameters. This is a mean to 
     826define links that aren't tied to a particular url configuration: 
     827 
     828    {% url path.to.some_view arg1,arg2,name1=value1 %} 
     829 
     830The first argument is a path to a view. It can be an absolute python path or just 
     831``app_name.view_name`` without the project name if the view is located inside the project.  
     832Other arguments are comma-separated values that will be filled in place of  
     833positional and keyword arguments in the URL. All arguments for the URL should be  
     834present. 
     835 
     836For example if you have a view ``app_name.client`` taking client's id and the  
     837corresponding line in a urlconf looks like this: 
     838 
     839    ('^client/(\d+)/$', 'app_name.client') 
     840 
     841... and this app's urlconf is included into the project's urlconf under some path: 
     842 
     843    ('^clients/', include('project_name.app_name.urls')) 
     844 
     845... then in a template you can create a link for a certain client like this: 
     846 
     847    {% url app_name.client client.id %} 
     848 
     849The URL will look like ``/clients/client/123/``. 
     850 
    822851widthratio 
    823852~~~~~~~~~~ 
    824853