Content Management Reusable Components
The story of the web is really the story of a search for a solution to the problem of content management. In the very early days, we didn't even know that this problem existed, never mind that it had a solution. Then we went from static sites to dynamic sites, but took the wrong emphasis - on cgi and perl and then later on JavaScript. All of these were solutions to a different problem.
Eventually, news sites emerged, and content management solutions began to spring up. It started out that we kept on doing the same things over and over when creating new sites, and only much later did we recognise that there was a common thread to each of these sites. Deciding on a name came much, much later.
But now we know that content management was the big problem of the web; far more than the (easy) shopping cart problem. And that, then, was the nineties.
What is Content Management?
When running a news site, it quickly becomes apparent that control of content has to be kept separate from control of display. Yes, this is a circle back to the first concepts of hypertext and the very first web - and this is a very good thing to discover.
Content editors typically are not web or graphic designers, and they need to reuse a common template layout thousands of times over every single day. A change to the layout, however, should propagate to change all appropriate pages on the site. Even the site structure may need to be flexible; high level content indexes should change to reflect new stories being added, even new sections with their own design templates should be added to the site dynamically.
A new story will go through several stages, and may need control and monitoring as it goes through these stages; in the simplest form, a story should not appear on the site until it has been approved for publication. Similarly, stories are likely to have specific dates and times on which they can be 'released' for publication, and at which they should expire.
In more complex forms, different versions of a story may be being worked on at the same time, for phased release.
In the end, a content managed site will be run from a database, with a publication application to present the site for general users, and a separate application for editing and publishing stories.
A full scale content management system may well have to be integrated with a web site that does many other things, and the content side may be just a small part of the site. Any site that isn't entirely static can benefit from this.
Background
The Content framework was developed over the course of creating several sites, all of which had a primary purpose that was other than content management. Developers were putting text onto web pages that had to be regularly edited - although this was never obvious at first. Pages like terms and conditions, delivery information, etc, all have to be revised on a frequent basis; even navigation frames are updated relatively frequently. Rather than having to go through a complex and expensive publication cycle of change the software driving the site, a simple content management system was required.
The system consists of a framework and an editing application. It provides the facility for a programmer to include an item of content on any page, that is the responsibility of the application users to manage. It also provides a new html tag that provides a link to a page showing an item of content, or a list of content items. This permits mini-sites to be created solely in the editing application, which has uses for help systems or FAQs.
The Content framework
Contains the several components used by the system, the eomodel describing the one table used to store all content, and a direct action class responsible for handling links generated by the custom tag, plus a tag parser to convert the custom tags into direct actions.
As far as a programmer using this system is concerned, they should know about the Content wocomponent, and the custom tag.
Content component
Use WebObjects Builder to enter a custom WebObjects component, with the class name "Content", wherever the custom content is required on a page. It can work without any bindings at all, or can take bindings for name (String), index (Integer), and image (boolean). Name is used to match the name of a content item from the database, and will default to the component name of the page on which it is placed - for example, "Main". If more than one item matches that name and is eligible for publication (by using the start and end dates and published flag) it will choose the one with the most recent start date. Index choose one other than the first, in order of start date, and is particularly useful for building navigation lists of links. If the image flag is set, it will display the image entered into the image url field of the content. This was found to be useful in practice and was requested by users, who often want to associate an image either as a header or an illustration for a piece of text.
PLLINK tag
There are four different attributes that can be used separately, each of which makes the tag act very differently. These are:
- page. This generates the page named using pageWithName().
- action. Calls the direct action named (and isn't strictly necessary, as this form of link can be generated manually).
- content. Is rather more complex, as it takes a number of additional option attributed. In its simples form, it will create a page with the value of the attribute as its named content. This can be accompanied by index, which acts the same as the the Conent WOComponent binding. wrapper uses the named component as a wrapper for the generated page, and nav uses the named content as a left side navigation component.
- contentList. Generates a page with all of the matching named content as a list, with links to their pages. It doesn't allow, at the moment, control over whether the pages generated are list pages or simple content pages. It also takes nav and wrapper attributes.
ContentEditor
This allows you to create new, delete and edit content items. The name field is used to match Content components and pages. Title is used for the links generated in contentList pages. Start Date, End Date are used to specify the earliest date that the item can appear, and the date after which it will stop appearing. Publish flag allows the item to appear (or not). Created and modified dates are set when the item is created and last modified, respectively; creator and modifier are not set - to be made use of, a user login system would be required.
Body and image url are used to determine the content shown. There is an additional set accessor in the system which is not used: plainText. This allows a user to enter plain text input, and will filter single carriage returns to <br> tags, and double carriage returns to <p> tags. As it stands, body will allow any html to be entered. The application could readily be customised to give a preview of the body content and image.
The final remaining field is category. This exists entirely for the convenience of the ContentEditor user, and was added as the result of user requests. Anything entered in this field will be used to build the category popup, and should allow pages of the application to be reduced to manageable size, even in a reasonably large system.
Notes:
OpenBaseLite, as supplied for free with WebObjects, only supports a maximum of 1024 characters in a object field used to store strings. This will be exceeded by almost any sample application. The solution is to upgrade to a full version of OpenBase.
Download the source code described in this article.