Django

Code

Changeset 8716

Show
Ignore:
Timestamp:
08/29/08 14:28:03 (3 months ago)
Author:
jacob
Message:

Merge branch 'url-tag-asvar'

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • django/trunk/django/template/defaulttags.py

    r8211 r8716  
    352352 
    353353class URLNode(Node): 
    354     def __init__(self, view_name, args, kwargs): 
     354    def __init__(self, view_name, args, kwargs, asvar): 
    355355        self.view_name = view_name 
    356356        self.args = args 
    357357        self.kwargs = kwargs 
     358        self.asvar = asvar 
    358359 
    359360    def render(self, context): 
     
    362363        kwargs = dict([(smart_str(k,'ascii'), v.resolve(context)) 
    363364                       for k, v in self.kwargs.items()]) 
     365         
     366         
     367        # Try to look up the URL twice: once given the view name, and again 
     368        # relative to what we guess is the "main" app. If they both fail,  
     369        # re-raise the NoReverseMatch unless we're using the  
     370        # {% url ... as var %} construct in which cause return nothing. 
     371        url = '' 
    364372        try: 
    365             return reverse(self.view_name, args=args, kwargs=kwargs) 
     373            url = reverse(self.view_name, args=args, kwargs=kwargs) 
    366374        except NoReverseMatch: 
    367375            project_name = settings.SETTINGS_MODULE.split('.')[0] 
    368             return reverse(project_name + '.' + self.view_name, 
    369                            args=args, kwargs=kwargs) 
     376            try: 
     377                url = reverse(project_name + '.' + self.view_name, 
     378                              args=args, kwargs=kwargs) 
     379            except NoReverseMatch: 
     380                if self.asvar is None: 
     381                    raise 
     382                     
     383        if self.asvar: 
     384            context[self.asvar] = url 
     385            return '' 
     386        else: 
     387            return url 
    370388 
    371389class WidthRatioNode(Node): 
     
    10421060    The URL will look like ``/clients/client/123/``. 
    10431061    """ 
    1044     bits = token.contents.split(' ', 2
     1062    bits = token.contents.split(' '
    10451063    if len(bits) < 2: 
    10461064        raise TemplateSyntaxError("'%s' takes at least one argument" 
    10471065                                  " (path to a view)" % bits[0]) 
     1066    viewname = bits[1] 
    10481067    args = [] 
    10491068    kwargs = {} 
     1069    asvar = None 
     1070         
    10501071    if len(bits) > 2: 
    1051         for arg in bits[2].split(','): 
    1052             if '=' in arg
    1053                 k, v = arg.split('=', 1) 
    1054                 k = k.strip() 
    1055                 kwargs[k] = parser.compile_filter(v) 
     1072        bits = iter(bits[2:]) 
     1073        for bit in bits
     1074            if bit == 'as': 
     1075                asvar = bits.next() 
     1076                break 
    10561077            else: 
    1057                 args.append(parser.compile_filter(arg)) 
    1058     return URLNode(bits[1], args, kwargs) 
     1078                for arg in bit.split(","): 
     1079                    if '=' in arg: 
     1080                        k, v = arg.split('=', 1) 
     1081                        k = k.strip() 
     1082                        kwargs[k] = parser.compile_filter(v) 
     1083                    elif arg: 
     1084                        args.append(parser.compile_filter(arg)) 
     1085    return URLNode(viewname, args, kwargs, asvar) 
    10591086url = register.tag(url) 
    10601087 
  • django/trunk/docs/ref/templates/builtins.txt

    r8651 r8716  
    676676tag instead of using the path to the view. 
    677677 
     678Note that if the URL you're reversing doesn't exist, you'll get an 
     679:exc:`NoReverseMatch` exception raised, which will cause your site to display an 
     680error page. 
     681 
     682**New in development verson:** If you'd like to retrieve a URL without displaying it, 
     683you can use a slightly different call: 
     684 
     685.. code-block:: html+django 
     686 
     687    {% url path.to.view arg, arg2 as the_url %} 
     688     
     689    <a href="{{ the_url }}">I'm linking to {{ the_url }}</a> 
     690     
     691This ``{% url ... as var %}`` syntax will *not* cause an error if the view is 
     692missing. In practice you'll use this to link to views that are optional: 
     693 
     694.. code-block:: html+django 
     695 
     696    {% url path.to.view as the_url %} 
     697    {% if the_url %} 
     698      <a href="{{ the_url }}">Link to optional stuff</a> 
     699    {% endif %} 
     700 
    678701.. templatetag:: widthratio 
    679702 
  • django/trunk/tests/regressiontests/templates/tests.py

    r8533 r8716  
    897897            'url-fail03': ('{% url regressiontests.templates.views.client %}', {}, urlresolvers.NoReverseMatch), 
    898898 
     899            # {% url ... as var %} 
     900            'url-asvar01': ('{% url regressiontests.templates.views.index as url %}', {}, ''), 
     901            'url-asvar02': ('{% url regressiontests.templates.views.index as url %}{{ url }}', {}, '/url_tag/'), 
     902            'url-asvar03': ('{% url no_such_view as url %}{{ url }}', {}, ''), 
     903 
    899904            ### CACHE TAG ###################################################### 
    900905            'cache01': ('{% load cache %}{% cache -1 test %}cache01{% endcache %}', {}, 'cache01'),