summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBen Bangert <ben@groovie.org>2008-06-05 17:04:55 -0700
committerBen Bangert <ben@groovie.org>2008-06-05 17:04:55 -0700
commit789f75fb03f85a8aea7c68ec07d00097493f404d (patch)
tree0247a2a99d55b147f7e856a29d7db8f2437848b1
parent7201c92dcef5d806615b1c533e0adf2ed5b5f32f (diff)
downloadroutes-789f75fb03f85a8aea7c68ec07d00097493f404d.tar.gz
* Add non-minimization option to Routes and the Mapper for generation and
recognition. --HG-- branch : trunk
-rw-r--r--CHANGELOG2
-rw-r--r--routes/base.py106
2 files changed, 85 insertions, 23 deletions
diff --git a/CHANGELOG b/CHANGELOG
index bc2987d..f229b1e 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -2,6 +2,8 @@ Routes Changelog
========================
-- 1.9 (**tip**)
+* Add non-minimization option to Routes and the Mapper for generation and
+ recognition.
* Add Routes 2.0 style syntax for making routes and regexp. For example, this
route will now work: '{controller}/{action}/{id}'.
* Fixed Routes to not use quote_plus when making URL's.
diff --git a/routes/base.py b/routes/base.py
index a2e512a..b75d73c 100644
--- a/routes/base.py
+++ b/routes/base.py
@@ -90,6 +90,9 @@ class Route(object):
routekeys = frozenset([key['name'] for key in routelist \
if isinstance(key, dict)])
+ if not self.minimization:
+ self.make_full_route()
+
# Build a req list with all the regexp requirements for our args
self.req_regs = {}
for key, val in self.reqs.iteritems():
@@ -110,6 +113,17 @@ class Route(object):
self.hardcoded = frozenset([key for key in self.maxkeys \
if key not in routekeys and self.defaults[key] is not None])
+ def make_full_route(self):
+ """Make a full routelist string for use with non-minimized
+ generation"""
+ regpath = ''
+ for part in self.routelist:
+ if isinstance(part, dict):
+ regpath += '%(' + part['name'] + ')s'
+ else:
+ regpath += part
+ self.regpath = regpath
+
def make_unicode(self, s):
"""Transform the given argument into a unicode string."""
if isinstance(s, unicode):
@@ -181,6 +195,15 @@ class Route(object):
"""
minkeys = []
backcheck = routelist[:]
+
+ # If we don't honor minimization, we need all the keys in the
+ # route path
+ if not self.minimization:
+ for part in backcheck:
+ if isinstance(part, dict):
+ minkeys.append(part['name'])
+ return (frozenset(minkeys), backcheck)
+
gaps = False
backcheck.reverse()
for part in backcheck:
@@ -492,29 +515,33 @@ class Route(object):
return result
- def generate(self, _ignore_req_list=False, _append_slash=False, **kargs):
- """Generate a URL from ourself given a set of keyword arguments
-
- Toss an exception if this
- set of keywords would cause a gap in the url.
-
- """
- # Verify that our args pass any regexp requirements
- if not _ignore_req_list:
- for key in self.reqs.keys():
- val = kargs.get(key)
- if val and not self.req_regs[key].match(self.make_unicode(val)):
- return False
-
- # Verify that if we have a method arg, its in the method accept list.
- # Also, method will be changed to _method for route generation
- meth = kargs.get('method')
- if meth:
- if self.conditions and 'method' in self.conditions \
- and meth.upper() not in self.conditions['method']:
- return False
- kargs.pop('method')
-
+ def generate_non_minimized(self, kargs):
+ """Generate a non-minimal version of the URL"""
+ url = ''
+ all_args = self.defaults.copy()
+ for part in self.routelist:
+ if isinstance(part, dict):
+ arg = part['name']
+
+ # For efficiency, check these just once
+ has_arg = arg in kargs
+ has_default = arg in self.defaults
+
+ # Ensure that our dict is updated if its not None and
+ if has_arg and kargs[arg] is not None:
+ all_args[arg] = kargs[arg]
+
+ # Otherwise, we weren't passed the arg, but we can't use
+ # None when making the URL, so remove it from the dict
+ elif has_default and all_args[arg] is None:
+ del all_args[arg]
+ if bool(self.minkeys - frozenset(all_args.keys())):
+ return False
+ else:
+ return self.regpath % all_args
+
+ def generate_minimized(self, kargs):
+ """Generate a minimized version of the URL"""
routelist = self.routebackwards
urllist = []
gaps = False
@@ -578,6 +605,39 @@ class Route(object):
urllist.append(part)
urllist.reverse()
url = ''.join(urllist)
+ return url
+
+ def generate(self, _ignore_req_list=False, _append_slash=False, **kargs):
+ """Generate a URL from ourself given a set of keyword arguments
+
+ Toss an exception if this
+ set of keywords would cause a gap in the url.
+
+ """
+ # Verify that our args pass any regexp requirements
+ if not _ignore_req_list:
+ for key in self.reqs.keys():
+ val = kargs.get(key)
+ if val and not self.req_regs[key].match(self.make_unicode(val)):
+ return False
+
+ # Verify that if we have a method arg, its in the method accept list.
+ # Also, method will be changed to _method for route generation
+ meth = kargs.get('method')
+ if meth:
+ if self.conditions and 'method' in self.conditions \
+ and meth.upper() not in self.conditions['method']:
+ return False
+ kargs.pop('method')
+
+ if self.minimization:
+ url = self.generate_minimized(kargs)
+ else:
+ url = self.generate_non_minimized(kargs)
+
+ if url is False:
+ return url
+
if not url.startswith('/'):
url = '/' + url
extras = frozenset(kargs.keys()) - self.maxkeys