Session 12: Re-using code
The topic for this session is re-using code the aim of which is to make development less work extensive and applications to perform more efficiently. This aim is obtained by spending more resources and time on new tasks considered to be repetitive, and to organize the results in such a way that they can easily be used when needed for development of new applications. There are others important issues associated with this objective, which we cannot discuss in this course, among which are scaling and load-balancing,
Re-using code
ColdFusion approaches
When the programmed computers emerged in the 1940's, it was soon recognized that a large proportion of development time was in fact used for re-inventing and re-coding programs already prepared, but unfortunately not always taken well care of and made available or distributed. Program and routine libraries therefore became established, systematized, published and distributed. About 20 years later, the object-oriented programming took off, and class libraries were developed and assembled with extended possibilities for re-use.
ColdFusion MX includes a battery of approaches for facilitating systematic re-use of codes including:
- CFINCLUDE Tags
- Customs Tags
- User-Defined Functions
- CFX Tags
- Components
You have most likely already used the CFINCLUDE tag in your work and probably saved yourself for some repetitive work. By means of this tag you can include a template with a sequence of tags frequently used in other templates. One drawback is that you have to keep track of the address at which the tag to be included is located.
In this session, we discuss Custom Tags and User_Defined Functions . You are referred to RBB for information about CFX tags. Visit also Macromedia web site for additional information.
Components and Web services will be discussed in later sessions.
Custom Tags
ColdFusion includes almost 100 tags. ColdFusion also includes a feature, Custom Tags , CF_ tags, which permits users to define their own tags for operations or procedures frequently used. CF_ tags are easy to use , save the developer for re-writing the code for the specific operation, permit definition of attributes, can be stored in standard directories, and decrease the possibility for creating bugs in the tedious re-writing of code.
This session's application examples include a tailor-made logging of application use. Evaluating web applications requires observations and data. One type of data is log data reflecting the users' movements from one template to another during a visit to the web site and possibly for a sequence of visits. Log data can identify templates frequently visited by users, users' paths through the application, and the time spent by users at each template or sequence of templates. The purpose is usually to provide knowledge to developers for improving the applications.
Let us consider the following scenario: Imagine that milestones (important points in an application) in can be identified in an application. At each milestone, a log recording can be embedded. Recorded passings of each milestone will be data of the type required.
What should be recorded in connection with a milestone passing? There are at least 4 useful facts for any log record:
- ID for the user ( ID )
- Timestamp for passing the milestone ( TimeStamp )
- Name of current milestone passed( CurrentMilestone )
- Name of previous milestone ( PreviousMilestone )
A CF_ tag, which takes care of the recording of these 4 facts, can be defined by the following template , logmilestone.cfm :
- <!--- LogMilestone.cfm --->
- <cfset timestamp=Now()>
- <cfset id="#session.pin#">
- <cfset CurrentMileStone=#cgi.SCRIPT_NAME#>
- <cfif Not IsDefined('session.PreviousMilestone')>
- <cfset session.PreviousMilestone="">
- </cfif>
- <cfset milestonerecord="#id#, #timestamp#, #CurrentMilestone#, #session.PreviousMilestone#">
- <cfset session.PreviousMileStone=#CurrentMilestone#>
- <CFIF NOT FileExists('logrecords.htm')>
- <CFFILE ACTION="write" FILE="#session.path#\logrecords.htm" OUTPUT="<h3><font color=""Blue"">Milestone records</font></h3>">
- </CFIF>
- <CFFILE ACTION="append" FILE="#session.path#\logrecords.htm" OUTPUT="#milestonerecord# <p>" addnewline="yes">
Note that the above listing shows that this template is not different from a regular template. Lines 2-4 take care of generating 3 of the 4 variables wanted for the log recording. The value, #session.pin#, is assumed set when the users entered the application. The 4th variable, PreviousMilestone , does not exist if the recording is the first milestone of the current session. If so, Lines 5-7 defines the session.PreviousMilestone to be blank ("").
Line 8 composes a list called milestonerecord . Lines 10-12 test the existence of the file logrecords.htm . If the file does not exist , i.e. this is the first log recording, done, the template establishes the file. Finally, Line 13 appends the list milestonerecord as a record to the file logrecords.htm
The Custom Tag template can be saved in different places. A recommended rule is to save it in a pre-installed directory called CustomTags in a special directory, Customtags , within the general CFMX directory. However, frequently an ISP host does not permit its customers access to this directory. The most easy way is then to copy the tag template to the directory in which it is used. The tag template can be called from any template by the tag CF_LogMileStone .
The CustomTags have a number of properties, possible uses as well as restrictions. In this session, only the most elementary aspects are discussed. You are recommended to study Chapter 27 of RBB .
We use the guess example from Session 2 to illustrate application of the CF_LogMileStone tag. We assume that the display of the problem and the response from the system are the 2 interesting milestones in this application. In the present example, index.cfm template of session 2 is re-named as index_.cfm after the CF_LogMileStone tag is included at the top of the template:
- <!--- index_.cfm --->
- <cfset session.pin=#xxxx#>
- <CF_LogMilestone>
- <CFSET temp=randomize(second(Now()))>
- <CFSET session.target=#RandRange(50,100)#>
- <h2><font color="Red">Guess!</font></h2>
- <form action="response_.cfm">
- <cfoutput>
- <p>My name is <input type="text" name="name"></p>
- <p>I guess the sum of all integers from <b>1</b> to <b>#session.target#</b> is <input type="text" name="guess"></p>
- </cfoutput>
- <p><input type="submit" value="Submit"></p>
- </form>
In Line 2 we have to set some value for the session.pin. Similarly, the response.cfm template of session 2 is renamed as response_.cfm after the CF_LogMileStone tag is included:
- <!--- response_.cfm --->
- <CF_LogMileStone>
- <CFSET sum="0">
- <CFLOOP INDEX="count" FROM="1" TO="#session.target#" >
- <CFSET sum=#sum#+#count#>
- </cfloop>
- <CFIF #sum# EQ #guess#>
- <cfoutput>
- <h3><font color="Blue">#name#, your guess was correct!</font></h3>
- </cfoutput>
- <CFELSE>
- <cfoutput>
- <h3><font color="Red">Sorry, #name#, the sum is <b>#sum#</b>.</font></h3>
- </cfoutput>
- </cfif>
To make the example complete, a menu is need, and index.cfm is included:
- <!--- index.cfm --->
- <center>
- <h2><font color="#0000FF">Menu</font></h2>
- <p>Do you want to:</p>
- <table>
- <ul>
- <li><a href="index_.cfm">Run</a> the application</li>
- <li><a href="logrecords.htm">See </a>the log</li>
- </ul>
- </table>
- </center>
The options of Lines 7-8 make it possible to run the application several times and then and inspect the listing of the log file in which the milestone passings are recorded. The list displays all activities of the example applications and you will see recordings from other users before you entered the example. The list can easily be copied and processed for analytical purposes by for example MS Excel . With real id numbers, you will then be able to study how many times the individual user tests the example application before he/she gets bored, how long time is used in average to figure out an answer, etc.
User-Defined Functions
User-Defined Functions , UDF , is another feature which makes re-using code easier. Compared with Custom Tags , UDF can be an advantage if you have some data manipulation (calculations, string parsing, etc.) to be done in different applications. A UDF can either be coded by general CFML tags, or as a CFScript block.
In the Guess example, response_.cfm includes the calculation of all integers from 1 up to a certain number. If we develop applications in which this calculation frequently is required, we may decide to make it a UDF . We decide to use the CFScript keeping in mind that this approach cannot use CFML tags. The CFScript is also compatible with earlier versions of CF .
We create a UDF called sum_integers(number) with one argument, numbe r. The argument is the upper limit of the integer series.
- <!--- UDF_lib.cfm --->
- <!--- You can store as many UDF-functions as you like within the CFSCRIPT tags --->
- <CFSCRIPT>
- function sum_integers(number)
- {
- sum=0;
- for(index=1; index LTE number; index=index+1)
- {
- sum=sum+index;
- }
- return sum;
- }
- </CFSCRIPT>
Note that the CFSCRIPT block comprises all statements in the template, in this case all statements in the single function included.
UDF libraries
A function can be saved in the same template it is used. Obviously, when you need to use the function more than once, a better solution is required. An effective approach is to collect all your functions in a library template, which you name UDF_lib.cfm . If you add an include tag, <CFINCLUDE template="UDF_lib.cfm"> , in your Application.cfm , all functions in your library will be available for all templates in your application.
Above, we have stored the function sum_integers(number) including the CFSCRIPT tags in the file called UDF_lib.cfm , and illustrate by the template index.cfm how we can make use of the library and its functions:
- <!---index.cfm --->
- < cfinclude template="udf_lib.cfm">
- < center>
- < Cfif IsDefined('number')>
- < cfoutput>
- < font color="blue"><h2>The sum is <b>#sum_integers(number)#</b></h2></font>
< /cfoutput>- <cfelse>
- < h2><font color="blue">Sum function</font></h2>
- < cfform action="index.cfm" method="post" enablecab="yes">
- < p>I want the sum of all integers from 1 to
- < cfinput name="number" required="yes" type="text">
- < input type="submit" value="Submit">
< /cfform>
- < /Cfif>
- </center>
Note that we have included the CFINCLUDE tag in this file, since we have not shown the Application.cfm for this application.
CFX Tags
CFX tags are tags prepared in a foreign language and compiled to a .dll or .class file. This opens for preparing very effective tailor made tags. In this course, however, we shall only take note of this possibility without exploring it further.
Exercises
a. You are encouraged to copy and try out the examples for yourself. Achallenging task will be to work out how a component can be called by means of the CFOBJECT tag.
b. Review your project templates and identify code sequences which you have used repetitively. Transform these sequences to Custom Tags , and evaluate what you gained in your project, and if you can benefit from your Custom Tags in future applications.
c. The experts recommend that you code your UDF based on tags . Re-write the UDF script-based function sum_integers(number) as a tag-based UDF and test it.
d. RBB discusses Function Libraries in Chapter 20. Read the chapter carefully. He refers to an open source repository named the Common Function Library Project . Import the library and see if you find any interesting and useful functions for your project in the library.
e. There are many ways of constructing and using components. RBB discusses some of them in Chapter 22. Components build on UDF is discussed in detail in RBB Chapter 20. You are recommended to read this chapter, and try pout some of the suggestions.
f. Consider how you would reorganize your own project if you should have implemented it by means of components.
e. You are welcome to study the wsdl of as well as and invoke the webservice: http://nordbotten.ifi.uib.no/webservices/access_webservice.cfc?wsdl called from an application on your own computer.
Link to the session examples.
Link to the session test.
Reusing Code in ColdFusion Pages
This chapter describes techniques for reusing code in ColdFusion pages. These techniques let you write your code once and use it, without copying it, in many places. This chapter describes the techniques and their features, and provides advice on selecting among the techniques.
Contents
CFML elements Including pages with the cfinclude tag
Calling user-defined functions Using custom
Selecting among ColdFusion code reuse methods
Steve McKean
UH-Email
CT FORUM CF
user - enter
Steve McKean
UH-Email
CT FORUM CF
user - enter
CFMX HISTORY RESOURCES
OBJECTIVES
Implementation aspects: