Skip to main content
Ben Nadel at CFCamp 2023 (Freising, Germany) with: Luis Majano and Michael Hnat
Ben Nadel at CFCamp 2023 (Freising, Germany) with: Luis Majano Michael Hnat

ColdFusion Custom Tags Can Have Privately Scoped Functions

By
Published in

In my previous post on the CF_SaveFile ColdFusion custom tag, my SaveFile.cfm template contained a private method named dedent(). Because ColdFusion custom tags execute in an isolated page context, all of the variables defined within the custom tag remain encapsulated within the custom tag boundary. The same is true for any functions defined within the custom tag. Which means, ColdFusion custom tags can have privately scoped helper functions.

This behavior isn't surprising once you understand how ColdFusion custom tags operate; but, it may not be obvious. And, I think it's worth calling it out specifically.

To demonstrate, I'm going to create a small custom tag (my-tag.cfm) that defines a function (myFunc()) and then invokes that function in order to setup a data variable:

<cfscript>

	data = myFunc();

	dump(
		label = "Custom Tag Variables",
		var = variables
	);

	// ------------------------------------------------------------------------------- //
	// ------------------------------------------------------------------------------- //

	/**
	* I'm a locally-scoped function, available only within the Custom Tag page context.
	*/
	private string function myFunc() {

		return "Defined in the custom tag.";

	}

</cfscript>

Aside: In the above code, I'm declaring the function as private because that feels like the correct intent. However, the code operates exactly the same if you declare the function as public (ie, it is still isolated to the custom tag execution context). private just feels more on brand for what I'm trying to accomplish.

As you can see, this ColdFusion custom is also performing a dump of its variables scope so that we can see how the custom tag page context interacts with the calling context. And, in this exploration, the calling context is also going to dump-out its variables scope:

<cfscript>

	data = "Defined in the index page.";

	module
		template = "./my-tag.cfm"
		input = "Hello World"
	;

	dump(
		label = "Root Page Variables",
		var = variables
	);

</cfscript>

Both the index.cfm page and the my-tag.cfm custom tag declare an unscoped data variable (which is implicitly stored in the variables scope of the current page context). Of course, since the custom tag is executing in an isolated context, the two data variables shouldn't collide. And, in fact, when we run this Lucee CFML code, we get the following output:

CFDump of the index page and the custom tag variables scope show isolated 'data' variables and a privately scoped function.

As you can see in the CFDump output, the two data variables remain isolated. And, in that same vein, the myFunc() function declared within the ColdFucion custom tag is only available from within the custom tag context—it doesn't leak out into the calling context.

In other words, ColdFusion custom tags can have private methods. This is perfect for when you need helper functions, but don't have the right mechanics for performing dependency injection (DI); and, you don't want to force the calling context to setup some application-scoped or request-scoped components.

Just another example of why ColdFusion custom tags are shockingly helpful!

Want to use code from this post? Check out the license.

Reader Comments

Post A Comment — I'd Love To Hear From You!

Post a Comment

I believe in love. I believe in compassion. I believe in human rights. I believe that we can afford to give more of these gifts to the world around us because it costs us nothing to be decent and kind and understanding. And, I want you to know that when you land on this site, you are accepted for who you are, no matter how you identify, what truths you live, or whatever kind of goofy shit makes you feel alive! Rock on with your bad self!
Ben Nadel