【问题标题】:rails mailer with different layouts具有不同布局的rails mailer
【发布时间】:2011-04-08 20:16:45
【问题描述】:

我在我的 Notifier 模型(20 多封电子邮件)中为我的所有电子邮件使用一种布局......但有时我只想发送一封没有布局或 html 的纯文本电子邮件。我似乎无法弄清楚如何?如果我尝试发送纯文本电子邮件,我仍然会得到布局以及电子邮件中的所有 HTML。

我使用的是 Rails 2.3.8。

我在这里读到了这个猴子补丁......但这似乎表明新版本的rails已经结束了这个?如果我能避免的话,我真的不想要猴子补丁。

Rails - setting multiple layouts for a multipart email with mailer templates

  layout "email" # use email.text.(html|plain).erb as the layout


  def welcome_email(property)
    subject    'New Signup'
    recipients property.email
    from       'welcome@test.com'
    body       :property => property
    content_type "text/html"
  end

  def send_inquiry(inquire)
    subject    "#{inquire.the_subject}"
    recipients inquire.ob.email
    from       "Test on behalf of #{inquire.name} <#{inquire.email}>"
    body       :inquire => inquire
    content_type "text/plain"

  end

我还有 2 个文件。

email.text.html.erb
email.text.plain.erb

它总是使用 text.html.erb... 即使 content_type 是“text/plain”

【问题讨论】:

    标签: ruby-on-rails layout email actionmailer multipart


    【解决方案1】:

    编辑:想通了,布局遵循与电子邮件模板不同的命名方案。只需将它们重命名如下:

    layout.text.html.erb    => layout.html.erb
    layout.text.plain.erb   => layout.text.erb
    

    我也犯了手动定义零件的错误,如果你使用这个:

    part :content_type => 'text/plain',
         :body => render_message('my_template')
    

    然后 Rails 无法确定您的部分的 content_type,它假定它是 HTML。

    在我改变了这两件事后,它对我有用!

    原始回复如下..


    过去,我曾多次为这个问题苦苦挣扎,通常以某种非干的快速而肮脏的解决方案告终。我一直认为我是唯一一个遇到这个问题的人,因为谷歌在这个问题上完全没有发现任何有用的东西。

    这一次我决定深入研究 Rails 来解决这个问题,但到目前为止还没有取得太大的成功,但也许我的发现会帮助其他人解决这个问题。

    我发现在 ActionMailer::Base 中,#render_message 方法的任务是确定正确的 content_type,并将其分配给 @current_template_content_type。 #default_template_format 然后为布局返回正确的 mime 类型,或者,如果未设置 @current_template_content_type,它将默认为 :html。

    这就是 ActionMailer::Base#render_message 在我的应用 (2.3.5) 中的样子

      def render_message(method_name, body)
        if method_name.respond_to?(:content_type)
          @current_template_content_type = method_name.content_type
        end
        render :file => method_name, :body => body
      ensure
        @current_template_content_type = nil
      end
    

    问题是 method_name 似乎是一个字符串(本地视图的名称,在我的例子中是“new_password.text.html”),字符串当然不响应#content_type,这意味着@current_template_content_type 将始终保持为零,因此 #default_template_format 将始终默认为 :html。

    我知道,与实际解决方案相差无几。 ActionMailer 内部对我来说太不透明了。

    【讨论】:

    • 嗯,很有趣。与您所说的相反,根据 API 文档,默认 content_type 是 text/plain...
    • 这对我来说也更有意义,但在 ActionMailer::Base 中寻找#default_template_format,这是我能解决的罪魁祸首。当我发现更多时,我会继续寻找和更新。
    • 我想我已经想通了,或多或少。我的问题是我使用“part :body => render_message()”手动定义部件,如果你这样做,ActionMailer 会忽略 content_type 并且默认为 html,就像我上面描述的那样。但是如果你让 Rails 自动确定部分,render_message 会得到一个 ActionView::ReloadableTemplate 而不是作为“method_name”传递的字符串(讨论误导性变量名),并且 content_type 检测有效。
    • 但是在我改变布局后仍然没有正确渲染。问题是电子邮件布局的命名方案与电子邮件模板的命名方案不同。电子邮件模板需要命名,例如contact_form.text.plain.erb,但布局需要命名为 email_layout.text.erb 和 email_layout.html.erb 所以不是完整的 mime 类型,而只是 text 或 html。一旦我改变它对我有用。
    • 您的最后一条评论听起来像是解决方案。做得好。我想知道它是否也适用于霍尔顿。如果是这样,他应该接受你的回答,这样其他人也可以找到解决这个问题的方法。
    【解决方案2】:

    好的,不确定这是否有效,但似乎默认的 content_type 是 text/plain,因此如果您想要 text/plain 以外的内容,则只需设置内容类型。

    试试这个:

    def send_inquiry(inquire)
      subject    "#{inquire.the_subject}"
      recipients inquire.ob.email
      from       "Test on behalf of #{inquire.name} <#{inquire.email}>"
      body       :inquire => inquire
    end
    

    我仍然认为你应该考虑这个:

    layout "email", :except => [:send_inquiry]
    

    我会使用上述内容,因为纯文本电子邮件似乎没有“布局”,只有您要发送的实际内容。

    【讨论】:

    • 这可能是一个快速修复,但如果我能弄清楚为什么所谓的内置功能不起作用,我仍然会喜欢它。 IE,当我声明一个 content_type 时,它​​应该寻找合适的文件?
    • 我更新了我的答案.. 不确定,但值得一试。祝你好运。
    【解决方案3】:

    我发现这个我认为可能有用。

    http://blog.blazingcloud.net/2009/11/17/simple-email-form-with-actionmailer/

    他利用重命名不同内容类型的视图模板。

    【讨论】:

      猜你喜欢
      • 2016-10-13
      • 2013-04-27
      • 1970-01-01
      • 2012-07-23
      • 2017-07-22
      • 1970-01-01
      • 2020-06-13
      • 2016-12-20
      • 1970-01-01
      相关资源
      最近更新 更多