Dynamic
Template Delivery (DTD) in FB3 and as a CFC
By
Ray Bayly
It?s 9:00 AM on a Monday
morning, the boss has called a meeting to discuss a new product as you sit there
recovering from a late of night battling foes on the computer you notice your
boss has that familiar malicious gleam in his eyes, you know the one it?s the
same one he had when he asked if the apps on the server were ?508?
compliant. As you begin sink in your chair you realize that he is looking at you
smiling. He mentions a client and a ?Big Opportunity?. Then he mentions the
word ?Portal? and that is when it dawn?s on you, He has found the stash of
?wired? magazines that you have been hiding from him. As the boss begins to
layout his ?BIG PLAN? your mind goes to work. He wants an application that
200 companies can view from there own site?s look and feel. 200 Companies you
think , That is allot of copied code , suddenly you think of 200 URL?S and 200
Folders on the server and you look over at Bill the IT Admin who is turning blue
from trying not to scream. You mention words to your boss like ?statistical
nightmare? disastrous support scenario?. But he just smiles blankly and asks
if you can have that in a week.
Normally this would be a
nightmare scenario with Code versions and multiple upgrades requiring an entire
staff to stay on top of it. But fear not there is an easier way to manage an
application like this. Now lets delve into that black bag of methodology for you Fusebox guru?s this will seem very familiar.
The Methodology
Let talk for a second about the process behind Dynamic Template Delivery. We are
of course talking about Model View Controller (MVC). This Methodology was first
developed By Xerox PARC for Small talk 80. MVC is the ability to separate into
three separate pieces the Model, User Interface (UI) and Controller. More of
this is covered at length in ?Discovering Fuse box 3? or at www.fusebox.org
I recommend you read up on it as it will become more and more relevant to
developers as MX becomes the Dominant Version of CF.

The
Database
So there you are blessed with
the knowledge of Model View Control and an app plan starting to come out of the
Monday fog in your head. You smile confidently at Bill the IT guy, visually
assuring him that he can postpone the
Ritual Hari Kari in the server room because you have everything under
control. So now the boss, sensing your confidence and Zen like state
throws another curve at you. The application now has to be managed by sales.
With that sinking feeling coming back into the pit of your stomach you look over
in the corner to Charlie the sales guy who at that moment is stomping and
cursing about not being able to find Word on the Etch e Sketch you told him was
a state of the art laptop not two weeks ago. But alas all is not lost, for you
remember one of the key benefits of Cold Fusion is database delivery and you
pull out your trusty Visor and begin to jot down a table design.

With a table like this you
are able to later build an admin area that uses cffile to allow you to register
and change sites and templates without the need for new code. Boy that was a
close one, but once again you have triumphed and we are ready to get on with
this scenario.
For
this example go ahead and build this table and name it DTD_Test in a Database of
your choice. Create a Datasource Called DTD_Test on the CFServer.
The
Test Template
Now that you have come this
far we are ready to create a couple of Templates. I want you to create three
distinct Designs and separate them into header and footer. Call them
header_1.htm, footer_1.htm and so on. I know all of you fuseboxers out there are
looking a little confused. Why break them up when fusebox allows for a single
template. Well there is a very simple reason. Since the templates are managed by
someone other then a Programmer we remove a possibility of error. Most
Administrators and or sales people are not programmers so there is a very real
possibility that even a simple piece of code like <cfouput>#fusebox.layout#</cfoutput>
would be too much to remember every time. So we very simply remove them from
having to do that .
Place
the template?s in your intepub directory under DTD_Test/Templates.
Alright the Templates are
created and the datasource is set up. Now we are ready to populate the Database
with some test data . Create a folder under the DTD_Test Directory called
SCRIPTS. Create a new file called populate.cfm and place the following script in
it.
<cfoutput>
<cfset I = 1>
<cfset N = 3>
<cfloop
condition=?I LTE N?>
<cfquery
name=?Populate?
datasource=?DTD_Test?>
INSERT INTO Site_Master
(Site_Name, DNS, Site_Version, template_header,. Template_footer)
VALUES
( ?Test Site #I#?, ?DTD_TEST?, ?1.0?, ?header_#I#.htm?,
?footer_#I#.htm?)
</cfquery>
<cfset I = I + 1>
</cfloop>
</cfoutput>
Once
the file has complete running go ahead and delete it as you will not be needing
it anymore. Now if you open the database you will notice three records with the
template names under header, footer fields.
Now the Database is populated
and we are ready to start coding.
The
Fusebox Files
First Go Ahead and Download
the Core Fusebox 3 files. This lesson is going to assume you
know how to use them so I
won?t go into detail on how to set them up.
Go ahead and install them into the DTD_Test Directory. You can get the
base Fusebox 3 files at http://www.fusebox.org/index.cfm?fuseaction=specs.cffusebox30
Once you have installed the
fusebox 3 files into the DTD_Test directory amd set them properly go ahead and open your favorite cfm editor.
First Let?s Create a File
and Call it qry_GetSite.cfm save it in the DTD_Test directory.
Put the following code into
the qry_GetSite.cfm file.
<!---
<fusedoc fuse="qry_GetSite.cfm">
<responsibilities>
I Dymanically Add the Visual Templates to the application.
</responsibilities>
<io>
<in>
<string name=?url.id? comments=?This is the optional passed
id?/>
<out>
<string name="Request.SiteName" comments="Number of
Records Returned " />
<string
name="Request.Site_Version" comments="Site version of current
code " />
<string name="Request.admin_email"
comments="Administrative site " />
<string name="Request.support_email" comments="Support
email for the site " />
<string name="Request.template_header"
comments="Header file name " />
<string name="Request.template_footer" comments="Footer
file name " />
</out>
</io>
</fusedoc>
--->
<cftry>
<cfif NOT IsDefined("url.id")>
<cfquery name="GetSite"
datasource="DTD_Test">
SELECT SiteName, Site_Version, admin_email, support_email, template_header,
template_footer
FROM Site_Master
WHERE dns = '<cfoutput>#cgi.HTTP_HOST#</cfoutput>'
</cfquery>
<cfelse>
<cfquery name="GetSite"
datasource="DTD_Test">
SELECT SiteName, Site_Version, admin_email, support_email, template_header,
template_footer
FROM Site_Master
WHERE id = '<cfoutput>#url.id#</cfoutput>'
</cfquery>
</cfif>
<cfif
GetSite.recordcount EQ 0>
<cfthrow
type="any" message="No Template Available">
</cfif>
<cfset
Request.SiteName = GetSite.SiteName>
<cfset
Request.Site_Version = GetSite.Site_Version>
<cfset Request.admin_email = GetSite.admin_email>
<cfset Request.support_email = GetSite.support_email>
<cfset Request.template_header =
GetSite.template_header>
<cfset Request.template_footer =
GetSite.template_footer>
<cfcatch
type="Any">
<cflocation
url="maintenance.cfm">
</cfcatch>
</cftry>
This is the core query file
for your template system it will check to see if you are passing an id
?index.cfm?id=2? and if so it will query the database on that id, however if
you don?t pass the query it will then look at the dns and query the database
off of that. If no records are returned from either of them then the system will
throw the user to a maintenance page.
Once
the file is created we are now ready to create our maintenance page. Create a
new file called maintenance.cfm this is a simple page that only say?s ?We
are under maintenance?.
Now save that to the root
directory. This maintenance page is also used to catch error?s in this file ,
if an error occurs it automatically sends the user to this page.
By being able to keep and register the templates in a database we can
keep track of all the sites using the system as well as the template versions,
this is done with the site_version field in the database.
Now open the index.cfm
file and type the following above the include files on the page.
<cfinclude
template=?qry_GetSite.cfm?>
Alright
you are doing great
By adding this to the
index.cfm page we insure we have full control over the base template at all
times. Now open the fbx_Layouts.cfm file change
the file to reflect the following.
<cfset
fusebox.layoutFile = "dsp_LayoutControl.cfm">
<cfset fusebox.layoutDir = "">
Creat
a blank file and call it
dsp_LayoutControl.cfm in the DTD_Test directory, add the following code
to the file and save it.
<!---
<fusedoc fuse="dsp_LayoutControl.cfm">
<responsibilities>
I
am the Display control file I add the dynamic template to the application
</responsibilities>
<io>
<in>
<string
name="Request.template_header" comments="Number of Records
Returned " />
<string
name="Request.template_footer" comments="Number of Records
Returned " />
</in>
</io>
</fusedoc>
--->
<cfoutput>
<cfinclude template="Templates/#Request.Template_header#">
#fusebox.layout#
<cfinclude template="Templates/#Request.Template_footer#">
</cfoutput>
This file will act as our
fusebox display file. It will pull the template?s into the file and add then
to the content of the application.
Now we are ready to test our
application. First type in the app address
http://127.0.0.1/DTD_Test/index.cfm
Right now you should see a
maintenance page. The reason for this is because we have not added the dns to
the database so by not passing an ID or by using a registered dns we in effect
don?t have any templates assigned. Now open the database and add then name of
the server the app is on to the first record. IE if you are on your machine then
add 127.0.0.1 to the field .
Now open the
application again and refresh the page. Notice now template 1 comes up . This is
because you have now added the dns to the system . As a note if you are not IT
support savvy the DNS server allows you to point more then one URL to a server.
This is great if you are selling your site. Heres an example lets say it was a
real estate application you were building and you wanted every state to
have its own look or feel on the application. So if you added
richmond