Site Nodes Proposal (Draft)
State of This Document
This proposal should be considered a rough draft as it has not yet been reviewed by any core team members. The response::* api has been renamed and moved to a separate proposal (templatehead).
Goals of this proposal, ie. why change site nodes?
I believe the changes in this proposal would:
- Allow more flexible use of the url space to facilitate a site wide approach to CMS type applications.
- Allow better and simpler integration for applications with a data driven url space (eg. wiki, form builder).
- Support better models of code reuse within OpenACS.
- Help relieve the burden on the overloaded concept of a subsite.
Suggested Changes
Abstractly, the changes I'm suggesting are:
- Allow site nodes to have multiple root nodes. Site nodes are currently constrained to be a single tree. Clearly the main site tree would need to be easily identifiable. This would allow applications to re-use the existing site_nodes datamodel to represent their own data driven url spaces. This would also allow different hostnames to correspond to different root nodes.
- Allow any object type to be mounted at a site node (the site nodes datamodel already allows any object type to be mounted but beyond a certain point the request processor assumes the mounted object is a package). Or put another way, the principal purpose of a site node would be to select a function to handle the request rather than a package object. The current control flow for handling packages would become a function invoked in this way.
- Allow parameters to be associated with site nodes. This would allow concept such as the DefaultMaster to be moved out of acs-subsite as well as allowing generic action code to be parameterised in a specific location.
- Already Implemented: Lazy Caching of site nodes. Site nodes are lazy cached, meaning they are loaded from the database once they are called / accessed for the first time instead of during startup. This considerably brings down the time needed for starting dotLRN.
I have implemented the above ideas in a copy of the site_nodes datamodel called 'locations'. Together with dynamic types I've used locations to create dynamic wizards and a data driven form builder which could be considered proofs of the concept.
Implementation Detail
Multiple Root Nodes
This can be achieved by treating site_nodes at depth 1 as root nodes; ie. the children of the current singleton root node would be root nodes in their own right.
The overall root site node is created during the kernel datamodel installation. The URL space for the main site, as we know it currently, would be created as a child of this root node with its root (at depth 1) being assigned an acs_magic_object. I propose the magic object be called 'default_site_root'. The root of the site nodes tree would therefore look something like this:
Despite the lack of a specific 'node_id' or 'url' option in some cases, the site_nodes::* api is designed to allow you to identify a site node by either its url or node_id. I would propose that functions which currently accept a node_id would carry out their function on the specified node regardless of which tree the node belongs to. Functions which accept a url parameter to identify the site_node would be given an optional 'root_id' switch which defaults to the 'default_site_root' magic object. The 'root_id' switch would allow you to look up a node by url in a different tree.
By default all hostnames are considered mapped to the 'default_site_root' node. In this proposal the host_node_map could be used to assign hostnames to alternate root nodes. Although I don't think their is enough support in the toolkit as a whole for templates/packages/objects which appear simultaneously at different paths below a hostname, this aspect of the host_node_map would continue to function as before.
Method Mapped URLs
Many MVC frameworks incorporate the idea of mapping handler functions (or controllers if you like) to urls - this much is pretty well understood. Exactly how a particular method should be selected for given URL may be a matter for debate. For example, some members of the core team have discussed with me the idea that the selection should be based in part on the data type of the object mounted on a site node. Personally, I would go for the simplest option: store the name of the function to call in the site node. I'll leave this part to be defined after there has been more discussion.
Site Node Parameters
These would be implemented using a fairly standard skinny tables approach similar to package parameters.
Impact On Existing Code
Currently I believe the code that would be affected by these changes amounts to:
- Site nodes api and caching code: would need to be updated to understand multiple root nodes. A small number of changes are required to remove assumptions of apm_packages.
- Site map admin pages: would need to be updated to understand that objects other than packages may be mounted.
- Any code which assumes only apm_packages are mounted on site nodes.