# HG changeset patch # User paulb # Date 1124711351 0 # Node ID 547a5f145818aadb4ca9ca374b94e03dbba8a8b4 # Parent 160859a75f44c49a3bdff9966434c2a1fa0c873d [project @ 2005-08-22 11:49:09 by paulb] Added "pass through" support to MapResource. diff -r 160859a75f44 -r 547a5f145818 README.txt --- a/README.txt Fri Aug 19 20:20:58 2005 +0000 +++ b/README.txt Mon Aug 22 11:49:11 2005 +0000 @@ -62,8 +62,9 @@ session store, avoiding deadlocks. Fixed the calendar example, making it perform a proper function. Added the notion of processed virtual path info - the part of the original -path info not represented in the current virtual path info (prompted by a -different suggestion from Scott Robinson). +path info not represented in the current virtual path info. +Added "pass through" behaviour to ResourceMap.MapResource (prompted by a patch +from Scott Robinson). Changed the ResourceMap.MapResource class to provide the empty string as the resource name where the virtual path info is only one component in length. Added a convenience method to Transaction for the decoding of path values and diff -r 160859a75f44 -r 547a5f145818 WebStack/Resources/ResourceMap.py --- a/WebStack/Resources/ResourceMap.py Fri Aug 19 20:20:58 2005 +0000 +++ b/WebStack/Resources/ResourceMap.py Mon Aug 22 11:49:11 2005 +0000 @@ -26,14 +26,48 @@ "A resource mapping names to other resources." - def __init__(self, mapping, directory_redirects=1): + def __init__(self, mapping, pass_through=0, directory_redirects=1): """ Initialise the resource with a 'mapping' of names to resources. The 'mapping' should be a dictionary-like object employing simple names - without "/" characters; the special value None is used where no name - corresponds to that used in the request path and may be used to map to - a "catch all" resource. + without "/" characters; the special value None is used to specify a + "catch all" resource which receives all requests whose virtual path + info does not match any of the names in the mapping. For example: + + mapping is {"mammals" : ..., "reptiles" : ..., None : ...} + + /mammals/cat -> matches "mammals" + /reptiles/python -> matches "reptiles" + /creatures/goblin -> no match, handled by None + + When this resource matches a name in the virtual path info to one of the + names in the mapping, it removes the section of the virtual path info + corresponding to that name before dispatching to the corresponding + resource. For example: + + /mammals/dog -> match with "mammals" in mapping -> /dog + + By default, where the first part of the virtual path info does not + correspond to any of the names in the mapping, the first piece of the + virtual path info is removed before dispatching to the "catch all" + resource. For example: + + /creatures/unicorn -> no match -> /unicorn + + However, the optional 'pass_through' parameter, if set to a true value + (which is not the default setting), changes the above behaviour in cases + where no matching name is found: in such cases, no part of the virtual + path info is removed, and the request is dispatched to the "catch all" + resource unchanged. For example: + + /creatures/unicorn -> no match -> /creatures/unicorn + + With 'pass_through' set to a true value, care must be taken if this + resource is set as its own "catch all" resource. For example: + + map_resource = MapResource(...) + map_resource.mapping[None] = map_resource The optional 'directory_redirects' parameter, if set to a true value (as is the default setting), causes a redirect adding a trailing "/" @@ -41,6 +75,7 @@ """ self.mapping = mapping + self.pass_through = pass_through self.directory_redirects = directory_redirects def respond(self, trans): @@ -74,15 +109,23 @@ resource = self.mapping.get(name) if resource is None: resource = self.mapping.get(None) + catch_all_resource = 1 + else: + catch_all_resource = 0 # If a resource was found, change the transaction's path info. # eg. "/this/next" -> "/next" # eg. "/this/" -> "/" # eg. "/this" -> "" + # Such changes are not made if the resource is in "pass through" mode + # and where the "catch all" resource is being used. In such situations + # this resource just passes control to the "catch all" resource along + # with all the path information intact. - new_path = parts[0:1] + parts[2:] - new_path_info = "/".join(new_path) - trans.set_virtual_path_info(new_path_info) + if not (catch_all_resource and self.pass_through): + new_path = parts[0:1] + parts[2:] + new_path_info = "/".join(new_path) + trans.set_virtual_path_info(new_path_info) # Invoke the transaction, transferring control completely.