I use one layout for all my emails in my Notifier model (20+ emails)... however sometimes I just want to send a plain text email with no layout or html at all. I can't seem to be able to figure out how? If I try to send a plain text email i still get the layout, and all the HTML in the email.
I'm using Rails 2.3.8.
I read about this monkey patch here... but it seemed to indicate a newer version of rails had over come this? And I don't really wanna monkey patch if I can avoid one.
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 '[email protected]'
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
I also have 2 files.
email.text.html.erb
email.text.plain.erb
It always uses text.html.erb... even if the content_type is "text/plain"
Just like controller views, you can also have mailer layouts. The layout name needs to be the same as your mailer, such as user_mailer.html.erb and user_mailer.text.erb to be automatically recognized by your mailer as a layout. In order to use a different file, call layout in your mailer:
Mailers have: Actions, and also, associated views that appear in app/views. Instance variables that are accessible in views. The ability to utilise layouts and partials. The ability to access a params hash. This section will provide a step-by-step guide to creating a mailer and its views.
You can use the :layout option to tell Rails to use a specific file as the layout for the current action: You can also tell Rails to render with no layout at all: You can use the :location option to set the HTTP Location header: Rails will automatically generate a response with the correct HTTP status code (in most cases, this is 200 OK ).
If you want Rails to put the text into the current layout, you need to add the layout: true option and use the .text.erb extension for the layout file. You can send an HTML string back to the browser by using the :html option to render: This is useful when you're rendering a small snippet of HTML code.
edit: Figured it out, the layouts follow a different naming scheme to the email templates. Just rename them as follows:
layout.text.html.erb => layout.html.erb
layout.text.plain.erb => layout.text.erb
I also made the mistake of manually defining the parts, if you use this:
part :content_type => 'text/plain',
:body => render_message('my_template')
Then Rails can't determine the content_type for your part and it assumes it's HTML.
After I changed those two things it worked for me!
original reply follows..
I've struggled with this question many times in the past, usually ending up with some sort of non-dry quick and dirty solution. I always thought I was the only one with this problem because Google turns up exactly nothing useful on the subject.
This time I decided to dig into Rails to figure it out but so far without much success, but maybe my findings will help someone else figure this out.
What I found was that in ActionMailer::Base the #render_message method is tasked with determining the proper content_type and should assign it to @current_template_content_type. #default_template_format then either returns the proper mime type for the layout or, if @current_template_content_type isn't set, it will default to :html.
This is what ActionMailer::Base#render_message looks like in my app (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
The trouble is that method_name appears to be a string (the name of the local view, in my case "new_password.text.html") and strings of course do not respond_to #content_type, meaning @current_template_content_type will always remain nil, and so the #default_template_format will always default to :html.
Not much closer to an actual solution, I know. The ActionMailer internals are just too opaque for me.
OK, not sure if this works, but it seems the default content_type is text/plain, so you would only need to set the content type if you want something other than text/plain.
Try this:
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
I still think you should consider this:
layout "email", :except => [:send_inquiry]
I would use the above because the plain text email does not seem to have a 'layout', only the actual content you want to send.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With