讓 Email 同時提供 text/plain 跟 text/html 版本,讓不支援 HTML 的 Email client 也可以顯示 plain 是一種是具有親和力的作法。根據 multipart-alternative 的定義,正確的格式應該長這樣,用 boundary 分隔成兩個部份:
From: Nathaniel Borenstein <[email protected]> To: Ned Freed <[email protected]> Subject: Formatted text mail MIME-Version: 1.0 Content-Type: multipart/alternative; boundary=boundary42 --boundary42 Content-Type: text/plain; charset=utf-8 ...plain text version of message goes here.... --boundary42 Content-Type: text/html; charset=utf-8 .... html version of same message goes here ... --boundary42--
一個方法來自 Rails Recipes(for Rails 1.1) 書上的作法:
def signup_notification(user) @from = EXTERNAL_MAIL_SENDER @subject = "Please activate your new account" @sent_on = Time.now @recipients = user.email @body[:user] = user content_type "multipart/alternative" part :content_type => "text/plain", :body => render_message("signup_notification_plain", @body ) part :content_type => "text/html", :body => render_message("signup_notification", @body ) end
檔案則是 signup_notification_plain.rhtml 跟 signup_notification.rhtml
不過經過 IRC #elixus 的朋友反應,在 mutt 跟 thunderbird 上看不到正確的 encoding。這才仔細看了 raw email data,竟然出來了三段 part 且第一段少了 charset utf-8。試著幾種不同寫法仍得不到看起來正確的格式,Rails Wiki 上的作法出來的格式也很奇怪。
本來想棄守 console-based email client 了,只提供 HTML 就好,但是布丁大人堅持要有 Gracefully Degrading 啊。於是再去看 ActionMailer API 發現其實有更簡單厲害的作法:
def signup_notification(user) @from = EXTERNAL_MAIL_SENDER @subject = "Please activate your new account" @sent_on = Time.now @recipients = user.email @body[:user] = user end
檔案則要命名成 signup_notification.text.plain.erb 跟 signup_notification.text.html.erb。嗯,Rails 依據副檔名慣例會自動合併成一封信,而無須寫明 content_type 跟使用 part。
我自己還有用Globalize plugin提供中英文不同版本,所以又還有 signup_notification.zh-TW.text.plain.erb 及 signup_notification.zh-TW.text.html.erb,真是長的副檔名啊 :>
這自動合併plain及html的部份,在rails 2.3.2能用嗎?
我試了都不行,是那裏不對呢?