Instantly share code, notes, and snippets.

What would you like to do?
Railo support custom tags written as CFCs, providing more
flexibility than traditional CFM-based custom tag, and also
allowing a CFC to act as both a tag and an object.
ACF and OBD do not support CFC-based custom tags (yet?), so this
traditional custom tag will act as a proxy to a CFC of the same
name, calling appropriate functions to replicate the behaviour
of a CFC-based tag (not all features can be implemented).
For details on Railo's core implementation, see:
For the latest version of this file, see:
This file may be licensed under the following licenses:
GPL v3 or any later version:
LGPL v2.1 or any later version:
Apache License v2:
It is hoped that whichever license used, any improvements to this
file are published, so that all CFML programmers can benefit.
* Parent tags
(not possible to implement?)
* Re-evaluating body
(return from onEndTag() is ignored; too much effort)
* Modification of ThisTag.GeneratedContent
(no known way to retrieve value from onEndTag?)
* Static Metadata validation
(should be possible, but not needed now).
<cfswitch expression=#ThisTag.ExecutionMode#>
<cfcase value="START">
<cfset ThisTag.CfcName = ListLast(getCurrentTemplatePath(),'/\').replaceAll('\.cfm$','') />
<cfset ThisTag.Object = createObject('component',ThisTag.CfcName) />
<cfif StructKeyExists(ThisTag.Object,'init')>
<!--- No support for parent CFCs --->
<cfset ThisTag.Object.init( HasEndTag = ThisTag.HasEndTag ) />
<!--- TODO: Validate metadata --->
<cfif StructKeyExists(ThisTag.Object,'onStartTag')>
<cfset ThisTag.RunEndTag = ThisTag.Object.onStartTag
( Attributes = Attributes
, Caller = Caller
) />
<cfset ThisTag.RunEndTag = ThisTag.HasEndTag />
<cfif (NOT ThisTag.HasEndTag) AND StructKeyExists(ThisTag.Object,'onFinally')>
<cfset ThisTag.Object.onFinally() />
<cfcase value="END">
<cfif ThisTag.RunEndTag AND StructKeyExists(ThisTag.Object,'onEndTag')>
<cfset ThisTag.Object.onEndTag
( Attributes = Attributes
, Caller = Caller
, GeneratedContent = ThisTag.GeneratedContent
) />
<!--- TODO: Possible to obtain value from function? --->
<cfset ThisTag.GeneratedContent = '' />
<cfif StructKeyExists(ThisTag.Object,'onFinally')>
<cfset ThisTag.Object.onFinally() />
<!--- INFO: Don't output content on error. --->
<cfset ThisTag.GeneratedContent = '' />
<cfif StructKeyExists(ThisTag,'Object')>
<cfset ThisTag.ErrorRethrow =
AND ThisTag.Object.onError(cfcatch)
OR NOT StructKeyExists(ThisTag.Object,'onError')
<cfif StructKeyExists(ThisTag.Object,'onFinally')>
<cfset ThisTag.Object.onFinally() />
<cfif ThisTag.ErrorRethrow >
<cfrethrow />
<cfrethrow />
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment