Skip to main content
Ben Nadel at cf.Objective() 2010 (Minneapolis, MN) with: Simon Free and Dan Wilson
Ben Nadel at cf.Objective() 2010 (Minneapolis, MN) with: Simon Free ( @simonfree ) Dan Wilson ( @DanWilson )

Determine The Parent ColdFusion Custom Tag Hierarchy Using GetBaseTagList()

By on
Tags:

Up until now, I have worked with ColdFusion custom tags that have a known parent; my cell has always been a child of the row, my row has always been a child of the table. But what happens if you want to build a slightly more dynamic tag that doesn't necessarily know what it's parent tag hierarchy is? Determining this hierarchy has been done loads before (which I am sure most of you know), but I have never done it, so I thought I would experiment.

You can use the GetBaseTagList() to get a comma delimited list of the current ColdFusion tag's parent tags. This list starts with the current tag (so it's a bit more than just a parent tag list, unless you consider the fact that all tags are parent to the actual method call). This function can be used outside of ColdFusion custom tags; it can be used anywhere in ColdFusion code. Running this:

<cfoutput>

	<!---
		Store the base tag list in content buffer variable.
		No need for this other than to create nested tags.
	--->
	<cfsavecontent variable="strTagList">
		#GetBaseTagList()#
	</cfsavecontent>

	<!--- Output tag list. --->
	#strTagList#

</cfoutput>

... gives us:

CFSAVECONTENT,CFOUTPUT

Notice that the GetBaseTagList() starts with CFSaveContent, the current tag, and then includes the parent tags (of which there is only one, CFOutput).

Of course, doing this outside of ColdFusion custom tags is not all that exciting. What this does show us though, is that GetBaseTagList() returns not just custom tags but all parent ColdFusion tags. Because of this, we have to be careful of its use in custom tags, especially when we only want a list of parent custom tags, not parent ColdFusion tags.

Here is a generic ColdFusion custom tag that will build an array of parent ColdFusion custom tags. Since GetBaseTagList() returns a bottom-up list of tags, the array that we generate below starts with the closest parent and then travels up to the originating parent tag.

<!---
	Check to see in which mode this tag is currently
	executing. Most of our actions will only apply to
	one of the two action modes.
--->
<cfswitch expression="#THISTAG.ExecutionMode#">

	<cfcase value="Start">

		<!---
			Convert the base tag list to an array so that we
			can more efficiently delete the tags that are NOT
			custom tags. The GetBaseTagList() function returns
			tag tag hierachy in an outward order, meaning
			the current tag is first with the parent tags
			after that.
		--->
		<cfset THISTAG.ParentTags = ListToArray(
			GetBaseTagList()
			) />

		<!---
			Loop over the parent tags and delete all the tags
			that are not ColdFusion custom tags. Be sure to
			delete the tags in reverse order so that you do
			not go out of bounds on the array.
		--->
		<cfloop
			index="intI"
			from="#ArrayLen( THISTAG.ParentTags )#"
			to="1"
			step="-1">

			<!---
				Check to see if this is a custom tag. All
				ColdFusion custom tags start with "cf_" even
				is that is not how they are being invoked in
				the code.
			--->
			<cfif (Left( THISTAG.ParentTags[ intI ], 3 ) NEQ "cf_")>

				<!--- Delete this standard tag. --->
				<cfset ArrayDeleteAt(
					THISTAG.ParentTags,
					intI
					) />

			</cfif>

		</cfloop>


		<!---
			At this point, we have cleared out all standard,
			non custom tags. This very first one in this array
			will be the current custom tag (remember, our tag
			list was in an outward direction). We don't need to
			keep track of this one so delete it.
		--->
		<cfset ArrayDeleteAt( THISTAG.ParentTags, 1 ) />

	</cfcase>

</cfswitch>

Notice that as a final step we are deleting the top item from the parent tag array. Again, this is because the GetBaseTagList() includes the current tag as well as all parent tags. This is a lot of work for a relatively simple idea. ColdFusion is very awesome and has been thought out very well; this makes me think that gathering parent tag data is not something that is advisable. Otherwise, I assume they would have built in something that accomplished this a bit more readily.

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

Reader Comments

2 Comments

This is one I've never run into before, but it's going to be very useful, even without using custom tags.

Working with a page that has multiple includes. The contents of those includes can be refreshed by ajax, at which point, they don't know that they're includes any longer, and some variables may need to be set since they're no longer inheriting them.

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