| 1 |
# Search for translated templates or fall back to the default one |
|---|
| 2 |
module ActionMailer # :nodoc: |
|---|
| 3 |
|
|---|
| 4 |
# Globalize overrides the create! method to support multiple templates |
|---|
| 5 |
# for different locales. For example, for English it will select the template: |
|---|
| 6 |
# signup_notification.en-US.text.html.rhtml |
|---|
| 7 |
# |
|---|
| 8 |
# It will look for the currently active locale code (en-US) first, |
|---|
| 9 |
# then the language code (en). |
|---|
| 10 |
# |
|---|
| 11 |
# If neither of those are found, it will use the regular name: |
|---|
| 12 |
# signup_notification.text.html.rhtml |
|---|
| 13 |
# |
|---|
| 14 |
# It is fully backwards compatible with the original Rails version. |
|---|
| 15 |
class Base |
|---|
| 16 |
|
|---|
| 17 |
# Initialize the mailer via the given +method_name+. The body will be |
|---|
| 18 |
# rendered and a new TMail::Mail object created. |
|---|
| 19 |
# |
|---|
| 20 |
# This method is overriden by Globalize to support multiple templates |
|---|
| 21 |
# for different locales. For example, use: |
|---|
| 22 |
# signup_notification.en-US.text.html.rhtml |
|---|
| 23 |
# It is fully backwards compatible with the original rails version. |
|---|
| 24 |
def create!(method_name, *parameters) #:nodoc: |
|---|
| 25 |
initialize_defaults(method_name) |
|---|
| 26 |
send(method_name, *parameters) |
|---|
| 27 |
|
|---|
| 28 |
# If an explicit, textual body has not been set, we check assumptions. |
|---|
| 29 |
unless String === @body |
|---|
| 30 |
# First, we look to see if there are any likely templates that match, |
|---|
| 31 |
# which include the content-type in their file name (i.e., |
|---|
| 32 |
# "the_template_file.text.html.rhtml", etc.). Only do this if parts |
|---|
| 33 |
# have not already been specified manually. |
|---|
| 34 |
if @parts.empty? |
|---|
| 35 |
append_localized_parts |
|---|
| 36 |
unless @parts.empty? |
|---|
| 37 |
@content_type = "multipart/alternative" |
|---|
| 38 |
@charset = nil |
|---|
| 39 |
@parts = sort_parts(@parts, @implicit_parts_order) |
|---|
| 40 |
end |
|---|
| 41 |
end |
|---|
| 42 |
|
|---|
| 43 |
# Then, if there were such templates, we check to see if we ought to |
|---|
| 44 |
# also render a "normal" template (without the content type). If a |
|---|
| 45 |
# normal template exists (or if there were no implicit parts) we render |
|---|
| 46 |
# it. |
|---|
| 47 |
render_localized_normal_template |
|---|
| 48 |
|
|---|
| 49 |
# Finally, if there are other message parts and a textual body exists, |
|---|
| 50 |
# we shift it onto the front of the parts and set the body to nil (so |
|---|
| 51 |
# that create_mail doesn't try to render it in addition to the parts). |
|---|
| 52 |
if !@parts.empty? && String === @body |
|---|
| 53 |
@parts.unshift Part.new(:charset => charset, :body => @body) |
|---|
| 54 |
@body = nil |
|---|
| 55 |
end |
|---|
| 56 |
end |
|---|
| 57 |
|
|---|
| 58 |
# If this is a multipart e-mail add the mime_version if it is not |
|---|
| 59 |
# already set. |
|---|
| 60 |
@mime_version ||= "1.0" if !@parts.empty? |
|---|
| 61 |
|
|---|
| 62 |
# build the mail object itself |
|---|
| 63 |
@mail = create_mail |
|---|
| 64 |
end |
|---|
| 65 |
|
|---|
| 66 |
private |
|---|
| 67 |
def append_localized_parts |
|---|
| 68 |
codes = locale_codes |
|---|
| 69 |
codes.each do |code| |
|---|
| 70 |
if code |
|---|
| 71 |
templates = Dir.glob("#{template_path}/#{@template}.#{code}.*") |
|---|
| 72 |
else |
|---|
| 73 |
templates = Dir.glob("#{template_path}/#{@template}.*") |
|---|
| 74 |
end |
|---|
| 75 |
templates.each do |path| |
|---|
| 76 |
sections = File.basename(path).split(".")[0..-2] || [] |
|---|
| 77 |
|
|---|
| 78 |
# skip if this is some other language |
|---|
| 79 |
next if !code && Globalize::RFC_3066.valid?(sections[1]) |
|---|
| 80 |
|
|---|
| 81 |
# skip either template name and locale, or just template name |
|---|
| 82 |
type_sections = code ? sections[2..-1] : sections[1..-1] |
|---|
| 83 |
type = type_sections.join("/") |
|---|
| 84 |
next if type.empty? |
|---|
| 85 |
@parts << Part.new(:content_type => type, |
|---|
| 86 |
:disposition => "inline", :charset => charset, |
|---|
| 87 |
:body => render_message(sections.join('.'), @body)) |
|---|
| 88 |
end |
|---|
| 89 |
|
|---|
| 90 |
# if we found templates at this stage, no need to continue to defaults |
|---|
| 91 |
break if !templates.empty? |
|---|
| 92 |
end |
|---|
| 93 |
end |
|---|
| 94 |
|
|---|
| 95 |
def render_localized_normal_template |
|---|
| 96 |
template_exists = @parts.empty? |
|---|
| 97 |
codes = locale_codes |
|---|
| 98 |
codes.each do |code| |
|---|
| 99 |
localized_name = @template |
|---|
| 100 |
if !template_exists |
|---|
| 101 |
if code |
|---|
| 102 |
localized_name = [ @template, code ].join(".") |
|---|
| 103 |
template_exists ||= |
|---|
| 104 |
Dir.glob("#{template_path}/#{localized_name}.*").any? { |i| i.split(".").length == 3 } |
|---|
| 105 |
else |
|---|
| 106 |
template_exists ||= |
|---|
| 107 |
Dir.glob("#{template_path}/#{@template}.*").any? { |i| i.split(".").length == 2 } |
|---|
| 108 |
end |
|---|
| 109 |
end |
|---|
| 110 |
@body = render_message(localized_name, @body) if template_exists |
|---|
| 111 |
break if template_exists |
|---|
| 112 |
end |
|---|
| 113 |
end |
|---|
| 114 |
|
|---|
| 115 |
def locale_codes |
|---|
| 116 |
loc = Globalize::Locale.active |
|---|
| 117 |
lang = Globalize::Locale.language |
|---|
| 118 |
codes = [ loc, lang ].compact.map {|o| o.code }.uniq |
|---|
| 119 |
codes << nil # look for default path, with no localization |
|---|
| 120 |
end |
|---|
| 121 |
end |
|---|
| 122 |
end |
|---|