Reputation: 808
For example, if I have a custom tag like <cf_AppSwitch action="Check">
my assumption would be something like AppSwitch(action="Check")
, but I am not certain CF can resolve that as a custom tag.
The other solution I can think of would be to write a wrapper function and call my custom tag, but that feels redundant.
It seems like I am oversimplifying a much more complex problem, so any insight would be appreciated (even as to why this is not/should not be supported).
Upvotes: 9
Views: 6125
Reputation: 479
Update for 2021:
Recent versions of ColdFusion that have enhanced cfscript support will allow you to call a custom tag similar to a function.
<cf_custtag att1="value1" att2="value2">
equates to
<cfscript>
cf_custtag(att1="value1", att2="value2");
</cfscript>
I have not found a native solution to nesting custom tags or getting the generatedContent, so I made a workaround.
I pass content in to the custom tag using a custom attribute named "generatedContentOverride".
In the custom tag code, I look for that attribute and use it in place of thisTag.generatedContent.
Upvotes: 1
Reputation: 3355
Update 2:
Here's an even badder ass (or is it bad asser?) way. Warning: undocumented features below (but still cool):
Assume the custom tag returns a value like so:
<cfif thisTag.executionMode eq "start">
<cfparam name="attributes.name" default="Dude" />
<cfparam name="attributes.result" type="variablename" default="result" />
<cfset caller[attributes.result] = "Hello, " & attributes.name & "!!" />
</cfif>
So the result attribute of the tag expects a variable name that will be set into the caller. Now using the method below we can access that result via cfscript.
<cfscript>
test = createObject("java", "coldfusion.tagext.lang.ModuleTag");
test.setPageContext( getPageContext() );
test.setTemplatePath(expandPath('echo.cfm'));
test.setAttributeCollection({name="Todd Sharp", result="testResult"});
test.doStartTag();
test.doEndTag();
test.releaseTag();
writeDump(testResult);
</cfscript>
Update:
The solution below may cause an undesired side effect. If your custom tag returns a value you will not have access to it since the tag is called from the component the return variable gets put into the variables scope of the component, not the calling template. Of course, if you're returning a value you should probably be using a CFC anyways (as I commented above) so use at your own risk.
How about this approach (modified from Jake's):
CustomTagProxy.cfc:
<cfcomponent>
<cffunction name="onMissingMethod" output="false">
<cfargument name="missingMethodName" type="string"/>
<cfargument name="missingMethodArguments" type="struct"/>
<cfset var returnVal = "">
<cfsavecontent variable="returnVal"><cfmodule template="#arguments.missingMethodName#.cfm" attributecollection="#arguments.missingMethodArguments#" /></cfsavecontent>
<cfreturn returnVal>
</cffunction>
</cfcomponent>
echo.cfm:
<cfif thisTag.executionMode eq "start">
<cfparam name="attributes.name" default="Dude" />
<cfoutput>Hello, #attributes.name#!!</cfoutput>
</cfif>
time.cfm:
<cfif thisTag.executionMode eq "start">
<cfoutput>It is now #now()#.</cfoutput>
</cfif>
index.cfm:
<cfscript>
proxy = new CustomTagProxy();
echoTest = proxy.echo(name="Todd");
timeTest = proxy.time();
writeOutput(echoTest);
writeOutput("<br />");
writeOutput(timeTest);
</cfscript>
Upvotes: 12
Reputation: 16955
Assuming you are using Adobe CF, unfortunately the answer is no. You have to write a wrapper function that is CFML-based. For example:
<cffunction name="myCustomTag">
<cfset var returnVal = "">
<cfsavecontent variable="returnVal"><cf_myCustomTag attributeCollection=arguments></cfsavecontent>
<cfreturn returnVal>
</cffunction>
<cfscript>
myCustomTag(a="b");
</cfscript>
Now, if you are using Railo, you could use the cfscript equivalent to the <cfmodule>
tag:
<cfscript>
module name="myCustomTag";
</cfscript>
Upvotes: 7