1<!---
2 WHAT IS THIS?
3 4 Railo support custom tags written as CFCs, providing more
5 flexibility than traditional CFM-based custom tag, and also
6 allowing a CFC to act as both a tag and an object.
7 8 ACF and OBD do not support CFC-based custom tags (yet?), so this
9 traditional custom tag will act as a proxy to a CFC of the same
10 name, calling appropriate functions to replicate the behaviour
11 of a CFC-based tag (not all features can be implemented).
12 13 For details on Railo's core implementation, see:
14 http://wiki.getrailo.org/wiki/3-2:CFC_based_Custom_Tags
15 16 For the latest version of this file, see:
17 https://gist.github.com/1003819
18 19 20 LICENSING:
21 22 This file may be licensed under the following licenses:
23 24 GPL v3 or any later version:
25 http://www.gnu.org/licenses/gpl-3.0.html
26 27 LGPL v2.1 or any later version:
28 http://www.opensource.org/licenses/lgpl-2.1.php
29 30 Apache License v2:
31 http://www.apache.org/licenses/LICENSE-2.0
32 33 It is hoped that whichever license used, any improvements to this
34 file are published, so that all CFML programmers can benefit.
35 36 37 NOT SUPPORTED:
38 39 * Parent tags
40 (not possible to implement?)
41 42 * Re-evaluating body
43 (return from onEndTag() is ignored; too much effort)
44 45 * Modification of ThisTag.GeneratedContent
46 (no known way to retrieve value from onEndTag?)
47 48 49 NOT YET IMPLEMENTED:
50 51 * Static Metadata validation
52 (should be possible, but not needed now).
53 54--->
55<cftry>
56 <cfswitch expression=#ThisTag.ExecutionMode#>
57 58 <cfcase value="START">
59 <cfset ThisTag.CfcName = ListLast(getCurrentTemplatePath(),'/\').replaceAll('\.cfm$','') />
60 <cfset ThisTag.Object = createObject('component',ThisTag.CfcName) />
61 62 <cfif StructKeyExists(ThisTag.Object,'init')>
63 <!--- No support for parent CFCs --->
64 <cfset ThisTag.Object.init( HasEndTag = ThisTag.HasEndTag ) />
65 </cfif>
66 67 <!--- TODO: Validate metadata --->
68 69 <cfif StructKeyExists(ThisTag.Object,'onStartTag')>
70 <cfset ThisTag.RunEndTag = ThisTag.Object.onStartTag
71 ( Attributes = Attributes
72 , Caller = Caller
73 ) />
74 <cfelse>
75 <cfset ThisTag.RunEndTag = ThisTag.HasEndTag />
76 </cfif>
77 78 <cfif (NOT ThisTag.HasEndTag) AND StructKeyExists(ThisTag.Object,'onFinally')>
79 <cfset ThisTag.Object.onFinally() />
80 </cfif>
81 </cfcase>
82 83 <cfcase value="END">
84 <cfif ThisTag.RunEndTag AND StructKeyExists(ThisTag.Object,'onEndTag')>
85 <cfset ThisTag.Object.onEndTag
86 ( Attributes = Attributes
87 , Caller = Caller
88 , GeneratedContent = ThisTag.GeneratedContent
89 ) />
90 <!--- TODO: Possible to obtain value from function? --->
91 <cfset ThisTag.GeneratedContent = '' />
92 </cfif>
93 <cfif StructKeyExists(ThisTag.Object,'onFinally')>
94 <cfset ThisTag.Object.onFinally() />
95 </cfif>
96 </cfcase>
97 98 </cfswitch>
99<cfcatch>
100 <!--- INFO: Don't output content on error. --->
101 <cfset ThisTag.GeneratedContent = '' />
102103 <cfif StructKeyExists(ThisTag,'Object')>
104105 <cfset ThisTag.ErrorRethrow =
106 StructKeyExists(ThisTag.Object,'onError')
107 AND ThisTag.Object.onError(cfcatch)
108 OR NOT StructKeyExists(ThisTag.Object,'onError')
109 />
110111 <cfif StructKeyExists(ThisTag.Object,'onFinally')>
112 <cfset ThisTag.Object.onFinally() />
113 </cfif>
114115 <cfif ThisTag.ErrorRethrow >
116 <cfrethrow />
117 </cfif>
118 <cfelse>
119 <cfrethrow />
120 </cfif>
121</cfcatch>
122</cftry>