Skip to main content
Ben Nadel at cf.Objective() 2009 (Minneapolis, MN) with: Ryan Vikander
Ben Nadel at cf.Objective() 2009 (Minneapolis, MN) with: Ryan Vikander

Strange Variable-Name Error When Writing To Base Tag In Adobe ColdFusion 2018

By
Published in Comments (2)

Yesterday, I posted an Adobe ColdFusion compatible version of my DSL for HTML emails. In that post, I listed getBaseTagData() as one of the compatibility issues between Lucee CFML and Adobe ColdFusion. It's actually a nuanced issue with several different stumbling blocks; one of which is a strange variable-name error that only gets thrown in Adobe ColdFusion. I figured I'd document that separate in case anyone ever ran into it.

A big part of my DSL (Domain Specific Language) for HTML emails is the communication between parent tags and child tags (which implement and inline cascading styles). As part of that communication, I store data into a shared memory space (shared with the developer). And so, as to reduce the likelihood of variable collisions, I use variable names that are very unlikely to be used by the developer.

For example, I might have a dynamically-generated variable name like:

$$entity:h1:small-title

In Lucee CFML, this variable name - when quoted - is totally fine. However, when I try to save this variable name into the parent tag in Adobe ColdFusion 2018:

<cfscript>

	parentTag = getBaseTagData( "cf_parent" );

	variableName = "$$entity:h1:small-title";
	parentTag[ variableName ] = true;

	writeDump( parentTag );

</cfscript>

... I get the following ColdFusion error:

The string $$entity:h1:small-title is not a valid ColdFusion variable name.

Valid variable names must start with a letter and can only contain letter, numbers, and underscores.

I assume this has to do with the fact that ColdFusion custom tags are a little bit magical in terms of how they relate to the "calling context". As such, I suspect that - at least in Adobe ColdFusion - the struct returned from getBaseTagData() isn't really just a struct, it's a "tunnel" into the context of the parent tag.

We've already covered a divergent behavior in caller scope assignment between Lucee CFML and Adobe ColdFusion. So, I assume this is a related issue.

To fix this call, we have to explicitly assign the value to the variables scope:

<cfscript>

	parentTag = getBaseTagData( "cf_parent" );

	variableName = "$$entity:h1:small-title";
	// NOTE: This time, I am explicitly referencing the VARIABLES scope in the parent
	// tag. I'm not relying on Adobe's magical handling of the parent tag context.
	parentTag.variables[ variableName ] = true;

	writeDump( parentTag );

</cfscript>

This time, by using parentTag.variables as my target, the code runs perfectly well in Adobe ColdFusion 2018.

Now, to be clear, this approach breaks Lucee CFML! If we were to run the same code in Lucee CFML, it would store the value into variables.variables, which is definitely not what we want.

ColdFusion custom tags aren't a hugely popular feature. Before writing my ColdFusion custom tag DSL for HTML emails, I probably hadn't touched them in a couple of years. So, it's not surprising that there are a number of compatibility issues between the two runtimes. It's just something to be aware of when you are coding.

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

Reader Comments

198 Comments

I wonder if this in another place where (the seldom used, at least I rarely use it), setVariable() might solve the issue. There seem to be a lot of weird differences in how ACF/Lucee handle scope assignment and setVariable() seems to behave consistently (at least in my findings) between the two.

Does this work across both?

setVariable('parentTag.' & variableName, true);

15,848 Comments

@Dan,

It's a good though. I did play around a bit with setVariable(), but the problem I think is that I can't use bracket-notation in the variable value. And, I can't use dot-notation since I have a key that has non-valid variable characters. So, I could probably get something working if I made the key a little more "variable friendly". Then, I think setVariable() might work.

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