1

我正在尝试将coldfusion代码存储在用于cfmail主题的数据库中。存储的代码如下:

"RE: <cfif myData.general.legalName NEQ """">  {{dotlegalname}}<cfelse>{{docketLegalName}}</cfif>,    
DOT## {{dot}}, Docket ##(s)   {{docketString}}" 

当我从数据库中检索字符串时,我使用 cfsavecontent 来尝试评估它。

<cfsavecontent variable="subject">
 <cfoutput>#myData.email.subject#</cfoutput>
</cfsavecontent>

我也试过

<cfsavecontent variable="subject">
     <cfoutput>#evaluate(myData.email.subject)#</cfoutput>
</cfsavecontent>

然后我将所有 {{ }} 替换为适当的值。

但是,电子邮件的主题顽固地拒绝包含已评估的 cfif,而是将 cfif 显示为字符串。

有任何想法吗?

4

10 回答 10

4

动态评估您在运行时创建的代码的唯一方法是将其写入文件,然后执行它。

最简单的方法是将其写入虚拟文件系统中的 .cfm 页面(可能以 UUID 命名文件,因此它是唯一的),然后在您需要运行内容的地方。

我通常不会提倡像这样在运行时生成代码,但在某些情况下它可能是最优雅的解决方案。

作为替代方案,您可以将一组 CFML 电子邮件模板文件存储在服务器上的目录中,而不是将 CFML 代码存储在数据库中,在您的数据库中,您只需通过 cfinclude 或cf模块。

于 2010-12-20T22:07:04.830 回答
3

如果不先将其写入文件然后使用<cfinclude>包含它,则无法动态评估存储在数据库中的 CFML。

于 2010-12-20T22:04:29.453 回答
3

除了马克的回答,这里还有一些伪代码:

<cfset fileName = createUUID() & ".cfm">
<cfset fileWrite( fileName, [CODE_FROM_DB]>
<cfinclude template="#fileName#">
<cfset fileDelete( fileName )>

我以前使用过这样的代码,没有任何问题。虚拟文件系统中的任何东西都在 RAM 中运行,因此可以飞。为了获得最佳实践,请记住删除创建的文件;)

于 2010-12-21T04:01:50.803 回答
2

如果您绝对必须这样做,请查看 evaluate() 函数。本质上,这会启动一个新的 CF 线程,编译传递给它的字符串,运行它并返回结果。

如果可能的话,我会尝试找到一种方法将您的逻辑移动到正在运行的实际文件,而不是数据库中的字符串。我假设您正在根据已经构建的一些字符串提取数据,因此您可能会考虑在其上附加一些内容,因此您正在查找 subjectDotLegal 和 subjectDocketLegal 或类似的东西。

请记住,evaluate() 很慢、很丑陋,而且可能很危险(它会运行任何传递给它的东西!)。如果有办法解决它,我建议你使用它。

于 2010-12-20T22:27:10.623 回答
2

为什么不直接使用小胡子之类的东西呢?

http://mustache.github.com/ https://github.com/pmcelhaney/Mustache.cfc

它不仅能够动态地在脚本中执行一些您想要的逻辑。我真的建议你检查一下这个项目,甚至可以改进它并做出贡献。

哦,只是为了有机会成为肥皂盒:多年来,我一直在给 Adob​​e 发送电子邮件,说我们需要动态解析和呈现 CFML 的能力。可悲的是,我的哭声只是被忽视了。也许如果更多的人抱怨需要添加此功能,它会得到应有的关注。

于 2011-09-30T19:47:19.237 回答
0

举个例子:假设code.txt是一个包含以下内容的文本文件(只是为了方便模拟存储在db中的CFML):<cfoutput>#now()#</cfoutput>

以下代码将起作用:

<cfset q = queryNew("code") />
<cfset queryAddRow(q,1) />
<cfset querySetCell(q, "code", fileRead(expandPath('code.txt')), 1) />
<cfdump var="#q#">
<cfset newCodeFile = expandPath('dynamic.cfm') />
<cfset fileWrite(newCodeFile, q.code[1]) />
<cfinclude template="dynamic.cfm" />
于 2010-12-20T22:12:10.800 回答
0

OpenBlueDragon中有渲染函数,它可以做到这一点。

您可以在 Railo 中通过创建自定义内置函数来模仿此函数,该函数将文件保存到 RAM 中,然后 cfinclude 使用以下代码:

<cffunction name="render" output="Yes" returntype="string"><!--- 
       ---><cfargument name="Code" required="Yes" type="string"><!--- 
       ---><cfset local.mapping = {'/render_ram_resource':'ram://'}><!--- 
       ---><cfapplication action="update" mappings="#local.mapping#"><!--- 
       ---><cfset local.fileName = "/render_ram_resource/_render_" & 
createUUID() & ".cfm"><!--- 
       ---><cffile action="WRITE" file="#fileName#" 
output="#arguments.Code#"><!--- 
       ---><cfinclude template="#fileName#"><!--- 
       ---><cffile action="DELETE" file="#fileName#"><!--- 
---></cffunction> 

(这看起来很不寻常,因为它需要允许输出,但要防止额外的空格,因此为什么会出现所有注释。不幸的是,SO 的语法突出显示似乎被他们混淆了。)

如果您需要兼容 ACF 的解决方案,则需要使用常规文件系统和预先创建的映射。(好吧,在 ACF9 及更高版本中,您可以使用 RAM 虚拟文件系统,但是您不能像这样动态创建映射。)

于 2011-09-30T18:09:52.073 回答
0

有一种更好的方法,即在内存文件中使用。这样,您的磁盘上就没有任何 I/O,因此速度更快:

对于采用逻辑路径的标签,请在 Administrator 中定义映射。使用 cfinclude 标记执行内存中的 CFM 页面:

为 ram:/// 创建一个映射,以便在标签中使用它。在此示例中,/inmemory 是指向 ram:/// 的映射。

对于采用绝对路径的标签,请指定以下示例中提供的语法:

您还可以从 ram usinf cffile 和操作删除中删除文件。

于 2013-03-27T18:39:46.487 回答
0

以下是我如何存储记录中所有页面的页眉和页脚。此代码可以放在每一页的顶部。但我在 APPLICATION.cfm 中有它,它似乎工作得很好。

这里的关键是不要在你的表情上使用#pound# 符号。用户 [方括号]。代码将挑选它们并评估它们并将结果返回给模板。

如果它不能评估表达式作为错误处理的手段,它将替换数字 0。

<CFSET FooterID=1234>  <!-- ID of the record you want to use -->
<CFQUERY NAME="StoredHeader" Datasource="DS1">
  Select Body from templates where id=#FooterID#
</CFQUERY>

<CFSET Parse=StoredHeader.Body>

<CFLOOP CONDITION="FindNoCase('[',Parse,1) GT 0">
    <CFSET STB=FindNoCase('[',Parse,1)>
    <CFSET ENB=FindNoCase(']',Parse,1)>
    <CFIF ENB-STB GT 0>
    <CFSET BracketExp=Mid(Parse,STB+1,ENB-1-STB)>
            <CFTRY>
                <CFSET BracketValue=Evaluate(BracketExp)>
                <CFSET Parse=ReplaceNoCase(Parse,'['&BracketExp&']',Evaluate(#BracketExp#))>                
                <cfcatch type="any">
                    <div>'Using ZERO 0 for missing <cfoutput>#BracketExp#' </cfoutput> </div>
                    <CFSET Parse=ReplaceNoCase(Parse,'['&BracketExp&']','0')>
                </cfcatch>
            </CFTRY>        
    </CFIF>
</CFLOOP>
<CFSET Footer=Parse>

<cfoutput>FOOTER</cfoutput>
于 2013-04-25T01:12:21.390 回答
-1

我会尝试内置的QuoteName 函数

于 2010-12-20T21:51:49.773 回答