1 require 'action_mailer'
4 module MailerViewPathsExtension
5 def self.included(base)
7 cattr_accessor :view_paths
8 self.view_paths = [ActionMailer::Base.template_root].compact
10 alias :create_without_view_paths! :create!
11 alias :create! :create_with_view_paths!
13 alias :initialize_template_class_without_view_paths :initialize_template_class
14 alias :initialize_template_class :initialize_template_class_with_view_paths
18 def full_template_path(template)
19 view_paths.each do |path|
20 full_path = File.join(path, template)
21 return full_path unless Dir["#{full_path}.*"].empty?
26 def create_with_view_paths!(method_name, *parameters) #:nodoc:
27 initialize_defaults(method_name)
28 __send__(method_name, *parameters)
30 # If an explicit, textual body has not been set, we check assumptions.
31 unless String === @body
32 # First, we look to see if there are any likely templates that match,
33 # which include the content-type in their file name (i.e.,
34 # "the_template_file.text.html.erb", etc.). Only do this if parts
35 # have not already been specified manually.
37 # Radiant: begin modifications
38 full_path = full_template_path("#{mailer_name}/#{@template}")
39 templates = Dir.glob("#{full_path}.*")
40 # Radiant: end modifications
41 templates.each do |path|
42 basename = File.basename(path)
43 template_regex = Regexp.new("^([^\\\.]+)\\\.([^\\\.]+\\\.[^\\\.]+)\\\.(" + template_extensions.join('|') + ")$")
44 next unless md = template_regex.match(basename)
45 template_name = basename
46 content_type = md.captures[1].gsub('.', '/')
47 # Radiant: begin modifications
48 @parts << ActionMailer::Part.new(:content_type => content_type,
49 :disposition => "inline", :charset => charset,
50 :body => render_message(template_name, @body))
51 # Radiant: end modifications
54 @content_type = "multipart/alternative"
55 @parts = sort_parts(@parts, @implicit_parts_order)
59 # Then, if there were such templates, we check to see if we ought to
60 # also render a "normal" template (without the content type). If a
61 # normal template exists (or if there were no implicit parts) we render
63 template_exists = @parts.empty?
64 template_exists ||= Dir.glob("#{template_path}/#{@template}.*").any? { |i| File.basename(i).split(".").length == 2 }
65 @body = render_message(@template, @body) if template_exists
67 # Finally, if there are other message parts and a textual body exists,
68 # we shift it onto the front of the parts and set the body to nil (so
69 # that create_mail doesn't try to render it in addition to the parts).
70 if !@parts.empty? && String === @body
71 # Radiant: begin modifications
72 @parts.unshift ActionMailer::Part.new(:charset => charset, :body => @body)
73 # Radiant: end modifications
78 # If this is a multipart e-mail add the mime_version if it is not
80 @mime_version ||= "1.0" if !@parts.empty?
82 # build the mail object itself
86 def initialize_template_class_with_view_paths(assigns)
87 full_path = File.dirname(File.dirname(full_template_path("#{mailer_name}/#{@template}")))
88 ActionView::Base.new([full_path], assigns, self)
93 ActionMailer::Base.send(:include, MerbRadiant::MailerViewPathsExtension)