【发布时间】:2011-02-25 02:58:36
【问题描述】:
我可能遗漏了一些明显的东西,但我有一个徽标,我想将其包含在我从我的应用程序发送的所有电子邮件中。我有一个用于所有这些邮件程序的主布局。我假设有一种方法可以让它保持干燥,而不必在每个邮件方法中添加代码行来附加文件。有人可以指出我正确的方向或纠正我的思路。
谢谢!
【问题讨论】:
标签: ruby-on-rails-3 actionmailer
我可能遗漏了一些明显的东西,但我有一个徽标,我想将其包含在我从我的应用程序发送的所有电子邮件中。我有一个用于所有这些邮件程序的主布局。我假设有一种方法可以让它保持干燥,而不必在每个邮件方法中添加代码行来附加文件。有人可以指出我正确的方向或纠正我的思路。
谢谢!
【问题讨论】:
标签: ruby-on-rails-3 actionmailer
未来的 Rails 版本将支持使用 before_filter 和 after_filter 的回调:
http://github.com/rails/rails/commit/4f28c4fc9a51bbab76d5dcde033c47aa6711339b
由于它们将使用 AbstractController::Callbacks 实现,因此您可以执行以下操作来模仿 Rails 4 发布后 ActionMailer::Base 中将出现的功能:
class YourMailer < ActionMailer::Base
if self.included_modules.include?(AbstractController::Callbacks)
raise "You've already included AbstractController::Callbacks, remove this line."
else
include AbstractController::Callbacks
end
before_filter :add_inline_attachments!
private
def add_inline_attachments!
attachments.inline["footer.jpg"] = File.read('/path/to/filename.jpg')
end
end
这包括将在未来的 rails 版本中使用的模块,因此您可用的回调挂钩将是相同的,以确保未来的兼容性。当您尝试升级到已经包含 AbstractController::Callbacks 的 Rails 版本时,代码会引发,因此会提醒您删除条件逻辑。
【讨论】:
AbstractController::Callbacks 真是太好了,我不知道可以这样做!解决了在每个邮件中获取内联附件的问题,我可以通过我包含在我的 ApplicationMailer 中的专用模块来配置所有内容。
我破解了一些东西,它并不理想,但它确实有效。
如果你使用
default "SOMEHEADER", Proc.new { set_layout }
然后定义set_layout
def set_layout
attachments.inline["logo.png"] = File.read("logopath.png")
attachments.inline["footer.jpg"] = File.read("footerpath.png")
"SOME HEADER VALUE"
end
然后因为 set_layout 被调用来设置标题,它也添加了内联附件。它基本上创建了一个用于添加附件的回调。
ActionMailer 中的实际回调系统会更好,但这也可以。
我想我会分享,因为我今天早些时候正在寻找这个问题的答案。
【讨论】:
在您的邮件程序使用的布局文件中,您可以添加以下内容
<%= image_tag('logo.png') %>
我假设发出的邮件是 html 或 multipart。
您还需要对环境文件进行更改。 ActionMailer 没有获得默认的 base_url。例如,在 environment/development.rb 我添加了以下内容
config.action_mailer.default_url_options = { :host => "localhost:3000" }
如果你想以一种干燥的方式(并作为附件)来做,也许你可以做类似的事情
class MyMailer < ActionMailer::Base
default :attachment => File.read(File.join(Rails.root,'public','images','logo.png'))
end
【讨论】:
attachments.inline['logo_small.png'] = File.read('public/images/logo_small.png')。那有意义吗?我想要一种 DRY 方式来添加附件。
我知道您曾询问过附加内联图像,但这里有一种不同的方法,它可以以较低的复杂性实现相同的目标。..
在html 布局中使用inline base64 encoded images - 不需要附件!
基本上只需将徽标图像的src="..." 更改为格式:
<img alt="example logo"
width="32px"
height="32px"
src="data:image/png;base64,iVBORw0KGgoAAA....."/>
我使用http://www.base64-image.net 的在线base64 编码器/解码器工具来生成完整的<img /> 标签
这种方法有几个好处:
- 无附件代码,让后端服务器代码更简洁易读
- 不增加电子邮件大小 - 内联图像附件无论如何都会转换为 base64,因此这种方法不会使电子邮件有效负载变得更大
- 得到广泛支持 - 如果接收电子邮件客户端显示html,则为pretty likely it also supports this method
【讨论】: