Quantcast
Channel: CFML Frameworks – Ricardo Parente's Blog
Viewing all articles
Browse latest Browse all 11

Fusebox 5.51 with MVC Tutorial – Part 1 New Edition

$
0
0

Unfortunately something happened to my old tutorial when I switched Internet provider and the posts were messed up, I got some complains, so I’m re-posting them here.
This is Part 1:

I work with Fusebox framework since its version 2. Now we are at version 5.51. I decided to write this tutorial to help some friends who haven’t got into Fusebox yet but are anxious to jump into the bandwagon, just don’t know how to start. I recommend Jeff Peter’s books on Fusebox for those who really want to take advantage of this framework:

MVC – Model View Controller

Before going into the framework, let’s talk a little about MVC (Model, View, Controller). For those who don’t know MVC, it is a method of separating the presentation, action and control layers of the application in order to achieve better and secure way of programming, and easier maintenance.

All external calls (from the web URL) are directed to the Control layer. Then the Control will decide which actions to take, like performing a query, a calculation, etc… That is done in the Model layer, which has no access from the outside world. Then the Control will submit the results to the View (presentation layer) which will assemble the contents to the public. Basically, all public link addresses to your website will be calling the Control layer. All your queries and action pages will be in the Model, and all your display pages will be in the View, easy to find and maintain.

Example: if you have to show a list of real estate properties, the Control will call a query in the Model to obtain the data and then call a display page in the View to show all the properties selected in the query.

Fusebox

Figure 1.1

Figure 1.1

Fusebox is a methodology for developing web applications. It protects your application by forcing all calls to be made to a single template: index.cfm, which acts as the hub where all connections are made. By passing the “fuseaction” attribute, you will tell the Fusebox framework what action you want to be executed.

So, with the analogy to the “electric fusebox”, the framework is divided into “circuits” and “fuses”. Your application folders are called “circuits” and the ColdFusion templates are the “fuses”.

In this tutorial we will be referencing the Fusebox 5.51 XML version, not the non-xml one (sort of OO). Let’s start by downloading the Fusebox 5.51 Core Files, select the first link: Official FB5.5.1/CFMX core files (v5.5.1).

Unzip the contents to a folder named “fusebox5″ inside your web application root if you DO NOT have access to the ColdFusion administration site. Otherwise, extract the contents to a folder outside your web root and then map it as “/fusebox5″. Doing that, you will be able to have multiple websites using the same Fusebox core installation.

Your Fusebox core structure should be like Figure 1.1 side.

Figure 1.2

Figure 1.2

We are going to create a web application for a store called FBTutorial. Here are the initial application requirements:

  • Home Page with News Articles
  • Contact Page – form
  • Products page – catalog
  • Shopping Cart
Figure 1.3

Figure 1.3

I know two ways of creating the MVC structure for a Fusebox application. One is most used by creating 3 folders: _model, _view and _controller (the underscores are for placing the folders on top of the other regular ones), and inside those folders we would put the Fusebox circuits.

I find that more complicated and less modular. Any maintenance you need to do, you will have to look at the subfolders inside other subfolders, etc… (figure 1.3)

If you want to turn a circuit into a module that could be copied to other application, the better approach should be creating the circuits first, and then inside each circuit you create the folders “model” and “view”, being the circuit root itself working as the “controller”.

So I chose the second structure by creating the circuit folders and

Figure 1.4

Figure 1.4

then their subfolders model and view (Figure 1.4). Here is how we will create the application structure:

  • FBTutorial
    • circuits
      • forms
      • home
      • news
      • products
      • shopping
    • other folders…

Now, inside each circuit folder, we will create the folders “model” and “view“. You decide

Figure 1.5

Figure 1.5

if you want to prefix them with underscore “_”, since you will not have any other folder in the circuits.

After creating all the necessary folders, we need to create empty control files in each folder. Those files will be named “circuit.xml.cfm”, which are XML files but with the extention CFM so they cannot be read by the browser without being parsed by ColdFusion. Just create the empty files for now.

Figure 1.5 shows the new structure with the XML files.

Do not worry about the empty files, we will fill them in later.

Figure 1.6

Figure 1.6

I’m just preparing the application structure before starting coding.

Now, let’s create the Fusebox required and optional files on the application root. Starting with the Application.cfc (capital “A”), fusebox.appinit.cfm, fusebox.init.cfm, fusebox.xml.cfm and index.cfm (create those empty files and we’ll work on them next. Your structure now should be like Figure 1.6.

Application Root

Let’s start now working on the Fusebox files on the application root. First of all, the Application.cfc component which is always the first to run on each request.
The basic methods in the Application.cfc component are:

  • onApplicationStart,
  • onApplicationEnd,
  • onSessionStart,
  • onSessionEnd,
  • onRequestStart

You may have additional methods like onRequestEnd, onError… but right now we are interested in the Fusebox method: onFuseboxApplicationStart. That method is called when the Fusebox application initiates. It replaces the template fusebox.appinit.cfm in the application root. So if you may decide to use this method instead of that template, then it’s one less file to maintain.

Here is our Application.cfc template:


<cfcomponent extends=”fusebox5.Application” output=”false”>
<cfscript>
	this.name = right(REReplace(expandPath(‘.’),’[^A-Za-z]‘,”,’all’),64);
	this.applicationTimeout = createTimeSpan(0,6,0,0);
	this.sessionManagement = true;
	this.sessionTimeout = createTimeSpan(0,0,30,0);
	this.clientManagement = true;
	this.mainDSN = “myDSN”;
	this.webmasterEmail = “myEmail@myDomain.com”;
</cfscript>
<!— trap non-index.cfm requests – must be outside onXxxYyy() handlers —>
<cfif right(cgi.script_name, len(“index.cfm”)) neq “index.cfm” and
	right(cgi.script_name, 3) neq “cfc”>
	<cflocation url=”index.cfm” addtoken=”no” />
</cfif>

<cffunction name=”onApplicationStart” returntype=”boolean” output=”false”>
<cfreturn True>

</cffunction>

<cffunction name=”onApplicationEnd” output=”false”>
	<cfargument name=”applicationScope” required=”true” />
</cffunction>

<cffunction name=”onSessionStart” output=”false”>
</cffunction>

<cffunction name=”onSessionEnd” output=”false”>
</cffunction>

<cffunction name=”onFuseboxApplicationStart”>
	<cfset super.onFuseboxApplicationStart() />
	<!— code formerly in fusebox.appinit.cfm —>
	<cfif not structKeyExists(application,”mainDSN”)>
		<cflock name=”mainDSN” type=”exclusive” timeout=”10″>
			<cfset application.mainDSN = this.mainDSN />
		</cflock>
	</cfif>
</cffunction>

<cffunction name=”onRequestStart”>
	<cfargument name=”targetPage” />
	<cfscript>
		super.onRequestStart(arguments.targetPage);
		//code formerly in fusebox.init.cfm
		self = myFusebox.getSelf();
		myself = myFusebox.getMyself();
		if (listFirst(CGI.SERVER_NAME, “.”) == “www”) {
			FUSEBOX_PARAMETERS.mode = “production” ;
		} else {
			FUSEBOX_PARAMETERS.mode = “development-circuit-load” ;
		}
		// request scope
		request.applicationName = this.name;
		request.mainDSN = this.mainDSN;
		request.webmasterEmail = this.webmasterEmail;
		request.baseDir = GetDirectoryFromPath(GetBaseTemplatePath());
		request.componentPath = “assets.components.”;
		request.imagePath = “assets/images/”;
		request.cssPath = “assets/css/”;
		request.jsPath = “assets/js/”;
		request.flashPath = “assets/multimedia/”;
		request.videoPath = “assets/multimedia/”;
		request.ppsPath = “assets/multimedia/”;
	</cfscript>
</cffunction>

</cfcomponent>

Now, here is the deal. Since the Fusebox core also has an Application.cfc with the same methods, we need to extend our Application.cfc to the Fusebox one and make use of the “call super” to invoke those methods first in order to use ours. On the first line, we extend the component. Remember to map /fusebox5 in your ColdFusion adminstration to the folder were you saved the core files.


<cfcomponent extends=”fusebox5.Application” output=”false” />

The method onFuseboxApplicationStart must have the call super:


<cffunction name=”onFuseboxApplicationStart”>
	<cfset super.onFuseboxApplicationStart() />
	....
</cffunction>

Some code that was formerly in fusebox.init.cfm:


self = myFusebox.getSelf();
myself = myFusebox.getMyself();

Fusebox.init.cfm

We basically wrote all the necessary code for starting with the Application.cfc, now let’s concentrate on the Fusebox template fusebox.init.cfm. It is included by the framework at the start of every request. It is included within a cfsilent tag so it cannot generate output. It is intended to be for per-request initialization and manipulation of the fuseaction variables.

You can set attributes.fuseaction, for example, to override the default fuseaction. Fusebox 5.1 and later – set variables implicitly from the Fusebox itself.

Could also modify the self location here:


<cfset myFusebox.setSelf(“/myapp/start.cfm”) />

For now, just write the following code in your fusebox.init.cfm template:


<cfprocessingdirective suppresswhitespace=”true”>
<!— some future code here —>
</cfprocessingdirective>

Index.cfm

The index.cfm template will have only one statement:


<cfinclude template=”/fusebox5/fusebox5.cfm” />

In a Fusebox application the index.cfm template has no use other than to include the framework.

Fusebox.xml.cfm

The last file on the application root we have to work on is the fusebox.xml.cfm, which is the file that controls all the fusebox circuits, parameters, classes, plugins and global actions.
In the “circuits” block we define the paths and aliases for the circuits. You may chose any name as an alias to a circuit, does not have to be the same name of the folder, you will see below that we are calling “cart” the circuit in the folder “shopping”.
The “parameters” block contains Fusebox default settings, and it is customizable.
Here is our fusebox.xml.cfm file:


<?xml version=”1.0″ encoding=”UTF-8″?>
<!DOCTYPE fusebox>
<!–Example fusebox.xml control file. Shows how to define circuits, classes, parameters and global fuseactions. This is just a test namespace for the plugin custom attribute example –>
<fusebox xmlns:test=”test”>
	<circuits>
		<!– Home circuit –>
		<circuit alias=”home” path=”circuits/home/” parent=”" />
		<circuit alias=”mhome” path=”circuits/home/model/” parent=”home” />
		<circuit alias=”vhome” path=”circuits/home/view/” parent=”home” />
		<!– Forms circuit –>
		<circuit alias=”forms” path=”circuits/forms/” parent=”home” />
		<circuit alias=”mforms” path=”circuits/forms/model/” parent=”forms” />
		<circuit alias=”vforms” path=”circuits/forms/view/” parent=”forms” />
		<!– News circuit –>
		<circuit alias=”news” path=”circuits/news/” parent=”home” />
		<circuit alias=”mnews” path=”circuits/news/model/” parent=”news” />
		<circuit alias=”vnews” path=”circuits/news/view/” parent=”news” />
		<!– Products circuit –>
		<circuit alias=”products” path=”circuits/products/” parent=”home”/>
		<circuit alias=”mproducts” path=”circuits/products/model/” parent=”products” />
		<circuit alias=”vproducts” path=”circuits/products/view/” parent=”products” />
		<!– shopping circuit –>
		<circuit alias=”cart” path=”circuits/shopping/” parent=”home” />
		<circuit alias=”mcart” path=”circuits/shopping/model/” parent=”cart” />
		<circuit alias=”vcart” path=”circuits/shopping/view/” parent=”cart” />
		<!– Layout circuit –>
		<circuit alias=”layout” path=”circuits/layout/” />
	</circuits>
	<classes>
	</classes>
	<parameters>
		<parameter name=”defaultFuseaction” value=”home.main” />
		<!– you may want to change this to development-full-load mode: –>
		<parameter name=”mode” value=”development-full-load” />
		<!– change this to something more secure: –>
		<parameter name=”password” value=”" />
		<parameter name=”strictMode” value=”true” />
		<!– These are all default values that can be overridden:
		<parameter name=”fuseactionVariable” value=”fuseaction” />
		<parameter name=”precedenceFormOrUrl” value=”form” />
		<parameter name=”scriptFileDelimiter” value=”cfm” />
		<parameter name=”maskedFileDelimiters” value=”htm,cfm,cfml,php,php4,asp,aspx” />
		<parameter name=”characterEncoding” value=”utf-8″ />
		<paramater name=”strictMode” value=”false” />
		<parameter name=”allowImplicitCircuits” value=”false” />
		<parameter name=”debug” value=”false” /> –>
	</parameters>
	<globalfuseactions>
		<preprocess>
		</preprocess>
		<postprocess>
		</postprocess>
	</globalfuseactions>
	<plugins>
		<phase name=”preProcess”>
		</phase>
		<phase name=”preFuseaction”>
		</phase>
		<phase name=”postFuseaction”>
		</phase>
		<phase name=”fuseactionException”>
		</phase>
		<phase name=”postProcess”>
		</phase>
		<phase name=”processError”>
		</phase>
	</plugins>
</fusebox>

We define the circuits in the “circuits” block by assigning an alias to the path. In the application we will call the index.cfm passing the circuit,fuse and fuseaction we want to execute. Example:

Figure 1.7

Figure 1.7

index.cfm?fuseaction=home.main
index.cfm?fuseaction=products.showProduct&productID=1234
index.cfm?fuseaction=cart.addToCart

With Fusebox, everything is assembled in the root. The index.cfm loads Fusebox and it prepares the request to be served without the customer seeing in which folders the templates are.
We added a circuit named “layout” which will handle all the layouts for our application. Since it is for the presentation layer, we do not have to create the “model” folder. Figure 1.7 shows an updated version of our structure.

Circuit.xml.cfm

Now we are going to look at the circuit.xml.cfm file placed in all circuits.
Let’s start with the “home” main circuit, the controller one” /circuits/home/circuit.xml.cfm:
For now we will not have any actions to call, just a display page to show the homepage, then our circuit.xml.cfm file will have the following code:


<?xml version=”1.0″ encoding=”UTF-8″?>
<!– home –>
<circuit access=”public” xmlns:cf=”cf/”>
	<fuseaction name=”main”>
		<do action=”vhome.main” />
	</fuseaction>
</circuit>

You noticed that we here we are calling an action on another circuit, the “vhome”, in the “view” part of the MVC, to display the homepage. If we had to calculate anything or grab any information from a database in order to populate that homepage, then we would call the “model” layer before the “view”.

The call to “index.cfm?fuseaction=home.main” will get to this circuit which will call the “vhome.main” fuseaction in the “view” area. Subsequently that fuseaction, “vhome.main”, will include the template “dspMain.cfm” with the contents of the homepage, and then Fusebox will assemble the full page for ColdFusion to render to the browser. Note that the attribute “access” for this circuit is set to “public”. That means it can be accessed by the web browser, it is a public fuse.

Here is the circuit.xml.cfm file in the “view” area:


<?xml version=”1.0″ encoding=”UTF-8″?>
<!DOCTYPE circuit>
<!– vhome –>
<circuit access=”internal” xmlns:cf=”cf/”>
	<fuseaction name=”main”>
		<include template=”dspMain.cfm” required=”true” />
	</fuseaction>
</circuit>

In this case, the “access” attribute is set to “internal” which means this circuit can be only called by another circuit, it will not respond to browser calls.

The fuseaction “main” will include the template dspMain.cfm.
Just for testing purpose, create the file dspMain.cfm with the following HTML code:


<h1>Hello World!</h1>

Now, let’s test the site. If you have ColdFusion Developer Edition installed in your machine, just browse to: “http://localhost/FBtutorial“. You do not have to specify any attributes, because the Fusebox configuration file (fusebox.xml.cfm) will take care of calling the default fuseaction “home.main”.
You should get the page “Hellow World”.

On the next part we will start handling layouts.

I hope you have liked this tutorial and please feel free to comment if you have questions.

Part 2


Viewing all articles
Browse latest Browse all 11

Trending Articles