我可以在cfscript中调用自定义标签吗?

9
例如,假设我有一个自定义标签,如<cf_AppSwitch action="Check">,我的假设是像AppSwitch(action="Check")这样的,但我不确定CF是否能将其解析为自定义标签。
我能想到的另一种解决方案是编写一个包装函数并调用我的自定义标签,但那感觉多余。
似乎我在过度简化一个更复杂的问题,因此任何见解都将不胜感激(即使是为什么不支持/不应该支持它)。
3个回答

12

更新2:

这里有一种更糟糕的方式。警告:以下是未记录的功能(但仍然很酷):

假设自定义标记返回如下值:

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

因此,标签的result属性需要一个变量名,该变量名将被设置为调用者。现在,通过以下方法,我们可以通过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>

更新:

下面的解决方案可能会导致意外的副作用。如果你的自定义标签返回一个值,由于标签是从组件中调用的,这个返回变量会被放入组件的变量作用域而不是调用模板的变量作用域中,因此您将无法访问它。当然,如果你要返回一个值,你应该考虑使用 CFC(如我上面所评论的)来代替自定义标签,所以请自行决定是否使用。

那么这种方法怎么样(改编自 Jake 的方法):

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>

冷加工.tagext.lang.ModuleTag ftw - Mike Causer
使用这种方法,您可以在cfscript中执行大量其他标记。 - Mike Causer

7

假设您使用的是Adobe CF,不幸的是答案是否定的。您必须编写一个基于CFML的包装函数。例如:

<cffunction name="myCustomTag">
  <cfset var returnVal = "">
  <cfsavecontent variable="returnVal"><cf_myCustomTag attributeCollection=arguments></cfsavecontent>
  <cfreturn returnVal>
</cffunction>

<cfscript>
 myCustomTag(a="b");
</cfscript>

如果您正在使用Railo,您可以使用 cfscript 相当于 <cfmodule> 标签:

<cfscript>
    module name="myCustomTag";
</cfscript>

谢谢Jake,正是我在寻找的东西。 - ryankeairns
3
有人认为标签适合用于UI相关的操作,而组件更适合用于建模和服务。因此很少有人需要这样做。 - Todd Sharp
@Todd Sharp 的观点很有道理。我正在使用 FW/1 重写一个应用程序,并且必须处理一堆已存在的自定义标签,这些标签被几个其他应用程序所使用...如果有足够的时间,我肯定会将它们重写为组件。 - ryankeairns

1

2021年更新:

最近版本的ColdFusion增强了cfscript支持,使您能够像调用函数一样调用自定义标签。

<cf_custtag att1="value1" att2="value2">

equates to

<cfscript>    
    cf_custtag(att1="value1", att2="value2");
</cfscript>

我没有找到一种原生的解决方案来嵌套自定义标签或获取生成的内容,因此我做了一个变通方法。
我使用一个名为“generatedContentOverride”的自定义属性将内容传递给自定义标签。
在自定义标签代码中,我查找该属性并将其用于替换thisTag.generatedContent。

谢谢发布这个内容!我测试过了,这个语法可以运行在 ColdFusion 2016 Update 17 及以上版本。它在这里被引用:https://helpx.adobe.com/coldfusion/cfml-reference/script-supported-tags-and-functions.html - James Moberg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接