By Peter Bell

URIs in LightBase

So, after a little page stub pondering I've decided to add the concept of URIs to LightBase. By default a unique URI is created for each page you build in the page table (initially using a page stub generator, although you could also implement using URL rewriting and a db or file based lookup table). In addition, every feature has a URI generator so the master URI generator calls the feature specific URI generator for each page to generate any sub links.

Lets look at how this would work, and then how to architect and implement the solution . . .

Imagine you have a very simple site with two pages: home and catalog. The page URI generator would generate two URIs - say home.html and catalog.html. It would then call the URI generator for the feature on each page. Home.html is just a simple HTML pagedisplay, so it wouldn't generate any more URIs. Catalog.html has three categories and a bunch of products, so it'd create a URI for each category and one for each product in a category (one product in two categories would have 2 URIs reflecting the fact that there is meaning from a reporting and SEO perspective in the category through which a product is accessed - an important part of the meaning of a resourse is its context). So if we had outerwear which has subcategories of gloves and coats, we'd now have added catalog/outerwear.html, catalog/outerwear/gloves.html and catalog/outerwear/coats.html. If there were two coats (leather jacket and green duffel) we'd also have catalog/outerwear/coats/leather-jacket.html and catalog/outerwear/coats/green-duffel.html. Of course, all the design decisions about what does or doesn't have multiple URIs and what they are called would be easy to change - this is just a concrete example of the core principle.

What IS a URI
In this specific context, a URI would be a page combined with a set of additional properties to drive a request to a specific set of content. For example, traditionally to get to the glove we might have gone to index.cfm?event=catalog.categoryview&CatID=3&ProdID=12 (or we could have used category and product names - ID is just more common).

So, all we need the URI to tell us is the page to go to, and any URL properties to pre-set (in the case of LightBase, the action if it shouldn't be the default page action, and then any feature specific properties like category ID's or article names or whatever).

What is the best way to implement this? I have no idea! For now, I'm going to try the following as a quick hack to see where it takes us. In each stub file I'm going to create a URI struct which will be passed into LightBase (if it exists). LightBase will then set any URI properties (including the page filepath which is used to look up additional page specific information) by loading them into the input object (which encapsulates access to URL and form scopes). It will *then* load the URL and form scopes, so if you want to overload URI settings you can do so buy just passing a URL or form variable (and it happens that you may want a single URI to support multiple actions so you need the ability to overload the URIs default action - which of course makes it not a true URI, but I'll take the flexibility for now and lock things down in a bit if I find I don't need it!).

What I really like about this approach is that I can create page URIs and then delegate to my features (or a composed object within them) to generate their own URIs so I don't need to figure out how all of my features will create URIs - they can do it any way they want.

This post was starting to get a little long, so I stopped here, hacked together a simple URI file: about-us.html. The goal of it was to display the About Us page. The following code worked fine:

<cfscript>
   URI = StructNew();
   URI.FilePath = "about-us";
</cfscript>
<cfinclude template="index.cfm">

I also tried adding and testing for various other properties like "action" and "CatID" and it all worked just as planned. The code to implement basecially required index.cfm to create a URI struct if there wasn't one (for consistency) and to pass it in to LightBase.run(). LightBase then just needed to Input.load(URI) before input.load(URL) and input.load(form). Obviously all kinds of issues and enhancements, but as a first cut I quite like the flexibility that this provides for any combination of URI, URL and/or form properties for a given page request - it gives a lot of flexibility to the feature designers when they decide how to design their URLs for features they want to add to LightBase.

Thoughts?!

Comments
BlogCFC was created by Raymond Camden. This blog is running version 5.005.