在 ColdFusion 中的何处存储自动交易电子邮件模板
Where to store automated transactional email templates in ColdFusion
我正在开发一个电子商务应用程序,该应用程序可以自然地通过电子邮件与用户就交易进行交流,例如:
- 用户注册
- 邮箱验证
- 密码重置
- 订单确认
- 发货确认
- 评论通知
以此类推
目前我只发送用户注册电子邮件,所以我设法将它们全部保存在一个名为 email.cfc
的组件中,并在 application
范围内保留一个实例,例如 <cfset APPLICATION.EmailSender = New email.cfc() />
email.cfc
只是有一堆发送不同电子邮件的方法,例如:
<cffunction name="NewUserRegistered">
<cfmail type="html" to="#useremail#" subject="Welcome" >
<h1>Thanks for registering #username#!</h1>
</cfmail>
</cffunction>
<cffunction name="PasswordReset">
<cfmail type="html" to="#useremail#" subject="Password Reset">
<h1>Dear #username#, you requested a password reset...</h1>
</cfmail>
</cffunction>
<cffunction name="OrderConfirmation">
<cfmail type="html" to="#useremail#" subject="Order Confirmation #orderid#">
<h1>Your order: #order_id# has been received...</h1>
</cfmail>
</cffunction>
我刚刚意识到不同类型电子邮件的数量即将激增,我最终可能会收到大约 50 种不同类型的电子邮件,这些电子邮件必须根据正在发生的事件类型发送出去。将所有这些电子邮件模板保存在应用程序范围内的单个 CFC 中似乎太容易了,这可能会填满服务器内存或导致其他一些可伸缩性问题(无论可能 be/mean)
在 ColdFusion 中管理发送自动交易电子邮件的更好方法是什么?一些可能的解决方案:
- 继续将所有电子邮件保存在一个 CFC 中并从其他 CFCs/CFM 页面访问它们
- 将模板保留在需要它的 CFC 中,例如
shoppingcart.cfc
将在购物会话结束时触发订单确认电子邮件
编辑: 添加了占位符替换示例。
我建议在 HTML 中写出模板,然后将 HTML 保存到您的数据库中。然后你可以创建一个函数来查询你的数据库然后填充并发送你的电子邮件。那会很轻。
<cfscript>
// Our mail function.
public Void function genEmail ( required Numeric templateTypeID, required String userEmail, required Struct placeholder ) {
// Created fake query of templates.
emailTemplateQuery = queryNew(
"templatetypeid,templatesubject,templatetext",
"integer,varchar,varchar",
[
{ templatetypeid=1,templatesubject='Welcome',templatetext='<h1>Thanks for registering!</h1><p>[[p1]]</p><p>[[p2]]</p>' },
{ templatetypeid=2,templatesubject='Password Reset',templatetext='<h1>You requested a password reset.</h1><p>[[p1]]</p><p>[[p2]]</p>' },
{ templatetypeid=3,templatesubject='Another Email',templatetext='<h1>You did something.</h1><p>[[p1]]</p><p>[[p2]]</p><p>[[p3]]</p>' }
]
) ;
///////////////////////////////////
// Build the query.
local.sql = "SELECT templatesubject, templatetext FROM emailTemplateQuery WHERE templateTypeID = :templateTypeID" ;
// Which template?
local.params = { templateTypeID = arguments.templateTypeID };
// Query options?
local.queryoptions = {
dbtype="query"
// datasource="myDSN" << Use your DSN for final query.
} ;
// Create a new query and execute it.
local.emailQ = QueryExecute(local.sql, local.params, local.queryoptions ) ;
local.finalEmailString = local.emailQ.templatetext ;
// Let's inject our placeholder info into our email template
for ( var p IN arguments.placeholder ) {
local.finalEmailString = local.finalEmailString.replaceNoCase(
"[[" & p & "]]" ,
arguments.placeholder[p] ,
"All"
) ;
}
// Create a new mail object.
local.sendEmail = new mail() ;
// Save mail body to a variable.
savecontent variable="emailBody" {
writeOutput(local.finalEmailString);
}
// Set From, To, Type, etc.
sendEmail.setFrom("fromMe@domain.com");
sendEmail.setTo(arguments.userEmail);
sendEmail.setType("html");
sendEmail.setSubject(local.emailQ.templatesubject);
// Send the email. So uncomment next line to send.
//sendEmail.send(body=emailBody);
// We don't have to return anything, but for this demo, we want to see what email will be sent.
writeDump(local.emailQ.templatesubject);
writeDump(local.finalEmailString);
}
// To send an email, just call genEmail() and pass the type and who to.
genEmail(1,"bill@beexcellent.com",{"p1":"This is my first replacement.","p2":"This is my second replacement."}) ;
writeoutput("<br><br>");
genEmail(2,"ted@beexcellent.com",{"p1":"This is my third replacement.","p2":"This is my fourth replacement."}) ;
writeoutput("<br><br>");
genEmail(3,"rufus@beexcellent.com",{"p1":"This is my fifth replacement.","p2":"This is my sixth replacement.","p3":"This is my seventh replacement."}) ;
</cfscript>
可以稍微简化一下。我的大部分代码是设置测试数据和使用 Query Of Query。您希望定期调用您的数据源。您还可以在 cfmail
标记内更有效地使用查询结果。我强烈建议在允许任何东西从您的系统发送电子邮件之前进行大量过滤和验证。您还可以 return 来自电子邮件功能的状态代码来验证成功(或其他信息)。
您可以将您的电子邮件进程保存到它自己的 CFC 中,然后缓存它以在您的整个应用程序中使用。
注意:对于大多数 CF,我也更喜欢脚本而不是标签,但是如果你愿意,我上面的逻辑可以转换回标签。
结果:
通过我的上述测试,您会收到包含以下 HTML 的电子邮件。
genEmail(1,"bill@beexcellent.com",{"p1":"This is my first
replacement.","p2":"This is my second replacement."})
Welcome
Thanks for registering!
This is my first
replacement.
This is my second replacement.
genEmail(2,"ted@beexcellent.com",{"p1":"This is my third
replacement.","p2":"This is my fourth replacement."})
Password Reset
You requested a password reset.
This is my third
replacement.
This is my fourth replacement.
genEmail(3,"rufus@beexcellent.com",{"p1":"This is my fifth
replacement.","p2":"This is my sixth replacement.","p3":"This is my
seventh replacement."})
Another Email
You did something.
This is my fifth
replacement.
This is my sixth replacement.
This is my
seventh replacement.
我正在开发一个电子商务应用程序,该应用程序可以自然地通过电子邮件与用户就交易进行交流,例如:
- 用户注册
- 邮箱验证
- 密码重置
- 订单确认
- 发货确认
- 评论通知
以此类推
目前我只发送用户注册电子邮件,所以我设法将它们全部保存在一个名为 email.cfc
的组件中,并在 application
范围内保留一个实例,例如 <cfset APPLICATION.EmailSender = New email.cfc() />
email.cfc
只是有一堆发送不同电子邮件的方法,例如:
<cffunction name="NewUserRegistered">
<cfmail type="html" to="#useremail#" subject="Welcome" >
<h1>Thanks for registering #username#!</h1>
</cfmail>
</cffunction>
<cffunction name="PasswordReset">
<cfmail type="html" to="#useremail#" subject="Password Reset">
<h1>Dear #username#, you requested a password reset...</h1>
</cfmail>
</cffunction>
<cffunction name="OrderConfirmation">
<cfmail type="html" to="#useremail#" subject="Order Confirmation #orderid#">
<h1>Your order: #order_id# has been received...</h1>
</cfmail>
</cffunction>
我刚刚意识到不同类型电子邮件的数量即将激增,我最终可能会收到大约 50 种不同类型的电子邮件,这些电子邮件必须根据正在发生的事件类型发送出去。将所有这些电子邮件模板保存在应用程序范围内的单个 CFC 中似乎太容易了,这可能会填满服务器内存或导致其他一些可伸缩性问题(无论可能 be/mean)
在 ColdFusion 中管理发送自动交易电子邮件的更好方法是什么?一些可能的解决方案:
- 继续将所有电子邮件保存在一个 CFC 中并从其他 CFCs/CFM 页面访问它们
- 将模板保留在需要它的 CFC 中,例如
shoppingcart.cfc
将在购物会话结束时触发订单确认电子邮件
编辑: 添加了占位符替换示例。
我建议在 HTML 中写出模板,然后将 HTML 保存到您的数据库中。然后你可以创建一个函数来查询你的数据库然后填充并发送你的电子邮件。那会很轻。
<cfscript>
// Our mail function.
public Void function genEmail ( required Numeric templateTypeID, required String userEmail, required Struct placeholder ) {
// Created fake query of templates.
emailTemplateQuery = queryNew(
"templatetypeid,templatesubject,templatetext",
"integer,varchar,varchar",
[
{ templatetypeid=1,templatesubject='Welcome',templatetext='<h1>Thanks for registering!</h1><p>[[p1]]</p><p>[[p2]]</p>' },
{ templatetypeid=2,templatesubject='Password Reset',templatetext='<h1>You requested a password reset.</h1><p>[[p1]]</p><p>[[p2]]</p>' },
{ templatetypeid=3,templatesubject='Another Email',templatetext='<h1>You did something.</h1><p>[[p1]]</p><p>[[p2]]</p><p>[[p3]]</p>' }
]
) ;
///////////////////////////////////
// Build the query.
local.sql = "SELECT templatesubject, templatetext FROM emailTemplateQuery WHERE templateTypeID = :templateTypeID" ;
// Which template?
local.params = { templateTypeID = arguments.templateTypeID };
// Query options?
local.queryoptions = {
dbtype="query"
// datasource="myDSN" << Use your DSN for final query.
} ;
// Create a new query and execute it.
local.emailQ = QueryExecute(local.sql, local.params, local.queryoptions ) ;
local.finalEmailString = local.emailQ.templatetext ;
// Let's inject our placeholder info into our email template
for ( var p IN arguments.placeholder ) {
local.finalEmailString = local.finalEmailString.replaceNoCase(
"[[" & p & "]]" ,
arguments.placeholder[p] ,
"All"
) ;
}
// Create a new mail object.
local.sendEmail = new mail() ;
// Save mail body to a variable.
savecontent variable="emailBody" {
writeOutput(local.finalEmailString);
}
// Set From, To, Type, etc.
sendEmail.setFrom("fromMe@domain.com");
sendEmail.setTo(arguments.userEmail);
sendEmail.setType("html");
sendEmail.setSubject(local.emailQ.templatesubject);
// Send the email. So uncomment next line to send.
//sendEmail.send(body=emailBody);
// We don't have to return anything, but for this demo, we want to see what email will be sent.
writeDump(local.emailQ.templatesubject);
writeDump(local.finalEmailString);
}
// To send an email, just call genEmail() and pass the type and who to.
genEmail(1,"bill@beexcellent.com",{"p1":"This is my first replacement.","p2":"This is my second replacement."}) ;
writeoutput("<br><br>");
genEmail(2,"ted@beexcellent.com",{"p1":"This is my third replacement.","p2":"This is my fourth replacement."}) ;
writeoutput("<br><br>");
genEmail(3,"rufus@beexcellent.com",{"p1":"This is my fifth replacement.","p2":"This is my sixth replacement.","p3":"This is my seventh replacement."}) ;
</cfscript>
可以稍微简化一下。我的大部分代码是设置测试数据和使用 Query Of Query。您希望定期调用您的数据源。您还可以在 cfmail
标记内更有效地使用查询结果。我强烈建议在允许任何东西从您的系统发送电子邮件之前进行大量过滤和验证。您还可以 return 来自电子邮件功能的状态代码来验证成功(或其他信息)。
您可以将您的电子邮件进程保存到它自己的 CFC 中,然后缓存它以在您的整个应用程序中使用。
注意:对于大多数 CF,我也更喜欢脚本而不是标签,但是如果你愿意,我上面的逻辑可以转换回标签。
结果: 通过我的上述测试,您会收到包含以下 HTML 的电子邮件。
genEmail(1,"bill@beexcellent.com",{"p1":"This is my first replacement.","p2":"This is my second replacement."})
WelcomeThanks for registering!
This is my first replacement.
This is my second replacement.
genEmail(2,"ted@beexcellent.com",{"p1":"This is my third replacement.","p2":"This is my fourth replacement."})
Password Reset
You requested a password reset.
This is my third replacement.
This is my fourth replacement.
genEmail(3,"rufus@beexcellent.com",{"p1":"This is my fifth replacement.","p2":"This is my sixth replacement.","p3":"This is my seventh replacement."})
Another Email
You did something.
This is my fifth replacement.
This is my sixth replacement.
This is my seventh replacement.