Using ColdFusion Custom Tags To Create An HTML Email DSL In Lucee CFML 5.3.7.47, Part XIV
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_
:
<cfscript>
/**
* 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 );
}
</cfscript>
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.
Want to use code from this post? Check out the license.
Reader Comments