Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Merge branch 'url-tag-asvar'

git-svn-id: http://code.djangoproject.com/svn/django/trunk@8716 bcc190cf-cafb-0310-a4f2-bffc1f526a37
  • Loading branch information...
commit c068bc184c3c78b7bc9a1c5d43cc78c92bc41999 1 parent 2ca8cf3
@jacobian jacobian authored
View
51 django/template/defaulttags.py
@@ -351,22 +351,40 @@ def render(self, context):
return self.mapping.get(self.tagtype, '')
class URLNode(Node):
- def __init__(self, view_name, args, kwargs):
+ def __init__(self, view_name, args, kwargs, asvar):
self.view_name = view_name
self.args = args
self.kwargs = kwargs
+ self.asvar = asvar
def render(self, context):
from django.core.urlresolvers import reverse, NoReverseMatch
args = [arg.resolve(context) for arg in self.args]
kwargs = dict([(smart_str(k,'ascii'), v.resolve(context))
for k, v in self.kwargs.items()])
+
+
+ # Try to look up the URL twice: once given the view name, and again
+ # relative to what we guess is the "main" app. If they both fail,
+ # re-raise the NoReverseMatch unless we're using the
+ # {% url ... as var %} construct in which cause return nothing.
+ url = ''
try:
- return reverse(self.view_name, args=args, kwargs=kwargs)
+ url = reverse(self.view_name, args=args, kwargs=kwargs)
except NoReverseMatch:
project_name = settings.SETTINGS_MODULE.split('.')[0]
- return reverse(project_name + '.' + self.view_name,
- args=args, kwargs=kwargs)
+ try:
+ url = reverse(project_name + '.' + self.view_name,
+ args=args, kwargs=kwargs)
+ except NoReverseMatch:
+ if self.asvar is None:
+ raise
+
+ if self.asvar:
+ context[self.asvar] = url
+ return ''
+ else:
+ return url
class WidthRatioNode(Node):
def __init__(self, val_expr, max_expr, max_width):
@@ -1041,21 +1059,30 @@ def url(parser, token):
The URL will look like ``/clients/client/123/``.
"""
- bits = token.contents.split(' ', 2)
+ bits = token.contents.split(' ')
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
+
if len(bits) > 2:
- for arg in bits[2].split(','):
- if '=' in arg:
- k, v = arg.split('=', 1)
- k = k.strip()
- kwargs[k] = parser.compile_filter(v)
+ bits = iter(bits[2:])
+ for bit in bits:
+ if bit == 'as':
+ asvar = bits.next()
+ break
else:
- args.append(parser.compile_filter(arg))
- return URLNode(bits[1], args, kwargs)
+ for arg in bit.split(","):
+ if '=' in arg:
+ k, v = arg.split('=', 1)
+ k = k.strip()
+ kwargs[k] = parser.compile_filter(v)
+ elif arg:
+ args.append(parser.compile_filter(arg))
+ return URLNode(viewname, args, kwargs, asvar)
url = register.tag(url)
#@register.tag
View
23 docs/ref/templates/builtins.txt
@@ -675,6 +675,29 @@ The template tag will output the string ``/clients/client/123/``.
<naming-url-patterns>`, you can refer to the name of the pattern in the ``url``
tag instead of using the path to the view.
+Note that if the URL you're reversing doesn't exist, you'll get an
+:exc:`NoReverseMatch` exception raised, which will cause your site to display an
+error page.
+
+**New in development verson:** If you'd like to retrieve a URL without displaying it,
+you can use a slightly different call:
+
+.. code-block:: html+django
+
+ {% url path.to.view arg, arg2 as the_url %}
+
+ <a href="{{ the_url }}">I'm linking to {{ the_url }}</a>
+
+This ``{% url ... as var %}`` syntax will *not* cause an error if the view is
+missing. In practice you'll use this to link to views that are optional:
+
+.. code-block:: html+django
+
+ {% url path.to.view as the_url %}
+ {% if the_url %}
+ <a href="{{ the_url }}">Link to optional stuff</a>
+ {% endif %}
+
.. templatetag:: widthratio
widthratio
View
5 tests/regressiontests/templates/tests.py
@@ -896,6 +896,11 @@ def get_template_tests(self):
'url-fail02': ('{% url no_such_view %}', {}, urlresolvers.NoReverseMatch),
'url-fail03': ('{% url regressiontests.templates.views.client %}', {}, urlresolvers.NoReverseMatch),
+ # {% url ... as var %}
+ 'url-asvar01': ('{% url regressiontests.templates.views.index as url %}', {}, ''),
+ 'url-asvar02': ('{% url regressiontests.templates.views.index as url %}{{ url }}', {}, '/url_tag/'),
+ 'url-asvar03': ('{% url no_such_view as url %}{{ url }}', {}, ''),
+
### CACHE TAG ######################################################
'cache01': ('{% load cache %}{% cache -1 test %}cache01{% endcache %}', {}, 'cache01'),
'cache02': ('{% load cache %}{% cache -1 test %}cache02{% endcache %}', {}, 'cache02'),
Please sign in to comment.
Something went wrong with that request. Please try again.