A SportPage application is a collection of topics, each consisting of a collection of subtopics. A primary requirement of SportPage is that these topics be queried by human beings using as close to a natural query language as is possible within the web. To do this, SportPage combines two architecture ideas: A human-oriented query vocabulary and Representational State Transfer (REST). The latter could be simply put as “To the reader, everything is a document” and manifests as doing everything over plain ordinary HTTP, and the former involves an avoidance of GET-style appendages (for example, “?x=0xDE&y=2”) and extraneous technology artifacts such as file-type identification suffices (for example .html, also known as the ubiquitous “dawt aych tee emm el”).
SportPage URI paths are intended to be easy to say in a natural and unambiguous way while avoiding file-type identification suffices and extraneous characters. For example, the human visitor is interested in “olympics, sports, luge, history” and when the translation from that phrase to the URL is explained once, the visitor has a pretty good chance of guessing the URL to “olympics, sports, hockey, essentials”.
A design philosophy of SportPage is to let people do what people do best and let machines do what machines do best. Machines are very good at looking up things, people are not very good at remembering details that are out of context with the subject matter. A further design philosophy is to “humanize” our information systems; only developers care if a page is sourced from HTML, XML or dynamically generated. All people care about is getting at the content, in this case, information about sporting events.
This human interface engineering is accomplished through the default.extensions list (specified in the configuration file) and a rule that the index of a page is called either index or home. Given a list of extensions of .html,.xml, a URL like http://poseidon/olympics/sports/bobsleigh (with or without the trailing slash) will try the following sequence looking for a valid page file
/olympics/sports/bobsleigh/index.html
/olympics/sports/bobsleigh/bobsleigh.html
/olympics/sports/bobsleigh/index
/olympics/sports/bobsleigh.html
give up and insert the 404 page-not-found exception which the template can reference as $exception.
The reason for the second rule is because that was what the CBC designers preferred. The reason for the fourth is because some Apache installations will usurp /olympics/index.html even though it may allow /olympics/sports/index.html... go figure, but I expect this is because of limited pattern matching inside mod_jserv. The work around is for the root index HTML-pagelet to be named index
A SportPage URI path defines a context and may also define qualifying information about that context. In the most basic case, /sports/hockey would define a final context topic (hockey) with its own menu, layout, news headlines &c, while /sports/hockey/news/story/brandon23 could resolve to a context of hockey.news, thereby setting the main content area template to a news-story formatting template, and passing the extra information as the unique identifier to retrieve the specific news item from the database or from a file.
Sportwire decides on the context in two ways, by actions of the page handler, and by context dependent dot-variables.
In the first method, the original URI string is scanned from the end to the beginning looking for a path component that describes a PageHandler (described later); if a handler is found, the class is instanced and may alter the context-building process, for example, to take the remainder of the path as a default document or as database key information. This variation in the action taken on the extra path info can only be manipulated by creating page-handler classes.
Example 1. Deciding the SportPage Page-Handler
A request URI is scanned from the end to the beginning looking for a matching Java page-handler class:
http://cbc.ca/olympics/bio/snowboarding/deadhead/jim.bo
this url gets scanned for DeadheadPageHandler, then SnowboardingPageHandler and finally settles on BioPageHandler. This PageHandler is dynamically loaded and given the current page context (a Map of $varname=object pairs) which the handler can freely modify before the page starts to render.
The most common use of special page handlers is to restructure the page layout by changing the context variables specifying the sidebars, pages or any other context variables.
The page handler may also add other variables, for example, a BioPageHandler might take the $path as an XML document and pre-loads it as a globally accessible JDOM object that the /bio page templates can share.
The following code sample shows how a global $dom variable bound to a shared JDOMFile object might be used in a template:
#set ($root = $dom.rootElement) #set ($sp = $root.getChild("sport")) #set ($sport = $sp.getAttribute("name").value) #set ($athlete = $sp.getChild("athlete")) #set ($ch = $athlete.getChild("career_highlights")) #set ($chs= $ch.getChildren("point")) #foreach ($point in $chs) #show($point) #end
In practice, however, this method is not as useful as it seems and it locks the types of content to specific topic areas. A more flexible method is to define dot-variable beans, which can be specified globally or per-topic, and then use these beans to access documents by passing in the $path pathinfo. The above example would be modified only slightly, by inserting the following code at the top:
#set ($dom = $xml.dom( $path ))
The javabean dot-variables *.bean lets you map any java beans to variables; in this case, $xml has been bound to the DOMFileFactory which provide the means to fetch documents from the $path. If the javabean uses data caching and/or is a singleton (or stashes itself in the application properties), there is very little overhead in using this method.
Overwriting dot-variables happens when the page handler is loaded, starting from the left-end of the URI, adding each path element one at a time as it scans the configuration file for variables beginning with that same string. For example, given the URI /olympics/sports/hockey/history the page handler will assign all default.* values to variables of the same base name (default.lineup.category becomes $lineup.category in the velocity template), then repeat the process for the first level (so sports.lineup.category overwrites the value of $lineup.category), then adding the second (sports.hockey.lineup.category) and so forth. Sportpage also allows any subtopic to introduce new variables unknown in sibling or parent topic templates.