As seen in Fusion Authority CF e-zine http://www.fusionauthority.com/
What is Fusebox?
Fusebox is a "wave" that is sweeping the ColdFusion community. A coding standard and program methodology, it is quickly becoming popular among ColdFusion coders. In fact, it has even been ripped off…err…adapted for use with other web programming languages! The reason it is so popular is that it does an excellent job of filling the standards void in the ColdFusion development community.
Steve Nelson and Gabe Roffman developed Fusebox in 1998 because they needed a way to collaborate efficiently on projects. They had to solve problems like finding a way to write object-oriented code and to make scalable applications, while at the same time making it easier to read and document their code. In the end they delivered an idea that was much more than they expected. Fusebox began to spread as quickly as ColdFusion's phenomenal popularity.
Fusebox is a ColdFusion programming methodology. Using Fusebox for building applications has the following benefits:
Promotes reuse of code
Allows small applications to scale larger ones
Supports division of labor among content providers, programmers, graphic artists and layout workers.
Makes code easier to read, understand and document
Makes it easier to maintain code
Allows programmers to "embed" an entire CF application by turning the application into a CF tag
The Physical Design of a Fusebox application
At first Fusebox can be a bit difficult to understand, especially if you’ve never worked with modular code or in an object-oriented environment. Perhaps the hardest thing to get about Fusebox is that it’s really quite simple! Once you wrap your mind around a few concepts, it becomes very easy to grasp. First, let’s have a look at the physical setup of the Fusebox architecture.
The main idea behind Fusebox is to break down your application into modules, or small pieces that do simple, specific tasks. These tasks are called fuses—I’ll explain why in a moment. Each individual "fuse" module is made up of smaller sections of code that serve specific purposes, which are broken down into five categories: Actions, Display Blocks, Queries, Application Files and ColdFusion Custom Tags. These are actually implemented by files that contain ColdFusion and HTML code. The reason for breaking down the files in this way is that it makes it very easy to reuse them. You’ll end up with a smorgasbord of files that comprise your application. Later, I will explain how to use the CFINCLUDE statement to throw these files together on the fly to make your files work together.
For example, if you have a small application that queried your database and then displayed the results, you would separate the query itself from the code that displays the results. Each of the two pieces would go into its own separate file, which would be named in specific way to make it easy to identify its function. The file containing the SQL query, for instance, would be placed in your QUERIES directory and named qry_what_this_query_does.CFM. The file that contains the code to display the results of your query would begin with the dsp_ prefix and be placed in the BLOCKS directory. The file may be called dsp_what_this_code_displays.cfm. The dsp_ prefix indicates that this is a display BLOCK file, which will display something, and the qry_ prefix indicates that this file contains code for a SQL query. This way, someone looking at your code could easily see, just by looking in your QUERIES directory, that each file is a query and since you’ve given it a descriptive name, they will even have an idea what each query’s job is without ever viewing the actual code. Furthermore, if you ever find the need to reuse that query in another place in your application, you’ll be able to find it and reference it again. And better yet—if you change the query, you’ll only do it once, and it will affect every place that this SQL is used. The same holds true for the display block represented by dsp_what_this_code_displays.cfm.
Once you have the component files of your module ready, you use the CFINCLUDE statement to bring them together. The CFINCLUDE tag allows you to embed separate ColdFusion pages into another page. ColdFusion will use the CFINCLUDEd page as if it were actually part of the page that references it. It just inserts the code from the included page into the page that CFINCLUDEs it. This is the key to keeping the pieces of your application separate, while at the same time allowing you to reconstitute them as needed. In general, the syntax of a CFINCLUDE tag is:
A bit earlier, we gave the file that contains our query a simple prefix and placed it in a specially named directory. To keep your Fusebox applications standard, you always use the Fusebox prefixes for the different types of files and put them into the proscribed directories. To make this easier, I suggest that the first thing you do when you start a Fusebox application is to set up your directory tree. The basic tree structure looks like this:
This physical organization is very important to standard Fusebox coding. With this directory structure in place, the CFINCLUDEs necessary to do the job of querying the database and then displaying the results would look something like:
Notice that we are using relative paths in the example above. Although it is possible to do your CFINCLUDEs this way, the preferred method is to create CF mapping to the root directory of each application. The CF mapping can only be used with the CFINCLUDE and CFMODULE tags. This way you can call a file from anywhere in your site, without having to worry about relative references to the file. For example:
<CFINCLUDE template="/ROOTMAPPING /queries/ qry_what_this_query_does.CFM " >
<CFINCLUDE template="/ROOTMAPPING/blocks/ dsp_what_this_code_displays.cfm ">.
As illustrated below, CF mappings are set in CF Administrator.
Figure 1 Creating a mapping in the Cold Fusion Administrator
So now you have an idea of how to physically set up your application. You have also seen how your code must be broken down into small modular pieces. Stay Tuned for Part II of this article, where we'll get down to the nitty gritty of coding in Fusebox.
FUSEBOX, An Overview: Part II
The Logical Setup of A Fusebox application
In Part I of this article, you learned about physically setting up your Fusebox application, and how your code must be broken down into small modular pieces. Now, let's look at the coding logic of a Fusebox app. The logical architecture of a Fusebox app resembles a hub and spoke system, with all actions returning to the hub (the Fusebox). This sort of structure is also known as a circuit application.
Figure 1 Fusebox App Structure
A circuit application is usually a single directory of files and generally does a few related tasks such as search. The overall application is called the home application, which is made up of many circuit applications. This is where Fusebox gets its name. Just like an electrical Fusebox, it is set up as a group of circuits ("fuses") that are ready to send the user to whichever part of the application his or her next click requires. Each of these fuses has a name, called a fuseaction. Fuseactions are used to turn on the appropriate switches to cause the required action. So the Fuseaction is the key to the application—without a fuseaction, the application will only do the default fuseaction.
INDEX.CFM and the Fuseaction
The home application is ALWAYS engendered in a file called INDEX.CFM, which is placed in the root directory of your application. Every link on the website will always be to this file! When creating the user interface for the application, each URL link or form will be to INDEX.CFM and then contain the name of the fuseaction that will do the work necessary if it is activated. For a URL, the fuseaction will be contained in the query string, for instance: http://www.this.co.uk/INDEX.CFM?fuseaction=search. For a form, the usual method of placing the fuseaction is to call the INDEX.CFM file in the form’s action field, but then include a hidden form field with the fuseaction:
<FORM action="INDEX.CFM" method="post">
<input type="hidden" name="fuseaction" value="search">
Okay, so now you are probably wondering about the internal workings of the INDEX.CFM file. As mentioned earlier, it will use CFINCLUDEs to combine files together to create a working application. But how does ColdFusion use the fuseaction to know which files to combine? This is done using CFCASE/CFSWITCH.
The CFCASE/CFSWITCH tags perform a similar function to a CFIF statement with a bunch of CFELSEIFs. But, using CFSWITCH/CFCASE will run much faster than a similar series of CFIF/CFELSEIF. When there are many ELSEIF's, the logic is exactly the same.
For example, here is a logical statement using CFIF/CFELSEIF:
<CFIF my_variable is "DOG">
<CFELSEIF my_variable is "CAT">
<CFELSEIF my_variable is "COW">
Using CFCASE/CFSWITCH, the same statement would be:
Since CFSWITCH/CFCASE is faster, it is the method used in the Fusebox architecture. INDEX.CFM will contain CFSWITCH/CFCASE to determine what the user wants to do. Think of the INDEX.CFM as basically one big switch statement and each CFCASE contains the information on what to do for a particular fuseaction. Therefore, the EXPRESSION= parameter of the CFSWITCH will be equal to your Fuseaction variable. An example: fuseaction=search might run a search and then display the results. In this case, the opening CFSWITCH statement should assign #FUSEACTION# to be the variable to be used, as in:
<CFSWITCH EXPRESSION="#FUSEACTION# ">
This means that basically, a fuseaction is the equivalent of a single CFCASE statement in your INDEX.CFM. Have a look at this code:
Suppose a user clicks on the following link:
<a href="INDEX.CFM?fuseaction= Sign_Up_For_Newsletter_Form>Sign up for the newsletter</a>
Using the example code above, when Cold Fusion executes our CFSWITCH using the "Sign_Up_For_Newsletter_Form" fuseaction, it will first display our HTML header block, then it will include the registration form itself and then finally the HTML footer. The rest of the CFCASES will be ignored.
Are you still with me? Great, because now you’ve already got down most of the basics of a Fusebox application. In part III of this article, we will cover some of the finer points of writing a good Fusebox application.
END OF PART II
The Finer Points
A typical application is going to need more than just a few CFINCLUDES to make it complete. There needs to be a vehicle to set default variable values and to hold important Cold Fusion directives such as CFAPPLICATION. In a Fusebox application, this is done through two files that always get included at the top of every INDEX.CFM file BEFORE your CFSWITCH statement. These your app_locals.cfm and app_globals.cfm files.
These two files are such a great idea, and they’re really going to save you time! Any Fusebox application will always contain one and only one app_globals.cfm file. Its purpose is to house global variables, default values and any directives that will be needed for every part of your application. Its contents will always wind up at the top of every page of your application. This is accomplished by using CFINCLUDE to include the files contents at the top of the app_locals.cfm file. Aside from conveying the values of the app_globals.cfm file, the app_locals.cfm file is basically used to house the values of variables that will only be needed for "local" sections of your application. A simple Fusebox application will only need one of these. A more complex application could have many of them. To help clarify this, have a look at these two file listings:
<!---Setup the application file --->
<cfapplication name="MyApplication" sessionmanagement="yes" clientmanagement="YES" setclientcookies="YES">
<!---Setup the default database name for the entire application --->
<CFPARAM NAME="application.dsn" DEFAULT="MyDatabaseName">
<!--- set the default fuseaction for this section of the app, in case none is given --->
<cfparam name="fuseaction" default=" Sign_Up_For_Newsletter_Form ">
At the top of your INDEX.CFM file you would need the following statement:
As explained above, this would cause the app_locals.cfm file to be included which in turn would include the app_globals.cfm file. You’ll want to put default values for your application in these two files. This way, whenever someone needs to change default values of some variable in your application, they can avoid opening up your code to search for the values, if they’re familiar with Fusebox, they’ll know right away that they can go directly to these two files.
You’ll notice a custom tag at the top of the app_globals.cfm file listed above: <cf_formURL2attributes>. This tag is an important part of a standard Fusebox application. It can be downloaded from www.fusebox.org’s custom tags area. Its main purpose is to change the scope of "URL." and "form." variables and convert them to the "attributes." scope. Why? The use of attributes variables is essential to encapsulating an entire app so that it can be called as if it were a custom tag, using <CF_tagname> or <Cf_module>. At first this idea may seem hard to grasp. It may take a first-hand look to really "get it." But when you see what this really means, its like magic.
To help facilitate this, all variables that are changed by users within a Fusebox application should be scoped with "attributes" in your app_globals file all Form. and URL. Scoped variables will be converted to attributes.variable, this allows an application to become both a standalone application and a CF Tag, which is exactly what Fusebox applications are trying to accomplish.
When you call a custom tag (i.e. FormURL2Attributes.cfm) CF takes any variables passed and makes them part of the attributes collection- to reference them you must use the "attributes." Prefix- this custom tag converts both form and URL variables into attributes. Variables -cfmodule can call circuit app as a tag.
cfmodule template=/ has to be an attributes variable- within the custom tag you must refer to any variables with the "attributes."
General Fusebox issues
When dealing with multiple file web apps it is important to realize that there are two types of Fusebox Tag Objects:
- Single page Tag Objects- fairly simple to integrate into other apps.
- Dual page Tag Objects- requires user interaction
The first page begins the operation, while the second will complete operation by doing some action depending on user's choices. Both are fairly simple to integrate into other apps.
The CF (fusebox) file is made up of only two sections:
- The first is responsible for a definition of variables that will affect the entire application. You can either define each variable in the fusebox or <CFINCLUDE> a page that holds this info (the latter is better for large projects).
- The second part of fusebox is responsible for direction. At any one time, the app has only one fuseaction, each user action is associated with a fuseaction- a single <CFSWITCH> statement determines the value of this variable that directs the program flow.
Designing for Fusebox
Create Fuse cards to design architecture:
- Fuseactions- dsp_, act_
- Required attributes
- Optional attributes
- Return attributes
- RFA (Return Fuseaction)
Using RFA's can help maintain code by insulating fuses from the changes made to other fuses. The RFA's are parameters passed into the fuse- they come from the fusebox.
Other CF programming tips
If you’re building a database from scratch, it is recommended that when creating a new table within your database to always use a single "number/integer" datatype as your primary and foreign key fields. This allows for the most integration with other database systems.
It's important that <CFTRANSACTION> be used when incrementing your primary key on the application side. By using CFTRANSACTION, your INSERT SQL statement and the MAX_ID will be treated as a single SQL statement on the database.
RULES ARE MADE TO BE BROKEN
The Fusebox standard is meant more as a series of guidelines. There is plenty of room built into the standard to allow for individual programmers styles. Also, the standard is not perfect. There are a few known scenarios that do not fit perfectly in with the Fusebox standard, although Eron Cohen can’t name even one. The recommendation is to try to stay as close as possible to the standard styles specified.
Fusebox Quick Reference:
1. Application Files (i.e. – app_locals.cfm or app.globals.cfm)
App_globals.cfm and app_locals.cfm contain global and local variables that are needed for an application.
- App_locals.cfm will always include an app_globals.cfm file
- App_locals.cfm will contain default variables specific to smaller application
- App_globals.cfm will contain variables that are global to the overall application (in the app_globals file we refer to formurl2attributes)
Steps to building a Fusebox application:
Plan your application. Use Fusecards and other techniques to get a very good idea of what needs to be done before you start
Create an empty directory structure and make a mapping in the Cold Fusion administrator to go with your application.
Setup your application files.
Begin coding the individual modules that will comprise your application
- App_Globals.cfm file is <CFINCLUDE>d as part of Fusebox's initialization and setup, which gives us a place to put variables that will be used by many fuses
- Application.cfm will not be used: when a file is called through a tag (CFMODULE) or when the application.cfm does not get called.
- App_locals will be CFincluded at the top of the INDEX.CFM
Because the user always goes through the INDEX.CFM, the app_locals and app_globals files will do the same thing as the application.cfm . CFAPPLICATION is put in the app_globals.cfm file as:
<CFAPPLICATION NAME="Someapplicationname" CLIENTMANAGEMENT="YES" SESSIONMANAGEMENT="YES">
2. Display Files (i.e. - dsp_yourfilename.cfm)
When modifying applications later, all you have to work with are the display files. Display files (dsp_) contain HTML and simple CFML and do not change data on the server, they only display info on the screen to the user and gather user input
A dsp_ file will never insert a new record into a database, but it may select info from a database using CF. The dsp_ files are the only files that contain info the user will see:
- cfinclude html and graphics
- cfinclude template=/blocks/dsp_.cfm
Directory named blocks will be created off the root directory of your application. This is where global display blocks will be stored, which all begin with "dsp_". The "Display Block" is a special dsp_ file that can be reused. The links should be either universal (INDEX.CFM) or absolute (/directory/INDEX.CFM)
3. Query Files- (i.e. - qry_yourfilename.cfm"
Global query files will begin with qry_ - CFINCLUDE the query file to reuse.
Directory named queries will be created off the root dir of your app, this is where global query files will be stored, which begin with qry_. Query files contain queries that may be reused in multiple parts of the application, these queries are cached when possible
- cfinclude qry in display file
- cfinclude template=qry_.cfm
Queries can be run only to obtain data, they cannot update, add, or delete info on the server.
Query files are a new file type, useful when used with query caching and should only be used when the rest of Fusebox concepts have been mastered. Query files generally have only a single CFQUERY in them, but are not restricted to one. The tag has a "cached within" attribute built in which takes timespan of when to auto refresh.
4. Action Files (i.e. - act_yourfilename.cfm (i.e. act_searching.cfm) )
Action files (act_) contain CFML and may not contain HTML. Action files can be used to insert, delete, and update within a database or could be used to change other data such as writing to a file or making changes to the data in an LDAP server. However, no info will be displayed to the user. These files are not limited to database changes, they can also be used for doing tasks that do not fit well into a display file. act_.cfm- will do CFLDAP and CFLOOP.
5. CFX (ie - <CF_SOMETAG> or <CFX_SOMETAG>)
Exists in the custom tags directory. CF extensions are CF tag or CFX tag that have been added to the CF server.
CFID and CFTOKEN can be used as cookie, form, or URL variables. You can then use client or session variables. If you plan on using client or session variables, it's recommended that you not rely on people using cookies. Attach #URLtoken# onto all of your links.
Fuse Manager File= INDEX.CFM, acts as the box, the Fusebox is the INDEX.CFM. This is the parent file which controls all the apps methods, known as "FuseActions". All requests for an application will go through this file. The job of the fusebox is to manage the action. It delegates actions to the fuses, which may be single or compound. The fuse-files are <CFINCLUDE>d into the fusebox which allows them to inherit all the variables of the fusebox itself.
The task of this file is to determine what CF code is necessary to do the "FuseAction" the user needs to do. For scalability with large applications, an INDEX.CFM should be in every directory in your application. Each directory will consist of essentially a different application. The first two lines of INDEX.CFM will refer to app locals and app_globals. Point all "href" and "action" attributes of your forms and links to the INDEX.CFM and include the fuseaction as a form field or as a URL variable. All urls refer to INDEX.CFM (may be something like /search/INDEX.CFM- (absolute path)).
Sample Fusebox app
The follow INDEX.CFM page is part of Steve’s SpecTool app. Fuses are marked in blue
// Copyright (C) 1999 Steve Nelson
// Distributed under the terms of the GNU Library General Public License
<cflocation url="INDEX.CFM?fuseaction=editspec&filename=#attributes.filename#" addtoken="No">
<cflocation url="INDEX.CFM?fuseaction=choosefile" addtoken="No">
<cflocation url="INDEX.CFM?fuseaction=choosefile&validupload=#validupload#" addtoken="No">
<cflocation url="INDEX.CFM?fuseaction=editspec&filename=#attributes.filename#&applicationid=#thisapplicationid#&saved=yes" addtoken="No">
<cflocation url="INDEX.CFM?fuseaction=editspec&filename=#attributes.filename#" addtoken="No">
<cflocation url="INDEX.CFM?fuseaction=editspec&filename=#attributes.filename#" addtoken="No">
Eron Cohen is ColdFusion programmer, MDCFUG speaker and author. Michael Smith is president of TeraTech http://www.teratech.com/ , a 11-year-old Rockville, Maryland based consulting company that specializes in ColdFusion, Database and Visual Basic development. Michael runs the MDCFUG and recently organized the two-day, Washington, DC-based CFUN-2k conference which attracted more than 750 participants. You can reach Michael at [email protected] or 301-424-3903.