iblue
iblue

Reputation: 30414

Rails escapes HTML in my plain text mails

I am using the rails 3.2.5 ActionMailer to send plain text mails. Given I have a mail view like this:

message_from_user.text.erb:

Hi <%= @recipient.name %>,

You got the following message from <%= @sender.name %>:

<%= @message %>

When @message is "quotes & ampersands", then the plain text mail contains &quot;quotes &amp; ampersands&quot;. So it seems like rails just treats this as a HTML view and escapes any html in order to prevent cross site scripting. However this is a plain text mail. The extension is .text.erb and ActionMailer detectes this and sets the MIME to text/plain. So I never want to escape any html in it.

I have quite a few mail templates in my application, they are all plain text. I would consider patching all of them to include <%=raw @message%> or <%= @message.html_safe %> bad style - not very DRY.

I tried varios work-arounds that included money patching Erubis. None of them seem to work. I am looking for some patch or config option or anything to disable escaping html for all .text.erb files.

Any help is greatly appreciated!

Upvotes: 7

Views: 5386

Answers (2)

iblue
iblue

Reputation: 30414

After some hours of debugging through the Erubis code, I found the following fix. You can just put it into config/initializers/fix_my_mails.rb. I've tested this with rails 3.2.7. It may work with other versions.

module ActionView
  class Template
    module Handlers
      class ERB
        def call(template)
          if template.source.encoding_aware?
            # First, convert to BINARY, so in case the encoding is
            # wrong, we can still find an encoding tag
            # (<%# encoding %>) inside the String using a regular
            # expression
            template_source = template.source.dup.force_encoding("BINARY")

            erb = template_source.gsub(ENCODING_TAG, '')
            encoding = $2

            erb.force_encoding valid_encoding(template.source.dup, encoding)

            # Always make sure we return a String in the default_internal
            erb.encode!
          else
            erb = template.source.dup
          end

          self.class.erb_implementation.new(
            erb,
            :trim => (self.class.erb_trim_mode == "-"),
            :escape => template.identifier =~ /\.text/ # only escape HTML templates
          ).src
        end
      end
    end
  end
end

It just disables HTML entities in every erb file containing .text in the file name.

Upvotes: 8

Hans Hohenfeld
Hans Hohenfeld

Reputation: 1739

Try

<%= @message.html_safe %>

You'd found this answer if you had used the search function. If that doesn't suit your needs, maybe check

https://rails.lighthouseapp.com/projects/8994/tickets/4858-actionmailer-is-html-escaping-ampersand-in-urls-in-plain-text-messages

If you haven't seen that yet, some options are discussed there

Upvotes: 8

Related Questions