Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I call a custom tag in cfscript?

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).

like image 932
ryankeairns Avatar asked Feb 09 '12 17:02

ryankeairns


People also ask

What is custom tag in ColdFusion?

A custom tag is a series of ColdFusion tags combined into one tag and called in a similar manner to normal ColdFusion tags. For example, you can create a page called script. cfm and then within your code can call this as cf_script.

What is the use of c f tag?

Usage. Performs processing in CFScript. This tag uses ColdFusion functions, expressions, and operators. You can read and write ColdFusion variables within this tag.


3 Answers

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>
like image 91
Todd Sharp Avatar answered Oct 06 '22 05:10

Todd Sharp


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.

like image 44
Michael Dawson Avatar answered Oct 06 '22 06:10

Michael Dawson


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>
like image 39
Jake Feasel Avatar answered Oct 06 '22 07:10

Jake Feasel