DIY Coder

© 2014. All rights reserved.

« Back

How I Create Custom CFML Tags


While I was cleaning up some code in a portal of ours, I realized that I could condense some of the code by combining a variable assignment with a custom tag attribute assignment.

To make things simple, the tag I am trying to optimize creates a database record with a note assigned to it.

1   <cfset notes="A ton of html code here.">
2   <cf_my_tag notes="#notes#">

The issue is that this code wouldn’t necessarily add a note in the same manner, every time. There might be times where I have to build the notes in a loop before I run the tag. Then there are times where I want to run the tag and NOT add a note. Also, I might want to define the note directly in the tag contents.

So here are the requirements for my new custom tag:

  1. The tag must be willing to accept an attribute named “notes”
  2. The tag must be willing to run without defining “notes”
  3. The tag must be willing to transform its contents into “notes”, if it is not empty.

With the above constraints in mind, here’s what I came up with.

 1 <!--- Content of my_tag.cfm --->
 2 <cfscript>
 3   param ATTRIBUTES.notes = "";
 4   if (ThisTag.hasEndTag) { // Closable Tag
 5     if (ThisTag.ExecutionMode EQ "start") {
 6       // ThisTag.GeneratedContent is not set yet.
 7     } else {
 8       // This is the best place to execute code
 9       // All possible 'ThisTag' variables are defined.
10       if (ThisTag.GeneratedContent NEQ '') {
11         // GeneratedContent takes priority over attribute
12         ATTRIBUTES.notes = ThisTag.GeneratedContent;
13       }
14       engage();
15     }
16   } else {
17     // Self-standing Custom Tag
18     engage();
19   }
20 </cfscript>
22 <cffunction name="engage">
23   <cfscript>
24     // Capture Generated Content
25     // (if we need to refer to the original content)
26     LOCAL.content = ThisTag.GeneratedContent;
28     // Prevent browser display of GeneratedContent
29     ThisTag.GeneratedContent = "";
30   </cfscript>
32   <!--- Do Stuff Here --->
33 </cffunction>

This setup fulfills all three requirements:

  1. I can refer to the ATTRIBUTES.notes variable to insert my note.
  2. I don’t need to define ATTRIBUTES.notes as it is param’ed at the top of the tag.
  3. If I have a closing tag with a non-empty string for its GeneratedContent, the ATTRIBUTES.notes variable will be overwritten with the GeneratedContent. This works for self-closing tags as well.
  4. It also allows me to place my logic into a single function rather than splitting it up in an if..else block.

So there you have it. A simple solution to create a custom tag with flexible closing tags.

Happy Coding!