Ticket #12945: 12945.2.2.diff
File 12945.2.2.diff, 9.3 KB (added by , 15 years ago) |
---|
-
django/template/defaulttags.py
diff --git a/django/template/defaulttags.py b/django/template/defaulttags.py index 0db77f1..3ffd071 100644
a b from django.utils.itercompat import groupby 14 14 from django.utils.safestring import mark_safe 15 15 16 16 register = Library() 17 # Regex for token keyword arguments 18 kwarg_re = re.compile(r"(?:(\w+)=)?(.+)") 17 19 18 20 class AutoEscapeControlNode(Node): 19 21 """Implements the actions of the autoescape tag.""" … … def templatetag(parser, token): 1071 1073 return TemplateTagNode(tag) 1072 1074 templatetag = register.tag(templatetag) 1073 1075 1074 # Regex for URL arguments including filters 1075 url_arg_re = re.compile( 1076 r"(?:(%(name)s)=)?(%(value)s(?:\|%(name)s(?::%(value)s)?)*)" % { 1077 'name':'\w+', 1078 'value':'''(?:(?:'[^']*')|(?:"[^"]*")|(?:[\w\.-]+))'''}, 1079 re.VERBOSE) 1076 # Backwards compatibility check which will fail against for old comma 1077 # separated arguments in the url tag. 1078 url_backwards_re = re.compile(r'''(('[^']*'|"[^"]*"|[^,]+)=?)+$''') 1080 1079 1081 1080 def url(parser, token): 1082 1081 """ … … def url(parser, token): 1085 1084 This is a way to define links that aren't tied to a particular URL 1086 1085 configuration:: 1087 1086 1088 {% url path.to.some_view arg1,arg2,name1=value1 %} 1087 {% url path.to.some_view arg1 arg2 %} 1088 1089 or 1090 1091 {% url path.to.some_view name1=value1 name2=value2 %} 1089 1092 1090 1093 The first argument is a path to a view. It can be an absolute python path 1091 1094 or just ``app_name.view_name`` without the project name if the view is … … def url(parser, token): 1117 1120 args = [] 1118 1121 kwargs = {} 1119 1122 asvar = None 1120 1121 if len(bits) > 2: 1122 bits = iter(bits[2:]) 1123 bits = bits[2:] 1124 if len(bits) >= 2 and bits[-2] == 'as': 1125 asvar = bits[-1] 1126 bits = bits[:-2] 1127 1128 # Backwards compatibility: {% url urlname arg1,arg2 %} or 1129 # {% url urlname arg1,arg2 as foo %} cases. 1130 if bits: 1131 old_args = ''.join(bits) 1132 if not url_backwards_re.match(old_args): 1133 bits = old_args.split(",") 1134 1135 if len(bits): 1123 1136 for bit in bits: 1124 if bit == 'as': 1125 asvar = bits.next() 1126 break 1137 match = kwarg_re.match(bit) 1138 if not match: 1139 raise TemplateSyntaxError("Malformed arguments to url tag") 1140 name, value = match.groups() 1141 if name: 1142 kwargs[name] = parser.compile_filter(value) 1127 1143 else: 1128 end = 0 1129 for i, match in enumerate(url_arg_re.finditer(bit)): 1130 if (i == 0 and match.start() != 0) or \ 1131 (i > 0 and (bit[end:match.start()] != ',')): 1132 raise TemplateSyntaxError("Malformed arguments to url tag") 1133 end = match.end() 1134 name, value = match.group(1), match.group(2) 1135 if name: 1136 kwargs[name] = parser.compile_filter(value) 1137 else: 1138 args.append(parser.compile_filter(value)) 1139 if end != len(bit): 1140 raise TemplateSyntaxError("Malformed arguments to url tag") 1144 args.append(parser.compile_filter(value)) 1141 1145 1142 1146 return URLNode(viewname, args, kwargs, asvar) 1143 1147 url = register.tag(url) -
docs/ref/templates/builtins.txt
diff --git a/docs/ref/templates/builtins.txt b/docs/ref/templates/builtins.txt index aabacc5..f015370 100644
a b Returns an absolute URL (i.e., a URL without the domain name) matching a given 891 891 view function and optional parameters. This is a way to output links without 892 892 violating the DRY principle by having to hard-code URLs in your templates:: 893 893 894 {% url path.to.some_view arg1 ,arg2,name1=value1 %}894 {% url path.to.some_view arg1 arg2 name1=value1 %} 895 895 896 896 The first argument is a path to a view function in the format 897 897 ``package.package.module.function``. Additional arguments are optional and … … If you'd like to retrieve a URL without displaying it, you can use a slightly 935 935 different call:: 936 936 937 937 938 {% url path.to.view arg ,arg2 as the_url %}938 {% url path.to.view arg arg2 as the_url %} 939 939 940 940 <a href="{{ the_url }}">I'm linking to {{ the_url }}</a> 941 941 … … This will follow the normal :ref:`namespaced URL resolution strategy 957 957 <topics-http-reversing-url-namespaces>`, including using any hints provided 958 958 by the context as to the current application. 959 959 960 .. versionchanged:: 1.2 961 962 For backwards compatibility, the ``{% url %}`` tag supports the old syntax 963 from previous Django versions of comma separating the arguments. The previous 964 syntax does not support commas as part of string literals in the arguments. 965 960 966 .. templatetag:: widthratio 961 967 962 968 widthratio -
tests/regressiontests/templates/tests.py
diff --git a/tests/regressiontests/templates/tests.py b/tests/regressiontests/templates/tests.py index 307fecc..0697fbb 100644
a b class Templates(unittest.TestCase): 1020 1020 1021 1021 ### URL TAG ######################################################## 1022 1022 # Successes 1023 'legacyurl02': ('{% url regressiontests.templates.views.client_action id=client.id,action="update" %}', {'client': {'id': 1}}, '/url_tag/client/1/update/'), 1024 'legacyurl02a': ('{% url regressiontests.templates.views.client_action client.id,"update" %}', {'client': {'id': 1}}, '/url_tag/client/1/update/'), 1025 'legacyurl10': ('{% url regressiontests.templates.views.client_action id=client.id,action="two words" %}', {'client': {'id': 1}}, '/url_tag/client/1/two%20words/'), 1026 'legacyurl13': ('{% url regressiontests.templates.views.client_action id=client.id, action=arg|join:"-" %}', {'client': {'id': 1}, 'arg':['a','b']}, '/url_tag/client/1/a-b/'), 1027 'legacyurl14': ('{% url regressiontests.templates.views.client_action client.id, arg|join:"-" %}', {'client': {'id': 1}, 'arg':['a','b']}, '/url_tag/client/1/a-b/'), 1028 1023 1029 'url01': ('{% url regressiontests.templates.views.client client.id %}', {'client': {'id': 1}}, '/url_tag/client/1/'), 1024 'url02': ('{% url regressiontests.templates.views.client_action id=client.id ,action="update" %}', {'client': {'id': 1}}, '/url_tag/client/1/update/'),1025 'url02a': ('{% url regressiontests.templates.views.client_action client.id ,"update" %}', {'client': {'id': 1}}, '/url_tag/client/1/update/'),1030 'url02': ('{% url regressiontests.templates.views.client_action id=client.id action="update" %}', {'client': {'id': 1}}, '/url_tag/client/1/update/'), 1031 'url02a': ('{% url regressiontests.templates.views.client_action client.id "update" %}', {'client': {'id': 1}}, '/url_tag/client/1/update/'), 1026 1032 'url03': ('{% url regressiontests.templates.views.index %}', {}, '/url_tag/'), 1027 1033 'url04': ('{% url named.client client.id %}', {'client': {'id': 1}}, '/url_tag/named-client/1/'), 1028 1034 'url05': (u'{% url метка_оператора v %}', {'v': u'Ω'}, '/url_tag/%D0%AE%D0%BD%D0%B8%D0%BA%D0%BE%D0%B4/%CE%A9/'), … … class Templates(unittest.TestCase): 1030 1036 'url07': (u'{% url regressiontests.templates.views.client2 tag=v %}', {'v': u'Ω'}, '/url_tag/%D0%AE%D0%BD%D0%B8%D0%BA%D0%BE%D0%B4/%CE%A9/'), 1031 1037 'url08': (u'{% url метка_оператора v %}', {'v': 'Ω'}, '/url_tag/%D0%AE%D0%BD%D0%B8%D0%BA%D0%BE%D0%B4/%CE%A9/'), 1032 1038 'url09': (u'{% url метка_оператора_2 tag=v %}', {'v': 'Ω'}, '/url_tag/%D0%AE%D0%BD%D0%B8%D0%BA%D0%BE%D0%B4/%CE%A9/'), 1033 'url10': ('{% url regressiontests.templates.views.client_action id=client.id,action="two words" %}', {'client': {'id': 1}}, '/url_tag/client/1/two%20words/'), 1034 'url11': ('{% url regressiontests.templates.views.client_action id=client.id,action="==" %}', {'client': {'id': 1}}, '/url_tag/client/1/==/'), 1035 'url12': ('{% url regressiontests.templates.views.client_action id=client.id,action="," %}', {'client': {'id': 1}}, '/url_tag/client/1/,/'), 1036 'url12': ('{% url regressiontests.templates.views.client_action id=client.id,action=arg|join:"-" %}', {'client': {'id': 1}, 'arg':['a','b']}, '/url_tag/client/1/a-b/'), 1039 'url10': ('{% url regressiontests.templates.views.client_action id=client.id action="two words" %}', {'client': {'id': 1}}, '/url_tag/client/1/two%20words/'), 1040 'url11': ('{% url regressiontests.templates.views.client_action id=client.id action="==" %}', {'client': {'id': 1}}, '/url_tag/client/1/==/'), 1041 'url12': ('{% url regressiontests.templates.views.client_action id=client.id action="," %}', {'client': {'id': 1}}, '/url_tag/client/1/,/'), 1042 'url13': ('{% url regressiontests.templates.views.client_action id=client.id action=arg|join:"-" %}', {'client': {'id': 1}, 'arg':['a','b']}, '/url_tag/client/1/a-b/'), 1043 'url14': ('{% url regressiontests.templates.views.client_action client.id arg|join:"-" %}', {'client': {'id': 1}, 'arg':['a','b']}, '/url_tag/client/1/a-b/'), 1044 'url15': ('{% url regressiontests.templates.views.client_action 12 "test" %}', {}, '/url_tag/client/12/test/'), 1037 1045 1038 1046 # Failures 1039 1047 'url-fail01': ('{% url %}', {}, template.TemplateSyntaxError),