Re-factoring CFML Applications, Part 4- From Tags to Script

In the first three parts of this series on re-factoring CFML applications, I covered the general concepts around re-factoring and laid out a set of plans for how you can go about re-factoring your application piece by piece. From here out, the remainder of this series will focus on specific techniques for moving old CFML code into your new FW/1 application, and how you might take advantage of specific features of FW/1 in the new application. In part 4, I will focus on a big element of re-factoring your CFML application - migrating your tag-based CFML code to script.

CFML was originally a tag-based programming language. Scripting was added a few years later, and over time scripting became the best way to write CFML. (OK, so I don’t really recommend using script in view code, but I don’t recommend putting anything other than what is needed for your display in view code. ) Unfortunately, a lot of old code still exists that primarily uses tag-based CFML. Re-factoring is the perfect time to get rid of those old tasks and streamline your code. Eliminating tags will reduce your character count for your code by a significant margin, and it makes your code easier to read. Since the query tag was converted into script in its current form, there has been no real reason in my mind to use tags outside of display code.

Stripping Tags Programmatically

FW/1 uses components for everything except layouts and views, so you will need to learn how script-based components work. I will not go into details about components, you can find ample documentation on component in CFML online. Let’s look at how specific code might be converted. Let’s take a block of application logic in tags and convert it to script.


<cfif myquery.min LT 10>
	<cfset min_E = 1>
	<cfset min_text = "Minimal">
<cfelseif myquery.min GT 100>
	<cfset min_E = 3>
	<cfset min_text = "Max">
<cfelse>
	<cfset min_E = 2>
	<cfset min_text = "Middle">
</cfif>

Let’s convert it to script using regex. Here is a simple regex for the cfif statement.

find: <cfif([^>|\r]+)>

replace: if( $1 ){

And cfelseif:

find: <cfelseif ([^>]+)>

replace:}else if( $1 ){

cfelse is just a normal replace:

find: <cfelse>

replace: }else{

And how about the cfset code:

find: <cfset ([^>]+)>

replace: $1;

And don’t forget to replace </cfif>, also a normal replace:

find: </cfif>

replace: }

It might not save you much time in this little block of code, but in a big tag block, it will save you a lot of time.

Another nice one, cfparam:

find: <cfparam ([^>]+)>

replace: param $1;

And for catching those stray tag endings these expressions missed:

find: >\n

replace:;\n

Regex is exceptionally useful, and this stuff is just scratching the surface of what you can do. If you find yourself staring at a large block of application logic that you need to convert, you will be happy to have regex in your toolbox. These expressions work in VSCode, your mileage may vary in other IDEs or text editors.

Converting Queries to Script

Tag-based queries are great. It was one of the things that made CFML stand out in the early days of Web programming. Drop in your SQL code block, add some variables, and go. Good IDEs even color-code the SQL code. Beautiful. Along the way, CFML added script-based queries in a very fluid way that is very similar to the functionality of tag-based queries. Going forward, you should really only be using script-based queries in your code. Let’s look at an example. First, the tag-based query:

<cfquery name="getTasks" datasource="mydsn">
	SELECT 	task, taskID, dateCreated, isComplete
	FROM 	tasks 
	WHERE	userID = <cfqueryparam cfsqltype="cf_sql_integer" value="#url.userID#"/>
</cfquery>

Now in script:

function getTasks( userID ){
		return queryExecute(
				sql: 	"SELECT task, taskID, dateCreated, isComplete
						FROM 	tasks 
						WHERE	userID = :userID",
				params: {userID: { CFSQLType: 'cf_sql_integer', value: arguments.userID }},
				options: { datasource: "mydsn" }
		);
	}

Now granted, this isn’t an exact comparison because the script-based query has been moved into a function, but putting that aside, you can see that the code is quite similar. What you can take from this code is that converting a tag-based query to script is easy. Just use this example as a template and plug in what you need. Note that you can use a variable for the sql statement, which makes it easy to build dynamic SQL strings if you need them.

Views- Is There Anything to Convert?

In general, you are not going to convert tags in your view code into script. The exception is where you need to move application logic out of the view code into your controller code. In that case, yes, convert to script. Otherwise, tags belong in .cfm files, and that’s OK.

Other Areas of Consideration

There are a lot of tags in CFML that do all kinds of useful things. There are script analogs in CFML, and converting from tags to script is usually just a matter of finding the specific syntax for the tags you are looking to convert. Some things, like file functions, have multiple script commands that correspond to a single tag like CFFILE. Take time to look through CFML documentation to familiarize yourself with things you will need to convert in your application.