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