The current implementation of MojoMojo allows for an arbitrarily deep page hierarchy.
I propose that we move to a single-level hierarchy.
The code as it currently exists is greatly complicated by support for hierarchies of an arbitrary depth. For an example, look at how permissions checking is done, or the code to calculate a page's path in
This also greatly complicates the user interface and the conceptual interface to the wiki. It's more stuff for users to understand, and it pokes it's head out all over the place. For example, we can look at recent changes for the entire wiki (/.recent) or for a sub-section of the wiki, at any depth.
Moving to a single-level hierarchy will preserve the useful parts of the existing design, simplify our codebase, and allow for great improvements to the UI.
Why have any hierarchy at all?
- A hierarchy can be a natural way to group together sets of related pages. For example, in this particular wiki, development information is located under Development.
- As a corrolary, having a hierarchy allows for the generation of nice breadcrumbs.
- A hierarchy allows for a natural partitioning of pages into ACL-controlled subsets of the whole.
- Secondarily, the ACL system allows for partitioning of users into subsets of the whole.
What are the problems with a multi-level hierarchy?
- Code complication. Instead of storing a single "group id" for a page, we need to store its place in a hierarchy of arbitrary depth. The code for this is much more complicated.
- As a corrolary, we constantly need to handle multi-level paths, of which any given member may or may not exist. This also leads to great complication in the code.
- Our ACL system is hard to implement and hard to understand, both for users and developers.
- Linking in a hierarchy is confusing. As an example, the Development page, until recently, had several links of the form [[Development/Foo Bar]]. This is wrong, as the link should either be [[/Development/Foo Bar]] (note the leading slash) or just [[Foo Bar]]. If even the MojoMojo developers make this mistake, imagine how non-geeks handle this.
- Even worse, if we ever implement page renaming/moving, then moving a page up or down in the hierarchy will cause all relative links of the form [[Foo]] to break!
- Allowing the slash in page titles/uris requires us to use the leading period uris (/.recent) we all know and don't love so much
Structure of a Single-Level Hierarchy
Instead of encoding the hierarchy in page titles, I propose that this concept be separated into a concept of a "wiki" and "pages". For the purposes of this proposal, MojoMojo should be thought of as a "multiple wiki hosting system", not "a wiki" (singular).
A wiki would contain a set of pages in a flat hierarchy. A wiki would also have ACLs and (possibly) users. Each wiki would have its own totally unrelated ACLs, so that some wikis could be entirely open to the public, and others could be totally private.
The wiki hosting system would maintain the users separately from the wikis, so that a user could use one login to access many wikis.
By default, operations like recent changes, rss feeds, searching, and so on would operate on a single wiki. Users with access to multiple wikis would also have the option to perform operations on an aggregate set of wikis. This would be a relatively simple matter of simply passing the right wiki ids into a database query.
There are a number of advantages to this system:
- First, the code would be hugely simplified. There would be no path calculations, ACLs would be simple flags, etc.
- Determining whether a page exists would also be very simple.
- Linking would be greatly simplified. The default would be to link to pages in the same wiki. We could also support an interwiki link syntax like [[/OtherWiki/Some Page]]. This form of "/Wiki/Page" could be generalized for other operations as well (page arguments given to wiki formatting plugins, for example).
- The presentation of ACLs to users with wiki admin authority would be greatly simplified. There would be no thought about where in the hierarchy to set them from, it would simply be a per-wiki option. It would also not be possible to mistakenly set them in the wrong place, or to create conceptually weird settings like are currently possible.
- We can use proper restful URIs like /wiki/Foo/page/some_random_page and /wiki/Foo/page/some_random_page/edit_form, along with things like /user/1, /wiki/Foo/settings_form, /users (or maybe /system/users), etc.
There are other benefits to introducing this feature:
- Having the concept of separate wikis enables many other features. For example, different wikis could have different themes, and other sitewide options could be moved to a per-wiki setting.
There are also some downsides:
- Some features would require some additional UI. For example, we would want to support copying/moving pages between wikis as well as in a single wiki, which might require additional UI.
Supporting a Fake Multi-Level Hierarchy
This proposal could also be combined with a greatly simplified (aka fake) multi-level hierarchy. We would disallow the / character in page titles (for sanity, and because uri-encoding / as %2F has a tendency to drive webservers crazy), and replace it with something else, possibly a colon.
Internally, the colon would simply be part of the name. However, we could use the presence of a colon in the page title as a way to do things like show breadcrumbs in the UI, so a page named "Development:Discussion:Foo" would generate breadcrumbs like "Development > Discussion > Foo". However, all links would need to be explicit and include the whole (fake) path.
This would allow users to organize pages in a multi-level hierarchy fashion, but impose very little cost in terms of development effort. It is also conceptually very simply, without the baggage of relative vs absolute paths, multi-level ACLs, etc.
Converting an Existing Wiki
This is, of course, the biggest problem in pursuing this path. This would require an explicit conversion tool that allowed users to specify a mapping between the existing hierarchy and one or more wikis to be created.
Any occurence of a path separate that didn't correspond to a wiki mapping would just be replaced by a colon (which would work regardless of whether or not we implement the fake multi-level hierarchy piece).
The biggest question would be how to handle a mapping that still left mutliple sets of ACLs in a given wiki. Presumably, the top-level ACL would be used, and the presence of others would generate a warning.
This is essentially how Socialtext organizes their produce. What I am calling a wiki here they call a "workspace", and they call the product a wiki. This is confusing.
I've intentionally avoided looking at their code while writing this up, because it's under a not-quite-free license. Since I used to work for Socialtext, I'd like to remain as free from potential legal complications as possible. There are no patents on any of these concept, and I'm sure there are other wiki products out there with similar features.
Showing changes from previous revision.