In this tutorial we will discuss

  • How to set dynamic application variables.
  • How to Manage dynamic application variables.
    • Set, reset, edit, delete
  • How to set dynamic application variables on the fly
    • In case server/application is restarted or variable was deleted.

First a little background. Application variables are variables used site wide, for example, Site Name, Global email address and settings, URL, etc. They are variables that you would use frequently throughout the site and instead of defining the variable on each page or going to the database, the variable is set as an application variable.

I use Dynamic Application Variables in a CMS I built. When setting up a new site I didn't want to set all the application variables right off the bat then have to go back into the code and change them. And some times I had to change the variables after the site was running so again I didn't want to have to go into the code. Then I would have to have a reset button. Seemed like more of a mess then any thing. So I came up with some code to do it dynamically.

 

First things second. You will need to define your database connection variables in your code. I put them in my Application.cfc (or the outed .cfm)

<!--- Database Name --->
<cfset application.dsnodbc = "database">
<!--- Database Name --->
<cfset application.dsnodbc_user = "user">
<!--- Database Name --->
<cfset application.dsnodbc_password = "password">

The database connection variables are the only one you need manually set, every thing else we will do dynamically. For this tutorial these are the only three we need to set, depending on your database connection string you might need to set others.

 

We need to create the application variable table in the database.

I named the table "application_variables" with the following fields (app_id, app_name_var, app_var_property, app_var_notes)

Here's the MySQL code for creating the table

DROP TABLE IF EXISTS `application_variables`;
CREATE TABLE `application_variables` (
`app_id` int(11) NOT NULL auto_increment,
`app_name_var` varchar(255) default NULL COMMENT 'Name of the Variable',
`app_var_property` longtext COMMENT 'What the variable is',
`app_var_notes` longtext COMMENT 'Any Notes about the Variable',
PRIMARY KEY (`app_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

 

  • app_id - Auto incremented number
  • app_name_var - The name of the application variable, spaces should be "_"
    • Example: "email_address" or "url"
  • app_var_property - The property of the variable
    • Example: "email@email.com" or "http://www.easycfm.com"
  •  app_var_notes - Description of the application variable or notes about so if some one else comes along they know what and why it is.

Now that we have the table and an explanation of the fields, lets get to setting some Application variables.

 

This form will add and edit the application variables along with resetting them in the system.

<!--- Pre-Declare some variables, attaching query names because I'm using cfinput fields so no cfouputs tags, mostly. plus when editing I'm pretty sure we need the query name. --->
<cfparam name="GrabAppEdit.app_id" default="">
<cfparam name="GrabAppEdit.app_name_var" default="">
<cfparam name="GrabAppEdit.app_var_property" default="">
<cfparam name="GrabAppEdit.app_var_notes" default="">

 

<!--- On Submit of the form check if its a new record. First check to see if create_app_var is defined (submit button) Next check if its value is set to insert/create. --->
<cfif IsDefined('create_app_var') AND create_app_var EQ "Create Application Variable">

<!--- lock the Database and insert the record --->
<cflock name="insertList" type="exclusive" timeout="30">
<cftransaction>
<cfquery name="qryPAge" datasource="#application.dsnodbc#" username="#application.dsnodbc_user#" password="#application.dsnodbc_password#">
INSERT application_variables(app_name_var, app_var_property, app_var_notes)
VALUES(<cfqueryparam value="#app_name_var#" cfsqltype="cf_sql_varchar">,
<cfqueryparam value="#app_var_property#" cfsqltype="cf_sql_longvarchar">,
<cfqueryparam value="#app_var_notes#" cfsqltype="cf_sql_longvarchar">)
</cfquery>

<!--- Now lets set the Application Variable --->
<cfset "application.#app_name_var#" = "#app_var_property#">

</cftransaction>
</cflock>

 

<!--- If we are just updating, run this. --->
<cfelseif IsDefined('create_app_var') AND create_app_var EQ "Update Application Variable">

<cflock name="insertList" type="exclusive" timeout="30">
<cftransaction>
<cfquery name="qryPAge" datasource="#application.dsnodbc#" username="#application.dsnodbc_user#" password="#application.dsnodbc_password#">
UPDATE application_variables
SET app_name_var = <cfqueryparam value="#app_name_var#" cfsqltype="cf_sql_varchar">,
app_var_property = <cfqueryparam value="#app_var_property#" cfsqltype="cf_sql_longvarchar">,
app_var_notes = <cfqueryparam value="#app_var_notes#" cfsqltype="cf_sql_longvarchar">
WHERE app_id = <cfqueryparam value="#app_id#" cfsqltype="cf_sql_integer">
</cfquery>

<!--- Now lets reset the Application Variable --->
<cfset "application.#app_name_var#" = "#app_var_property#">

</cftransaction>
</cflock>

</cfif>

<!--- Check to see if we are editing a record. Grab App Var info. --->
<cfif IsDefined('app_id') AND NOT IsDefined('create_app_var')>
<cfquery name="GrabAppEdit" datasource="#application.dsnodbc#" username="#application.dsnodbc_user#" password="#application.dsnodbc_password#">
Select *
FROM application_variables
WHERE app_id = <cfqueryparam value="#app_id#" cfsqltype="cf_sql_integer">
</cfquery>
</cfif>

 

<!--- The form for creating and editing the application variables --->
<cfform name="frmCreateApp" id="frmCreateApp" method="post" action="#script_name#?#query_string#">
<div style="position: relative; float: left; width: 35%; clear:both;" align="right">Application Variable Name:</div>
<div style="position: relative; float: left; width: 60%;" align="left"><cfinput type="text" name="app_name_var" id="app_name_var" value="#GrabAppEdit.app_name_var#" size="30" maxlength="255" required="yes" message="Please Enter an Application Variable Name."> </div>

<div style="position: relative; float: left; width: 35%; clear:both;" align="right">Variable Property:</div>
<div style="position: relative; float: left; width: 60%;" align="left"><cftextarea name="app_var_property" rows="5" cols="50" required="yes" message="Please Enter an Application Variable Property."><cfoutput>#GrabAppEdit.app_var_property#</cfoutput></cftextarea> </div>

<div style="position: relative; float: left; width: 35%; clear:both;" align="right">Variable Description:</div>
<div style="position: relative; float: left; width: 60%;" align="left"><cftextarea name="app_var_notes" rows="5" cols="50" required="yes" message="Please Enter an Application Variable Description."><cfoutput>#GrabAppEdit.app_var_notes#</cfoutput></cftextarea> </div>

<div style="position:relative; width:100%; clear:both; text-align:center;" align="center">

<!--- Display the Update button or Create button. --->

<cfinput type="hidden" name="app_id" value="#GrabAppEdit.app_id#" />

<cfinput type="submit" name="create_app_var" id="submitButton" value="#IIf(GrabAppEdit.app_id IS ',DE('Create Application Variable'),DE('Update Application Variable'))#" />
<cfinput type="reset" name="reset" value="Reset" />
</div>
</cfform>

 

 

Ok a few things to note here. Hopefully I commented out the code enough so you understand what is going on.

If I'm editing an application variable I'm looking for a url variable or form variable "app_id", that variable comes from the management page that is below.

The next thing is a little trick you might not know. You can dynamically set variable names by quoting them out.

<cfset "application.#app_name_var#" = "#app_var_property#">

So for that code if the app_name_var is email and the property is email@email.com Coldfusion sees it as

<cfset application.email = "email@email.com">

Pretty cool ehy? You can also do this for regular variables.

 

Now that we have a form to create and edit the application variables lets get on to managing them (view, delete, edit, reset).

 

<!--- Check to see if we are deleting an App Variable--->
<cfif IsDefined('submit') AND submit EQ "delete" AND IsDefined('app_id')>
<!--- First lock the database --->
<cflock name="Delete_app_var" type="exclusive" timeout="30">
<cftransaction>

<!--- First lets grab the application variable info from the database just to make sure we are deleting the right one --->
<!--- We could delete by application variable name but just in case we have more than one with the same name, best to do it by ID --->
<cfquery name="getappvari" datasource="#application.dsnodbc#" username="#application.dsnodbc_user#" password="#application.dsnodbc_password#">
SELECT app_name_var
FROM application_variables
WHERE app_id = <cfqueryparam value="#app_id#" cfsqltype="cf_sql_integer">
</cfquery>

<!--- Delete App Variable from the application scope. --->
<cfoutput query="getappvari">
<CFSET tmp=StructDelete(application,getappvari.app_name_var)>
</cfoutput>

<!--- Now lets delete the record from the database --->
<cfquery name="qryPAge" datasource="#application.dsnodbc#" username="#application.dsnodbc_user#" password="#application.dsnodbc_password#">
DELETE FROM application_variables
WHERE app_id = <cfqueryparam value="#app_id#" cfsqltype="cf_sql_integer">
</cfquery>
</cftransaction>
</cflock>
</cfif>


<!--- Check to see if we are Setting/Refreshing an App Variable--->
<cfif IsDefined('submit') AND submit EQ "Set" AND IsDefined('app_id')>
<!--- First lets grab the application variable info from the database just to make sure we are setting the right one --->
<cfquery name="getappvari" datasource="#application.dsnodbc#" username="#application.dsnodbc_user#" password="#application.dsnodbc_password#">
SELECT app_name_var
FROM application_variables
WHERE app_id = <cfqueryparam value="#app_id#" cfsqltype="cf_sql_integer">
</cfquery>

<!--- Now lets reset the Application Variable --->
<cfset "application.#getappvari.app_name_var#" = "#getappvari.app_var_property#">
</cfif>


<!--- Select all application variables --->
<cfquery name="getAllApp_var" datasource="#application.dsnodbc#" username="#application.dsnodbc_user#" password="#application.dsnodbc_password#">
SELECT *
FROM application_variables
</cfquery>

<div style="position: relative; float: left; width: 15px;" align="left">ID</div>
<div style="position: relative; float: left; width: 150px;" align="left">Name</div>
<div style="position: relative; float: left; width: 150px;" align="left">Property</div>
<div style="position: relative; float: left; width: 250px;" align="left">Description</div>
<div style="position: relative; float: left; width: 40px;" align="left">Edit</div>
<div style="position: relative; float: left; width: 40px;" align="left">Set</div>
<div style="position: relative; float: left; width: 40px;" align="left">Delete</div>

<cfoutput query="getAllApp_var">
<div style="position: relative; float: left; width: 15px; clear:both;" align="left">#app_id#</div>
<div style="position: relative; float: left; width: 150px;" align="left">#app_name_var#</div>
<div style="position: relative; float: left; width: 150px;" align="left">#app_var_property#</div>
<div style="position: relative; float: left; width: 250px;" align="left">#app_var_notes#</div>
<div style="position: relative; float: left; width: 40px;" align="left">
<!--- Button to edit the Application variable. Posts to the edit page which I named "edit.cfm" (the edit page from above). --->
<cfform name="frmEditApp" id="frmEditApp" method="post" action="edit.cfm">
<cfinput type="hidden" name="app_id" value="#app_id#" />
<cfinput type="submit" name="Edit" id="Edit" value="Edit" />
</cfform>
</div>
<div style="position: relative; float: left; width: 40px;" align="left">
<!--- Button to edit the Application variable. Posts to the edit page which I named "edit.cfm" (the edit page from above). --->
<cfform name="frmSetApp" id="frmSetApp" method="post" action="#script_name#?#query_string#">
<cfinput type="hidden" name="app_id" value="#app_id#" />
<cfinput type="submit" name="Set" id="Set" value="Set" />
</cfform>
</div>
<div style="position: relative; float: left; width: 40px;" align="left">
<!--- Button used to delete the application variable. Posts back to this page. --->
<cfform name="frmDeleteApp" id="frmDeleteApp" method="post" action="#script_name#?#query_string#">
<cfinput type="hidden" name="app_id" value="#app_id#" />
<cfinput type="submit" name="delete" id="delete" value="Delete" />
</cfform>
</div>
</cfoutput>

 

Pretty simple and straight forward view/manage page.

 

Now lets talk about setting Application variables on the fly. This is for when the server restarts or the application restarts. Instead of manually resetting them we can let the code handle it. And just reset the application variables when they are not found.

 

There are two ways to do this so please choose the best way for your site.

The first way is if you aren't using a site wide error handler in your application.cfc file. So if you are still old schooling it and using application.cfm or what ever, this will probably be the best way for you.

This code has to be on all pages that might have application variables.

<!--- The page should be wrapped in a cftry. This cftry catches any errors and then checks the error to see if its an application variable error. --->
<cftry>

HTML CODE GOES HERE. HTML CODE GOES HERE. HTML CODE GOES HERE. HTML CODE GOES HERE. HTML CODE GOES HERE.
HTML CODE GOES HERE. HTML CODE GOES HERE. HTML CODE GOES HERE. HTML CODE GOES HERE. HTML CODE GOES HERE.
HTML CODE GOES HERE. HTML CODE GOES HERE. HTML CODE GOES HERE. HTML CODE GOES HERE. HTML CODE GOES HERE.

<!--- Check to see if error is an application variable. Catch type is any just in case we get other errors, might as well deal with them too. --->
<cfcatch type="any">
<!--- Wrap in another cftry just incase some thing doesn't set right. We can dump the user on an error page. --->
<cftry>

<!--- Query the database to see if the error is a missing application variable --->
<cfquery name="appVariables" datasource="#application.dsnodbc#" username="#application.dsnodbc_user#" password="#application.dsnodbc_password#">
SELECT var_property
FROM app_var
WHERE name_var = '#cfcatch.element#'
</cfquery>

<!--- If no variable shoot it down and throw the error page. --->
<cfif appVariables.recordcount EQ 0>
<cflocation url="error.cfm" addtoken="no">
<cfelse>
<!--- If we found an application variable. Set it and reload it. --->
<cfoutput query="appVariables">
<CFSET "application.#cfcatch.element#" = "#var_property#">
</cfoutput>
<cflocation url="#script_name#?#query_string#" addtoken="no">
</cfif>
<!--- If complete error. Throw user to an error page. --->
<cfcatch type="any">
<cflocation url="error.cfm" addtoken="no">
</cfcatch>
</cftry>

</cfcatch>
</cftry>

 

The second way is a bit more complex and requires you to know a bit about the application.cfc file. If you don't, read up about it, Ray Camden, Ben Nadel, and other have some excellent tutorials out there.

 

I'm not going to post my full Application.cfc file here. It goes beyond the scope of this tutorial. If you are familiar with the application.cfc file you will know what I'm talking about here.

This is just the OnRequest function of the application.cfc file.

<!--- Runs before request as well, after onRequestStart --->
<!---
WARNING!!!!! THE USE OF THIS METHOD WILL BREAK FLASH REMOTING, WEB SERVICES, AND AJAX CALLS.
DO NOT USE THIS METHOD UNLESS YOU KNOW THIS AND KNOW HOW TO WORK AROUND IT!
EXAMPLE: http://www.coldfusionjedi.com/index.cfm?mode=entry&entry=ED9D4058-E661-02E9-E70A41706CD89724
--->
<cffunction name="onRequest" returnType="void">
<cfargument name="thePage" type="string" required="true">

<!--- CFTRY to catch any errors on the page, we are looking for expression errors --->
<cftry>

<!--- Displays the actual page we are requesting --->
<cfinclude template="#arguments.thePage#">

<!--- Catch any variable errors --->
<cfcatch type="expression">

<!--- just in case lets look to see if cfcatch.element is defined, it will have the missing variable name --->
<cfif IsDefined('cfcatch.element')>
<!--- Lets check to see if the application variable in the database. --->
<cfquery name="AppError" datasource="#application.dsnodbc#" username="#application.dsnodbc_user#" password="#application.dsnodbc_password#">
SELECT app_name_var, app_var_property
FROM application_variables
WHERE app_name_var = '#cfcatch.element#'
</cfquery>

<!--- If the variable is in the database... --->
<cfif AppError.recordcount NEQ 0>
<!--- If variable. Set it and load requested page --->
<cfoutput query="AppError">
<CFSET "application.#cfcatch.element#" = "#app_var_property#">
</cfoutput>
<cfinclude template="#arguments.thePage#">

<!--- if not, throw error page --->
<cfelse>
<cfinclude template="error.cfm">
<cfabort>
</cfif>

<!--- If cfcatch.element isn't defined, send the user to the error page --->
<cfelse>
<cfinclude template="error.cfm">
<cfabort>
</cfif>

</cfcatch>
</cftry>

 

</cffunction>

 

Both examples are pretty simple concepts, wrap the page in a cftry tag, if error, then check to see if the error is caused by an application variable, if so reset it and display page, If not throw the user to an error page.

 

I also include the OnError function in my application.cfc just in case the are any other errors.

<!--- Runs on error --->
<cffunction name="onError" returnType="void" output="false">
<cfargument name="exception" required="true">
<cfargument name="eventname" type="string" required="true">
<cfinclude template="error.cfm">
<cfabort>
</cffunction>

If you try to catch the application variable errors in the OnError Function, it won't work. It will throw an error, "element is undefined in cfcatch". Its a second level error handler or doesn't directly access the cftry tag? or some thing like that. Not really sure.

But that's it. Good luck!

About This Tutorial
Author: Jeff Mendelsohn
Skill Level: Intermediate 
 
 
 
Platforms Tested: CFMX,CF8
Total Views: 97,351
Submission Date: December 01, 2009
Last Update Date: December 01, 2009
All Tutorials By This Autor: 3
Discuss This Tutorial
Advertisement

Sponsored By...
Mobile App Development (IOS, Android, Cordova, Phonegap, Objective-C, Java) - Austin, Texas Mobile Apps - Touch512, LLC.