Skip to main content
Ben Nadel
On User Experience (UX) Design, JavaScript, ColdFusion, Node.js, Life, and Love.

Using ColdFusion Custom Tags To Create An HTML Email DSL In Lucee CFML, Part XIV

By Ben Nadel on
Tags: ColdFusion

After months of incrementally building-out my ColdFusion custom tag DSL (Domain Specific Language) for HTML emails, I've started to apply this technique to the transactional emails at InVision! I'm totes excited about this, not only because I think it will bring a pleasant unity to the look-and-feel of our transactional emails, but also because it will put the DSL to the test in a real-world scenario. And, already, it's starting to flesh-out some issues. As I mentioned in earlier posts, I've stumbled over some unexpected behaviors with the getBaseTagList() function and the getBaseTagData() function in Lucee CFML; as such, I'm going to simplify the way I walk the parent-tag list in my DSL.

View this code in my ColdFusion Custom Tag Emails project on GitHub.

My ColdFusion custom tag DSL works as a cohesive unit. Meaning, individual tags don't work in isolation; instead, they work together, often referring to each other through the use of the getBaseTagData() function. This function exposes the variables of an ancestral custom tag, which can then act as a pseudo API for the descendant.

In earlier iterations of the DSL, I had special checks to exclude native ColdFusion custom tags like CFSaveContent, CFSilent, and CFTimer from the tag traversal because they don't actually expose tag-data. However, this is not future-proof as I would need to keep adding new tags to this list. Instead, I'm starting to exclude any ColdFusion custom tag whose tag-name does not start with cf_:


	* I split the given base-tag list, returning the array of tag-names.
	* @value I am the list of tags-names being split.
	public array function splitBaseTagList( required string value )
		cachedWithin = "request"

		var tagNames = listToArray( arguments.value ).filter(
			( tagName ) => {

				// Some ColdFusion custom tags appear to be implemented as pseudo-custom
				// tags that don't actually expose any state. As such, we have to omit
				// these internal tags from the list otherwise our getBaseTagData() calls
				// will blow-up.
				return( arguments.tagName.reFindNoCase( "^cf_" ) );


		return( tagNames );



Now, when I call splitBaseTagList( getBaseTagList() ), the DSL will automatically skip over any internal ColdFusion custom tags since none of them start with the cf_ prefix.

I'm very excited to see my ColdFusion custom tag DSL coming to fruition! I'm also looking to refactor a number of the functions, possibly moving them all up to the <core:Email> tag, treating it like an API that the rest of the tags can access (via getBaseTagData()); or, maybe just having an utilities.cfm file that I can include more globally.

Reader Comments

What has two thumbs and hopes you leave a comment? This Guy! (Ben Nadel).

Post A Comment

You — Get Out Of My Dreams, Get Into My Blog
Live in the Now
Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.