I've made some good progress on the OokOok project over the last week. The system has a minimal page management interface now, so you can create, edit, and delete new pages and place them in the project's sitemap. You can create project editions that freeze the content in time, and you can see the different versions of a page using time-based URLs.
You know you have a real software project when you have a list of things that won't be in the current version. So it is with OokOok. Eventually, I want to support any dynamic web-based digital humanities project and allow it to run forever without any project-specific maintenance. For now, I'll be happy creating a simple text content management system that has all the time-oriented features. We can add support for algorithms later.
Today, I want to talk a bit about the model I'm using to keep track of the different versions and the impact this has on the user interface.
The fundamental idea for the project is that if you look at a page today, it will look the same in a hundred years, even if the technology delivering the content has changed. If you cite it, the person following your citation will see the same content that you did. You don't have to worry about your argument getting undercut because someone updated their page with new results that no longer support the point you were trying to make. Whoever follows your citation should see what you saw as well as find any changes made afterwards.
In the diagram, time flows from the top, down. Each vertical line is the history of a page, labeled Foo, Bar, and Baz. Each horizontal line is when an edition was cut, labeled A, B, and C. The diagram shows that Edition A had pages Foo and Baz, but not Bar. Edition B had a new version of page Foo and the first version of page Bar. Edition C kept the Foo and Bar pages from Edition B and added a new version of page Baz.
There are three different ways to find the right page version depending on what you are wanting to do: develop the project, see the most recent published version, or see a particular edition's version.
If you are working on creating an edition, then you will start at the bottom of the diagram and run your finger up the line representing a page until you run into a rectangle representing the most recent version of the page. If you make changes, a new rectangle will be created below the most recent Edition, in what I'm calling the "working edition."
If you are wanting the current, most recently published version, then you start at the most recent version. If a page has a version there, then use it. Otherwise, run your finger up the line until you find a rectangle representing a version, just as you would in development (except that you start with a published version instead of the most recent).
If you want a page as it was in a past edition, then you start with the horizontal line of that past edition and do as you would otherwise with the most recently published edition.
So projects have project editions, and project editions have pages. Pages are considered read-only once their associated project edition is published, but we don't make another page object until we try to change the page (copy-on-write semantics).
This pattern plays itself out in other areas of the system. I'm working now on adding themes. A project shouldn't worry about writing a lot of CSS and munging HTML to get it to look just right. That's not maintainable. Instead, the system will offer a set of themes (and people can create new themes) that can translate to the display technology current when someone looks at the project content.
The problem is that we don't want the theme changing on us once we've started building a project with it, so now, the system is set up to record which version of the theme you are using for a particular edition. Even if the theme gets updated, you'll still use the version that you selected when you published your edition (and the version you selected will always work). You can always move to a new version of a theme by cutting a new edition of the project.
Since I'm having to manage themes the same way I'm managing projects, I've abstracted the relationships between the "thing," "thing edition," and "thing content object" into a set of Moose roles. This is the Perl equivalent of mixins, interfaces, or not-quite-classes-but-inherited-anyway things from other languages. The "thing" has editions, the "thing content object" has versions, and the "thing edition" is an edition.
Why the tripartite division? The "thing" is what we want to talk about looking in from outside the system, but it has different versions itself, captured by the "thing edition" object. For example, a project has a name and a description, but those are properties of the edition since they can change from edition to edition as the project's goals are refined. The different "thing editions" are tied to the "thing" object for aggregation. Likewise, the "thing content objects" are tied to a "thing edition" for aggregation.
One of the consequences of versioning pages is that they don't own their URL. URLs are a property of the edition. Not all URLs have pages associated with them. Some are containers for sets of pages. As a result, pages can skip an edition if you don't have them listed in the sitemap somewhere. The interface tries to hide a lot of this, and new editions copy the sitemap from the earlier edition, so you only have to worry about changes instead of recreating the entire sitemap for each edition.
Here are some screenshots of different dialogs and parts of the system as they are at the moment. Of course, the UI is subject to change much more than the backend data model. I hope to have some screenshots in a couple of weeks (I'll be at DHSI next week) showing pages run through the layout/theme rendering.