When to use cfscript and when not to

Would appreciate some insight on this topic.

That really does depend on who you ask. Best practice these days suggests using script everywhere except where tags are necessary, such as in views. These days the apps I write are probably 90-95% script with a smattering of tags where needed in views… though I’m moving away from that as well and starting to build views that rely on ajax calls to get their data (moving towards serverless) so the answer, for me, is everywhere you can.

Others would argue tags have a place outside of views… such as using cfquery tags vs queryExecute() script. I, for one, have zero issues reading and writing queries with script… others find it… cumbersome. So it somewhat falls to personal preference.

HTH

– Denny

2 Likes

Thanks Denny

I’ve really haven’t much more to add to what @ddspringle already said. If you google for “cfscript vs cftags” you’ll find tons of some (sometimes a little heated) discussions about ‘why to’, ‘why not to’, ‘when to’ and ‘when not to’ use the one or another. Some answers might feel political or even a religious point of view. However…

Being more a cftaggy guy, I’ve learnt and adhered to cfscript in the recent years, and in my opinion this was a little bit too late. It’s really not that complicated to write cftags as cfscript because with almost all cftags you just need to ommit the <cf , put the attributes into brackets and set the body content (if the cftag has a body) into curly brackets. In my opinion this is the strenght of CFML, because it gives you the ability of separation of the “html outputting” stuff from the “logic programming” stuff just in the degree you need or want. Thus it’s extremly versatile. You define it!!!

What I do with preference nowadays is: use cftags when I have to mix html markup with dynamic stuff instead of lots of writeOutput-ting lines. And I also like to use <cfquery> in tag islands, because it makes SQL queries more readable in my very personal opinion. But(!!!) you still can use and stick to QueryExecute(sql,params,options) in cfscript like others do/ or like.

What I see more as a challange to myself is: undestanding how organize components well, give them good understandable names, not to create GOD objects, give good function names wire up everything together in a logical understandable way, define good naming conventions and keep up with them so that it documents itself.

2 Likes

Thank you @andreas I totally follow you including sentiment.

Regarding

would love to see some cases. Much appreciated.

Thanks to open source you can take a peek into source code of very interessting stuff. If you want to see what my personal goal of skills in cfml development is, then take a deeper look into coldboxes contentbox. It’s a CMS framework built on top of coldbox. Look into the source and see how it’s built. Really, I mean really cool stuff.

Also, see this:
https://modern-cfml.ortusbooks.com/

And look into Lucee’s source code how they programm the whole cfengine combining Java and CFML. Everything is of such an imense value to have it publicly available! These are my books of today. My bad I’m not that much of a dev pro to understand everything they do, but getting better day by day :smiley:

1 Like

Thanks @andreas

I just want to +1 on the concept of Tag Islands. I’ve been using those for the last few months, and it’s allowed me to start writing my “data access objects” in CFScript, where I just throw the CFQuery tag in a tag island. It’s the best of both worlds. Consider a DAO method like this:

component output = false {

	// ... other methods.

	public query function getSomeData(
		required numeric userID,
		string filter = ""
		) {

		```
		<cfquery name="local.results">
			/* DEBUG: myGateway.getSomeData(). */
			SELECT
				f.id,
				f.name
			FROM
				foo f
			WHERE
				f.user = <cfqueryparam value="#userID#" sqltype="integer" />

			<cfif filter.len()>
				AND
					f.name LIKE <cfqueryparam value="%#filter#%" sqltype="varchar" />
			</cfif>
		</cfquery>
		```

		return( results );

	}

	// ... other methods.

}

Honestly, this has been a game changer for me! It’s really the best of all possible worlds.

4 Likes

I was a major holdout on using CFTags. Then I was forced to switch to cfscript due to a job requirement. Now I use cfscript as much as possible. Use which ever one you are comfortable using.
On writing queries in cfscript I use this format. It is very close to the cfquery tag and give you the ability to dump the qry variable if needed.

var qry = {};
qry['Options'] = { 'datasource':DSN, 'result':'out' };
qry['Params']  = {
	'data': { cfsqltype="timestamp", value=value }
};
qry['SQL'] = '
	SELECT *
	FROM table
	WHERE field = :data
';

var qTemp = queryExecute( qry.SQL, qry.Params, qry.Options );
1 Like

That is great! Thanks for sharing. I’ve got a question on this. I’d like to know how would you do a dynamic “where”-condition look like, also select fieldnames with variations, “if-else” conditions, multiple “Order By” switches, with DESC/INC switches etc. All to be done in one SQL-command. Do you have an example? A select * from table where userid=1234 is a little bit too simple to rewrite as cfscript. maybe my scripting skills are simply too poor to do it in a good readable way.

When defining the SQL it is just text. You can handle it just like you would in cfquery. Any values can be inline or passed in. The passed in values will happen on the SQL server.

var qry = {};
qry['Options'] = { 'datasource':DSN, 'result':'out' };
qry['Params']  = {
	'data': { 'cfsqltype':'timestamp', 'value':value }
};
qry['SQL'] = '
	SELECT *
	FROM table
	WHERE field = :data
';

if( condition ){
	qry['Params']['list'] = { 'cfsqltype':'varchar', 'value':IDs, 'list':true };
	qry['SQL'] &= 'AND id IN ( :list )';
}

var qTemp = queryExecute( qry.SQL, qry.Params, qry.Options );

It is all just structs and text until you hit the queryExecute() command.

Here is another method that came to mind using 3 variables for SQL, Params & Options;

var Options = { 'datasource':DSN, 'result':'out' };
var Params  = {};
Params['data'] = { 'cfsqltype':'timestamp', 'value':value };

var SQL = [];
SQL.append(	"SELECT *" );
SQL.append(	"FROM table" );
SQL.append(	"WHERE field = :data" );

if( condition ){
	Params['list'] = { 'cfsqltype':'varchar', 'value':IDs, 'list':true };
	SQL.append(	"AND id IN ( :list )" );
}

var qTemp = queryExecute( SQL.toList( " " ), Params, Options );
1 Like