【问题标题】:Rails - Use same attachment for all emails using layoutRails - 使用布局对所有电子邮件使用相同的附件
【发布时间】:2011-02-25 02:58:36
【问题描述】:

我可能遗漏了一些明显的东西,但我有一个徽标,我想将其包含在我从我的应用程序发送的所有电子邮件中。我有一个用于所有这些邮件程序的主布局。我假设有一种方法可以让它保持干燥,而不必在每个邮件方法中添加代码行来附加文件。有人可以指出我正确的方向或纠正我的思路。

谢谢!

【问题讨论】:

    标签: ruby-on-rails-3 actionmailer


    【解决方案1】:

    未来的 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 中的专用模块来配置所有内容。
    【解决方案2】:

    我破解了一些东西,它并不理想,但它确实有效。

    如果你使用

    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 中的实际回调系统会更好,但这也可以。

    我想我会分享,因为我今天早些时候正在寻找这个问题的答案。

    【讨论】:

      【解决方案3】:

      在您的邮件程序使用的布局文件中,您可以添加以下内容

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

      【讨论】:

      • 如果他想使用内联附件就不行...他还需要设置一个基本网址才能正常工作...
      • 哦,是的,谢谢,忘了提到这一点。我根据您的评论编辑了我的答案。
      • 谢谢,@Shiv。不幸的是,它并没有真正回答我的问题(可能不清楚)。我遇到无法保持 DRY 的问题是在邮件程序类中,我必须在每个邮件程序方法中调用 attachments.inline['logo_small.png'] = File.read('public/images/logo_small.png')。那有意义吗?我想要一种 DRY 方式来添加附件。
      【解决方案4】:

      我知道您曾询问过附加内联图像,但这里有一种不同的方法,它可以以较低的复杂性实现相同的目标。..

      在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 编码器/解码器工具来生成完整的&lt;img /&gt; 标签

      这种方法有几个好处:
      - 无附件代码,让后端服务器代码更简洁易读
      - 不增加电子邮件大小 - 内联图像附件无论如何都会转换为 base64,因此这种方法不会使电子邮件有效负载变得更大
      - 得到广泛支持 - 如果接收电子邮件客户端显示html,则为pretty likely it also supports this method

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多