The Custom Tag Body-Scope

I was working with FlexChart a little this evening and ran into an interesting situation with a potentially very useful solution. I don't claim to be the first to think of it, but it's the first time I've used/seen it.

I added a date preparation tag a while back, but I thought it'd be nicer to have a UDF that you could use instead, when you're building a descriptor inline. What I realized is that for very little effort, you can easily scope variables (UDFs or otherwise) to the body of a custom tag. Here's how it works:

<cfif thisTag.executionMode EQ "start">
  <cfset injectedPrepChartDate = false />
  <cfif NOT structKeyExists(caller, "prepChartDate")>
    <cfif NOT structKeyExists(variables, "prepChartDate")>
      <cfinclude template="udf_prepchartdate.cfm" />
    </cfif>
    <cfset caller["prepChartDate"] = prepChartDate />
    <cfset injectedPrepChartDate = true />
  </cfif>
<cfelse> <!--- end --->
  <cfif injectedPrepChartDate>
    <cfset structDelete(caller, "prepChartDate") />
  </cfif>
</cfif>

First, in the start tag, I (conditionally) add a prepChartDate UDF to the caller scope, and set a variable for whether I did it or not. Then, in the end tag, I delete the UDF if I'd added it to the caller. The part that I've greyed out is only needed because I'm using a UDF; it's a simple don't-double-define-a-function check. In this case, I'm opting to only expose the UDF if it won't conflict with what is already there in the caller scope. It'd be just as reasonable to shadow the pre-existing variable and restore it after the body. This latter approach is basically how Fusebox implements DO parameters, if you've ever used them, though it's mechanism is both far more elaborate and far more flexible.

I've obviously removed everything else from the tag definition. If you want to see the full implementation of xmlchart.cfm (where I used it), you can see it in Subversion (look near the bottom), and/or see it in action on the demo.

Comments are closed.