Download Install Tutorial Docs FAQ Tools WikiLicense Team IRC Planet Involvement Shop Book

Changeset 2057

Show
Ignore:
Timestamp:
10/30/08 18:09:55
Author:
lakin
Message:

#869 - rename getsubnode to dispatch and pass vpath instead of just objectname

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/dynamicnodedispatch-869/cherrypy/_cpdispatch.py

    r2053 r2057  
    194194            request.handler = cherrypy.NotFound() 
    195195     
    196     _getobject = getattr 
    197     _getobject__doc = """ 
    198         Template method for resolving the objname given a node. 
    199     """ 
    200  
    201196    def find_handler(self, path): 
    202197        """Return the appropriate page handler, plus any virtual path. 
     
    221216        app = request.app 
    222217        root = app.root 
    223         _getobject = self._getobject 
    224218         
    225219        # Get config for the root object/path. 
     
    234228        node = root 
    235229        names = [x for x in path.strip('/').split('/') if x] + ['index'] 
    236         for name in names: 
     230        iternames = names[:] 
     231        while iternames: 
     232            name = iternames[0] 
    237233            # map to legal Python identifiers (replace '.' with '_') 
    238234            objname = name.replace('.', '_') 
    239235             
    240236            nodeconf = {} 
    241             node = _getobject(node, objname, None) 
     237            subnode = getattr(node, objname, None) 
     238            if subnode is None: 
     239                dispatch = getattr(node, 'dispatch', None) 
     240                if dispatch and callable(dispatch): 
     241                    subnode = dispatch(vpath=iternames) 
     242            name = iternames.pop(0) 
     243            node = subnode 
     244 
    242245            if node is not None: 
    243246                # Get _cp_config attached to this node. 
     
    521524    return vhost_dispatch 
    522525 
    523  
    524 class _DynamicNodeMixin(Dispatcher): 
    525     """CherryPy Dispatcher Mixin which makes the tree walking dynamic. 
    526  
    527     Adds in the ability for a controller to define a special method: 
    528     'getsubnode'. This method will be called when a portion of the path 
    529     is not found as an attribute of the current tree node. The method 
    530     is responsible for returning either None to indicate this path 
    531     does not exist or a reference to a new node from which the dispatcher 
    532     can continue walking the tree. 
    533  
    534     """ 
    535     def _getobject(self, node, objname, default=None): 
    536         """ 
    537         Template method for resolving the objname given a node. 
    538         """ 
    539         subnode = getattr(node, objname, default) 
    540         if subnode is None: 
    541             getsubnode = getattr(node, 'getsubnode', None) 
    542             if getsubnode and callable(getsubnode): 
    543                 subnode = getsubnode(objname) 
    544         return subnode 
    545  
    546 class DynamicNodeDispatcher(_DynamicNodeMixin, Dispatcher): 
    547     """CP Dispatcher which walks a dynamic tree of objects to find a handler. 
    548      
    549     The tree is rooted at cherrypy.request.app.root, and each hierarchical 
    550     component in the path_info argument is matched to a corresponding nested 
    551     attribute of the root object. Matching handlers must have an 'exposed' 
    552     attribute which evaluates to True. The special method name 'getsubnode' 
    553     allows the handler to dynamically specify the sub-tree of handlers based 
    554     on the remaining components in the path_info. 
    555  
    556     A special attribute named 'getsubnode' allows components of the path to 
    557     be dynamic before the end of the URI. For example, the URL 
    558     "/path/to/resource/<id>/attribute" might return 
    559     root.path.to.handler.getsubnode(<id>).attribute. 
    560     """ 
    561  
    562  
    563 class DynamicNodeAndMethodDispatcher(_DynamicNodeMixin, MethodDispatcher): 
    564     """CP Dispatcher which walks a dynamic tree of objects to find a handler. 
    565      
    566     The tree is rooted at cherrypy.request.app.root, and each hierarchical 
    567     component in the path_info argument is matched to a corresponding nested 
    568     attribute of the root object. Matching handlers must have an 'exposed' 
    569     attribute which evaluates to True. The special method name 'getsubnode' 
    570     allows the handler to dynamically specify the sub-tree of handlers based 
    571     on the remaining components in the path_info. 
    572  
    573     A special attribute named 'getsubnode' allows components of the path to 
    574     be dynamic before the end of the URI. For example, the URL 
    575     "/path/to/resource/<id>/attribute" might return 
    576     root.path.to.handler.getsubnode(<id>).attribute. 
    577  
    578     The leaf nodes of this dispatcher are invoked in the same way as the 
    579     MethodDispatcher. 
    580     """ 
  • branches/dynamicnodedispatch-869/cherrypy/test/test_dynamicobjectmapping.py

    r2054 r2057  
    4040        handler.exposed = True 
    4141 
    42         def getsubnode(self, objname): 
    43             return subsubnodes.get(objname, None) 
     42        def dispatch(self, vpath): 
     43            return subsubnodes.get(vpath[0], None) 
    4444 
    4545    subnodes = { 
     
    6060        handler.exposed = True 
    6161 
    62         def getsubnode(self, objname): 
    63             return subnodes.get(objname
     62        def dispatch(self, vpath): 
     63            return subnodes.get(vpath[0]
    6464 
    6565    #-------------------------------------------------------------------------- 
     
    9797            return unicode(sorted(user_lookup.keys())) 
    9898 
    99         def getsubnode(self, objname): 
     99        def dispatch(self, vpath): 
    100100            try: 
    101                 id = int(objname
     101                id = int(vpath[0]
    102102            except ValueError: 
    103103                return None 
     
    152152    Root.users = UserContainerNode() 
    153153 
    154     d = cherrypy.dispatch.DynamicNodeDispatcher() 
    155     md = cherrypy.dispatch.DynamicNodeAndMethodDispatcher() 
     154    md = cherrypy.dispatch.MethodDispatcher() 
    156155    for url in script_names: 
    157156        conf = {'/': { 
    158                     'request.dispatch': d, 
    159157                    'user': (url or "/").split("/")[-2] 
    160158                }, 

Hosted by WebFaction

Log in as guest/cpguest to create tickets