comparison piecrust/routing.py @ 1100:1ce67d2fae0a

routing: Fix URL generation bug with ugly URLs and index pages in sub-folders.
author Ludovic Chabant <ludovic@chabant.com>
date Sat, 17 Feb 2018 11:54:00 -0800
parents 45ad976712ec
children 6baa94da8b16
comparison
equal deleted inserted replaced
1099:07c23be08029 1100:1ce67d2fae0a
18 class RouteNotFoundError(Exception): 18 class RouteNotFoundError(Exception):
19 pass 19 pass
20 20
21 21
22 class InvalidRouteError(Exception): 22 class InvalidRouteError(Exception):
23 pass
24
25
26 class InvalidRouteParameterError(Exception):
23 pass 27 pass
24 28
25 29
26 class RouteParameter(object): 30 class RouteParameter(object):
27 TYPE_STRING = 0 31 TYPE_STRING = 0
109 113
110 def getParameter(self, name): 114 def getParameter(self, name):
111 for p in self.supported_params: 115 for p in self.supported_params:
112 if p.param_name == name: 116 if p.param_name == name:
113 return p 117 return p
114 raise Exception("No such supported route parameter '%s' in: %s" % 118 raise InvalidRouteParameterError(
115 (name, self.uri_pattern)) 119 "No such supported route parameter '%s' in: %s" %
120 (name, self.uri_pattern))
116 121
117 def getParameterType(self, name): 122 def getParameterType(self, name):
118 return self.getParameter(name).param_type 123 return self.getParameter(name).param_type
119 124
120 def matchesParameters(self, route_params): 125 def matchesParameters(self, route_params):
198 if not ext: 203 if not ext:
199 ext = '.html' 204 ext = '.html'
200 if suffix: 205 if suffix:
201 uri = base_uri + suffix + ext 206 uri = base_uri + suffix + ext
202 else: 207 else:
203 uri = base_uri + ext 208 # If we just have the extension to add to the URL, we
209 # strip any trailing slash to prevent, say, the index
210 # page of a source from generating an URL like
211 # `subdir/.html`. Instead, it does `subdir.html`.
212 uri = base_uri.rstrip('/') + ext
204 213
205 uri = self.uri_root + urllib.parse.quote(uri) 214 uri = self.uri_root + urllib.parse.quote(uri)
206 215
207 if self.show_debug_info: 216 if self.show_debug_info:
208 uri += '?!debug' 217 uri += '?!debug'
253 if param_type == RouteParameter.TYPE_INT4: 262 if param_type == RouteParameter.TYPE_INT4:
254 return '%%(%s)04d' % name 263 return '%%(%s)04d' % name
255 elif param_type == RouteParameter.TYPE_INT2: 264 elif param_type == RouteParameter.TYPE_INT2:
256 return '%%(%s)02d' % name 265 return '%%(%s)02d' % name
257 return '%%(%s)s' % name 266 return '%%(%s)s' % name
258 except: 267 except InvalidRouteParameterError:
259 known = [p.name for p in self.supported_params] 268 known = [p.name for p in self.supported_params]
260 raise Exception("Unknown route parameter '%s' for route '%s'. " 269 raise Exception("Unknown route parameter '%s' for route '%s'. "
261 "Must be one of: %s'" % 270 "Must be one of: %s'" %
262 (name, self.uri_pattern, known)) 271 (name, self.uri_pattern, known))
263 272
280 return r'(?P<%s>[^/\?]+)' % name 289 return r'(?P<%s>[^/\?]+)' % name
281 290
282 def _coerceRouteParameter(self, name, val): 291 def _coerceRouteParameter(self, name, val):
283 try: 292 try:
284 param_type = self.getParameterType(name) 293 param_type = self.getParameterType(name)
285 except: 294 except InvalidRouteParameterError:
286 # Unknown parameter... just leave it. 295 # Unknown parameter... just leave it.
287 return val 296 return val
288 297
289 if param_type in [RouteParameter.TYPE_INT2, RouteParameter.TYPE_INT4]: 298 if param_type in [RouteParameter.TYPE_INT2, RouteParameter.TYPE_INT4]:
290 try: 299 try: