Wednesday, August 4, 2010

ColdMVC: Basic CMS app request handling

I wanted to try make a cms app with ColdMVC so I took a stab at it. This is my first draft at a cms app. Below is a light weight request handler for cms views. We will break it down in a sec.


/**
* @accessors true
* @extends coldmvc.Controller
* @controller cmsview
* @layout cms_public
*/
component {

property _CMSPage;

/**
* @events requestStart
*/
function requestStart(){

var page = _CMSPage.findByAddress(getPath());

/*---check if the path is a cms page---*/
if(len(page.id()) gt 0){
$.event.action("render");
$.event.controller("cmsView");
$.event.view("cms/view/index.cfm");
}

}

function render(){

var path = getPath();
var actual_path = expandPath("/app/views/#path#");

/*---handles pages that end in a slash. Ex: www.mydomain.com/public/index.cfm/products/---*/
if(right(path,1) eq "/"){
actual_path = actual_path & "index.cfm";
path = path & "index.cfm";
}

/*---if the file exists render it, else run the page's html through the cms_public layout.---*/
if(fileExists(actual_path)){

$.event.view(path);

}else{

params.page = _CMSPage.findByAddress(getPath());

if(len(params.page.id()) eq 0){

render404();

}

}

}

/**
* @events invalidController, invalidAction
*/
function render404(){

params.page = _CMSPage.findByAddress("404");

if(len(params.page.id()) eq 0){
params.page._set("html","Sorry. We couldn't find the page you were looking for.");
}

$.event.controller("cmsView");
$.event.action("render404");
$.event.view("cms/view/index.cfm");

}

function getPath(){

var path = $.event.path();

if(left(path,1) eq "/"){
path = replace(path,"/","");
}

return path;

}

}


When a request begins I use the event "requestStart" to check if it's a cms page. This happens here...


/**
* @events requestStart
*/
function requestStart(){

var page = _CMSPage.findByAddress(getPath());

/*---check if the path is a cms page---*/
if(len(page.id()) gt 0){
$.event.action("render");
$.event.controller("cmsView");
$.event.view("cms/view/index.cfm");
}

}


As you can see above we are checking if getPath() is a cms page. getPath() gets the tail end of the url. Example: If the url read "www.mydomain.com/public/index.cfm/contact_us/", getPath() would return "contact_us/". This happens here...

function getPath(){

var path = $.event.path();

if(left(path,1) eq "/"){
path = replace(path,"/","");
}

return path;

}


If a cms page isn't found the request will run as usual. If a cms page is found it will go to render(). render() does a lot of checks.

First, we check if there is no file extension, example ".cfm", on path. If there is none I put in an "index.cfm" at the end. I do this for the next check which checks to see if the file exists.

Second, next we check if the file path actually exists in the app/views/ directory. If it does I render it. I do this because some pages might need to be coded where as other pages will be setup with a "web page generater" tool.

Third, if the file doesn't exists I can assume it's a page that was created by web page generator tool.

Lastly, I check if the page doesn't exists. I do this because my config.ini uses render() as defaults.
[default]
controller=cmsView
action=render

If someone requests "www.mydomain.com/public/index.cfm" the path won't exist. Therefore we excute the 404 handler, which is called render404().

This happens here...

function render(){

var path = getPath();
var actual_path = expandPath("/app/views/#path#");

/*---handles pages that end in a slash. Ex: www.mydomain.com/public/index.cfm/products/---*/
if(right(path,1) eq "/"){
actual_path = actual_path & "index.cfm";
path = path & "index.cfm";
}

/*---if the file exists render it, else run the page's html through the cms_public layout.---*/
if(fileExists(actual_path)){

$.event.view(path);

}else{

params.page = _CMSPage.findByAddress(getPath());

if(len(params.page.id()) eq 0){

render404();

}

}

}

If a page doesn't exists in the cms pages, an invalid controller or action is found I render404() is executed. I first check to see if a 404 page was created in the cms pages else I render my own html message.

This happens here...


/**
* @events invalidController, invalidAction
*/
function render404(){

params.page = _CMSPage.findByAddress("404");

if(len(params.page.id()) eq 0){
params.page._set("html","Sorry. We couldn't find the page you were looking for.");
}

$.event.controller("cmsView");
$.event.action("render404");
$.event.view("cms/view/index.cfm");

}


As I have been going through these functions I didn't explain where the pages are getting renderer. If you noticed at the top of first block of code there was an annotation @layout cms_public. All cms pages, whether they are coded up or database driven, run through the layout cms_public.cfm. Here's what it looks like...

<cfoutput>
< !DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html lang="en-us" xmlns="http://www.w3.org/1999/xhtml">

<cfif structKeyExists(params,"page")>
#page.html()#
<cfelse>
#render()#
</cfif>

</html>
</cfoutput>


All database driven pages run through a view in "views/cms/view/index.cfm" which looks like this...

<cfoutput>#page.html()#</cfoutput>


Thoughts on what I have so far?

No comments:

Post a Comment