Coldfusion CFMAIL & CfMailPart 自定义标签

Coldfusion CFMAIL & CfMailPart Custom Tags

我正在为 CFMAIL 编写自定义标签。我需要以不同于标准 CFMAIL 的方式处理某些电子邮件。我使用以下 post 作为起点 - http://www.cfhero.com/2011/11/creating-environment-safe-wrapper-for.html

之前

<cfmail to="no@example.com" from="no@test.com" subject="This is only a test">
<cfmailparam name="Importance" value="high">
hello world</cfmail>

自定义标签之后

<cf_email to="no@example.com" from="no@test.com" subject="This is only a test">
<cf_emailparam name="Importance" value="high">
hello world</cf_email>

自定义 CFMAIL 和 CFMAILPARAM 一切正常,但我的问题是如何处理 "CFMAILPART"。在新标签中使用现有的 CFMAILPART 时,CF 会抛出错误。

<cf_email to="no@example.com" from="no@test.com" subject="This is only a test">
<cf_emailparam name="Importance" value="high">
    <cfmailpart type="text">Text</cfmailpart>
    <cfmailpart type="html">HTML</cfmailpart></cf_email>

Detail: The tag must be nested inside a cfmail tag.

Message: Context validation error for tag cfmailpart.

我正在提出自己的想法,但找不到任何帮助文档。非常感谢任何帮助或起点。

提前致谢。

编辑:虽然这将使它使用自定义标签工作,但 John Whish 使用 cfc 的解决方案更灵活。

出于与创建 cf_emailparam 标签相同的原因,您可能需要创建一个 cf_emailpart 自定义标签。 cfemailparam 必须包含在 cfmail 标签中

<cf_email to="no@example.com" from="no@test.com" subject="This is only a test">
    <cf_emailparam name="Importance" value="high">
    <cf_emailpart type="text">Text</cf_emailpart>
    <cf_emailpart type="html">HTML</cf_emailpart>
</cf_email>

cf_emailpart

几乎与 cf_emailparam 相同。最后一部分将标签与 cf_email

相关联
<cfif CompareNoCase(thisTag.hasEndtag,"YES") EQ 0 AND CompareNoCase(thisTag.executionMode,"END") EQ 0 >
    <cfexit method="exittag" />
</cfif>

<cfassociate basetag="cf_email" datacollection="emailPart">

然后您需要将其添加到您的 cf_email 自定义标签文件中,在您输出 cfmailparam 标签的部分之后,以及 cfmail 标签内。

<cfif isDefined("thisTag.emailPart")>
    <cfloop array="#thisTag.emailPart#" index="attrCol">
        <cfmailpart attributecollection="#attrCol#" >
    </cfloop> 
 </cfif>

我没有测试过这段代码,但我认为这是你必须走的方向。

必须是自定义标签吗?在我看来,将其封装在 CFC 中会更简单。类似于:

<cfcomponent output="false">

    <cffunction name="init" access="public" returntype="any" output="false">
        <cfreturn this>
    </cfunction>

    <cffunction name="sendEmail" access="public" returntype="void" output="false">
        <cfargument name="to" required="true">
        <cfargument name="from" required="true">
        <cfargument name="subject" required="true">
        <cfargument name="importance" required="true">
        <cfargument name="htmlContent" required="true">
        <cfargument name="textContent" required="true">

        <!--- do a check here to see if in production something like--->
        <cfif ListFirst(CGI.SERVER_NAME, ".") neq "www">
            <!--- override the to email address or whatever here --->
            <cfset to = "foo@development.local">
        </cfif>

        <cfmail to="#to#" from="#from#" subject="#subject#">
            <cfmailparam name="Importance" value="#importance#">
            <cfmailpart type="text/plain">#textContent#</cfmailpart>
            <cfmailpart type="text/html">#htmlContent#</cfmailpart>
        </cfmail>
    </cffunction>

</cfcomponent>

那么您可以通过以下方式调用它:

<cfset Mailer = new Path.To.Component()>
<cfset Mailer.sendEmail(
    to="foo@somewhere.com",
    from="bar@somewhere.com",,
    subject="An Email",
    importance="high",
    htmlContent="<p>Hello!</p>,
    textContent="Hello!"
)>

Mailer 实例可以是单例(每个应用程序只需要一个实例),然后如果您愿意,可以执行诸如向其中注入配置设置之类的操作,而不是在实际的 CFC 中进行环境检测。