| | 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 | """ |
|---|