The last ThisTag variable AssocAttribs brings up a whole new feature of custom tags in ColdFusion 4 and later versions. Not only can you use end tags in your development but you can also wrap custom tags with other custom tags. By itself this is not a big deal. But by using Assocxttribs the CFA5S0CIATE tag and the new ColdFusion functions GetBaseTagL i st and GetBaseTagOata you can create custom tags that can communicate with other tags that are wrapping them. If you have ever used HTML blesyou have already seen a good example of tags wrapping tags:
In this example, the TOtags are wrapped by TRtags, which are wrapped by TABLE
tags. The TOtags communicate to the TRtags, which in turn communicate to the toplevel
TABLEtags. The browser uses thiscombination of tags to create a table.
Since ColdFusion 4, custom tags can now send data to their parent tags, or grab data
from their parents, including a list of who their parents a~e. So, for example, say you had
the following code:
The CF_50n tag would not only be able to share its data with CF_Father, but would also be able find out whether it has a Father and GrandPa, and if so, take the data from them
As you can see already, these new features allow for very complex tag integration. Let’sstart simply and work with an example that shows child tags sending information to their parents. Listings 31.11, 31.12, and 31.13 contain the code you will be using for the examples .
Tests intertag communication.
February 13, 2000
<CFPARAM NAME-‘Attributes.Name’ DEFAULT-‘Nameless’>
<CFPARAM NAME-‘Attributes.Age’ DEFAULT-‘#RandRange(l,lOO)#’>
<CFOUTPUT><FONT COLOR=’##008800′>I am a Child tag and my name is #Attributes.NAME#.
I am #Attributes.AGE# years old.</FONT></CFOUTPUT>
<!— Check to make sure I have a parent. —>
<CFSET Ancestors – GetBaseTagList(»
<CFOUTPUT><FONT COLOR-‘##008800’>I have a parent!</FONT><P></CFOUTPUT>
<CFOUTPUT><FONT COLOR-‘##OOS800’)I am an orphan. :«/FONT><P></CFOUTPUT>
Begin by looking at Child. cfm, the innermost tag. You start with two CFPARAM statemerits. One creates a Name attribute for the child and the other creates a random age. Both these default values can be overwritten if you pass in a Name or Age attribute. In Listing 31.11 you specify a name for the first two times you call Chi 1d . cfm and no attributes for the last instance. Your next step is to output some basic information. This is mainly so you can see the tag in action on the Web page .
The next line, <CFSET Ancestors – GetBaseTagL; stC»,·is our first example of tag interaction. The function GetBaseTagL; st returns a list of tags that are wrapping your .tag. It is important to remember two facts: First, if the tag is contained with a CFIF tag, the CFIF will show up on the list. Second, the tag itself will show up on the list as well. In this case, this shouldn’t bother you. As you can see in the next line Case(Ancestors. CF_Parent n », all you need to Care about is whether you are wrapped by a tag called CF_Pa rent. If you are, you output a simple message stating so
The important part is the line after the output. The CFASSOCIATEtag is what tells Cold-Fusion to associate your data with the parent tag. CFASSOCIATEtakes two arguments: the name of the base tag to share data with, and DATACQLLEGIONw,hich you did not use. In our example you tell Coldf’usien to share your data with CF_PARENT.By default, CFASSOCIATEshares data with parent tags in a structure called Assocat tr-i bs. Youwill see this structure. when we talk about Parent. cfm. If you wanted to specify a name different from AssocAttri bs, you would use DATACOLLEGIONto specify the new name. Why would you use this? Well, imagine if the CF_PARENTtag contained both CF_CHILD tags and CF~PETtags. You would probably want the different tags to create different structures in CF_PARENT
After the CFASSOCIATEtag, all you have left is the other clause of the CFIF statement. You use it to simply output the fact that you are not wrapped within it CF_PARENTtag. You could use it to throw an error condition. ‘Ibis would be useful for custom tags that are not meant to be used alone. For example, if y<>uwere building a ColdFusion version of the TABLE,TR,and TOtags, you may want to ensure that TOis never used outside of a TRor TABLEtag.
Now let’s take a look at Parent. cfm in Listing 31.12. The tag begins with a CFSWITCH statement. Our custom tag is being used with an end tag so you want to have a clause for both the beginning (ThisTag. Executi onMode – ‘Start ‘) and end (This Tag. Execution Mode m End’) of the tag. If the current execution mode is I Start you simply output a message stating so. Again, this would not usually be necessary. In this & se it provides some visual feedback for the examples.
The next clause is important. In this case, you know you are at the end of the tag. To check whether you have children, you check to see if This Tag .Assoc Attribs has been defined. Remember that in Chi 1d. cfm, you. used CFASSOCIATEto send data to your parentand because you did not specify a OATACOLLEGI ON attribute by-default the server used the name Assoc Attribs. If it is defined, then, you know you have children. Now here comes a tricky part. Pay special attention to these two lines:
Remember when we said that information passed from a tag is saved in AssocAttri bs? . Well, if you think about it, this could cause a problem if AssocAttri bs was a simple structure; In our example, you have two children. If AssocAttri bs was only a structure, the second child’s information would overwrite the first one’s ..To get around that whM data is passed from child tags, the server creates Assoc Attri bs as an array of structures. $0, you can first check the length of that array to determine how man}l children you have. Then, you can then loop through each structure by using the CFU)() Pcommand to run from the “l” to ‘#ArrayLen(Thi sTag .AssocAttribs)#”. Because you are dealing with an array, to output the information you need to use both array and structure syntax. Here are the lines to output:
Child lXI’s name is IThisTag.AssocAttribs[X].NameI<BR>
Child lXI’s age is #ThisTag.AssocAttribs[X].Age#
Notice the reference to ThisTag. AssocAtt ri bs [X] (remember you are in a loop). this ensures that you get the proper array element. Because the value of the array element is a structure you can use the dot notation to refer to the value of that particular key. You could have also written this as
Child lXI’s name is IThisTag.AssocAttribs[X][‘Name’]I<BR>
– Child lXI’s age is IThisTag.AssocAttribs[Xl[‘Age’]’
Both examples are valid.but the first one is a bit simpler to read. The CFLOOPdisplays information about each child, as you saw in Figure 31.3. If for some reason no child tags sent information back to the parent, we output a message stating so. This is present in the ELSEclause of our CFIF that checks to see if Thi sTag .AssoeAttri bs is defined.
That wraps up our discussion of one-way tag communication. As a final note examine how the child reacts when it ~ called outjide of the parent. The last line of Tag Convnunication Test. efm has an example of this. As we said earlier it may be a good idea for your tag code to prevent such things from happening. The choice is up to you!