From 6982acb0793fb6e59f52cab4062344a88e3691ce Mon Sep 17 00:00:00 2001 From: Luca Guidi Date: Tue, 1 Jul 2008 16:52:48 +0200 Subject: Experimental I18n charset support for ActionMailer --- actionmailer/lib/action_mailer.rb | 4 + actionmailer/lib/action_mailer/base.rb | 14 ++- actionmailer/lib/action_mailer/locale/en-US.rb | 3 + actionmailer/test/i18n_test.rb | 133 +++++++++++++++++++++++++ 4 files changed, 149 insertions(+), 5 deletions(-) create mode 100644 actionmailer/lib/action_mailer/locale/en-US.rb create mode 100644 actionmailer/test/i18n_test.rb diff --git a/actionmailer/lib/action_mailer.rb b/actionmailer/lib/action_mailer.rb index 2e324d4637..806edf1f9e 100755 --- a/actionmailer/lib/action_mailer.rb +++ b/actionmailer/lib/action_mailer.rb @@ -49,4 +49,8 @@ ActionMailer::Base.class_eval do helper MailHelper end +I18n.backend.populate do + require 'action_mailer/locale/en-US.rb' +end + silence_warnings { TMail::Encoder.const_set("MAX_LINE_LEN", 200) } diff --git a/actionmailer/lib/action_mailer/base.rb b/actionmailer/lib/action_mailer/base.rb index 1518e23dfe..e787c1b8da 100644 --- a/actionmailer/lib/action_mailer/base.rb +++ b/actionmailer/lib/action_mailer/base.rb @@ -307,10 +307,6 @@ module ActionMailer #:nodoc: # Specify the CC addresses for the message. adv_attr_accessor :cc - # Specify the charset to use for the message. This defaults to the - # +default_charset+ specified for ActionMailer::Base. - adv_attr_accessor :charset - # Specify the content type for the message. This defaults to text/plain # in most cases, but can be automatically set in some situations. adv_attr_accessor :content_type @@ -348,6 +344,15 @@ module ActionMailer #:nodoc: # have multiple mailer methods share the same template. adv_attr_accessor :template + # Specify the charset to use for the message. + # It performs a lookup, on the specified charset, then on the charset from + # the current locale, and, finally, on the +default_charset+ specified + # for ActionMailer::Base. + def charset(charset = nil) + @charset ||= charset || :'charset'.t || @@default_charset + end + attr_writer :charset + # Override the mailer name, which defaults to an inflected version of the # mailer's class name. If you want to use a template in a non-standard # location, you can use this to specify that location. @@ -517,7 +522,6 @@ module ActionMailer #:nodoc: # mailer. Subclasses may override this method to provide different # defaults. def initialize_defaults(method_name) - @charset ||= @@default_charset.dup @content_type ||= @@default_content_type.dup @implicit_parts_order ||= @@default_implicit_parts_order.dup @template ||= method_name diff --git a/actionmailer/lib/action_mailer/locale/en-US.rb b/actionmailer/lib/action_mailer/locale/en-US.rb new file mode 100644 index 0000000000..369f2d1a1c --- /dev/null +++ b/actionmailer/lib/action_mailer/locale/en-US.rb @@ -0,0 +1,3 @@ +I18n.backend.store_translations :'en-US', { + :charset => 'utf-8' +} \ No newline at end of file diff --git a/actionmailer/test/i18n_test.rb b/actionmailer/test/i18n_test.rb new file mode 100644 index 0000000000..92b128bce6 --- /dev/null +++ b/actionmailer/test/i18n_test.rb @@ -0,0 +1,133 @@ +require 'abstract_unit' + +class I18nMailer < ActionMailer::Base + def use_locale_charset(recipient) + recipients recipient + subject "using locale charset" + from "tester@example.com" + body "x" + end + + def use_explicit_charset(recipient) + recipients recipient + subject "using explicit charset" + from "tester@example.com" + body "x" + charset "iso-8859-2" + end + + def multiparted(recipient) + recipients recipient + subject "Multiparted" + from "tester@example.com" + body "x" + + part "text/html" do |p| + p.body = "multiparted iso-8859-1 html" + end + + part :content_type => "text/plain", + :body => "multiparted utf-8 text", + :charset => 'utf-8' + end + + def rxml_template(recipient) + recipients recipient + subject "rendering rxml template" + from "tester@example.com" + end + + def initialize_defaults(method_name) + super + mailer_name "test_mailer" + end +end + +I18n.backend.store_translations :'en-GB', { } +I18n.backend.store_translations :'de-DE', { + :charset => 'iso-8859-1' +} + +class I18nTest < Test::Unit::TestCase + def setup + @charset = 'utf-8' + @recipient = 'test@localhost' + end + + def test_should_use_locale_charset + assert_equal @charset, mail.charset + end + + def test_should_use_default_charset_if_no_current_locale + uses_locale nil do + assert_equal @charset, mail.charset + end + end + + def test_mail_headers_should_contains_current_charset + uses_locale 'de-DE' do + assert_match /iso-8859-1/, mail.header['content-type'].body + end + end + + def test_should_use_charset_from_current_locale + uses_locale 'de-DE' do + assert_equal 'iso-8859-1', mail.charset + end + end + + def test_should_raise_exception_if_current_locale_doesnt_specify_a_charset + assert_raise I18n::MissingTranslationData do + uses_locale 'en-GB' do + mail + end + end + end + + def test_should_use_explicit_charset + assert_equal 'iso-8859-2', mail('use_explicit_charset').charset + end + + def test_mail_parts_charsets + uses_locale 'de-DE' do + charsets = mail('multiparted').parts.map(&:charset) + assert_equal 'iso-8859-1', charsets[0] + assert_equal 'iso-8859-1', charsets[1] + assert_equal 'utf-8', charsets[2] + end + end + + def test_mail_parts_headers + uses_locale 'de-DE' do + content_types = mail('multiparted').parts.map(&:header).map do |header| + header['content-type'].body + end + assert_match /iso-8859-1/, content_types[0] + assert_match /iso-8859-1/, content_types[1] + assert_match /utf-8/, content_types[2] + end + end + + # TODO: this case depends on XML Builder, + # should we pass Builder::XmlMarkup.new :encoding => charset_from_i18n ? + def _ignore_test_rxml_template_should_use_current_charset + uses_locale 'de-DE' do + assert_equal "\n", + mail('rxml_template').body.strip + end + end + + private + def mail(method = 'use_locale_charset') + I18nMailer.__send__('create_' + method, @recipient) + end + + def uses_locale(locale, &block) + begin + I18n.locale = locale + yield + ensure + I18n.locale = I18n.default_locale + end + end +end -- cgit v1.2.3