GitHub Sale: sign up for any paid plan this week and pay nothing until January 1, 2009!  [ hide ]

public
Fork of halorgium/mephisto
Description: A mirror of the mephisto code-base
Homepage: http://mephistoblog.com/
Clone URL: git://github.com/zmack/mephisto.git
svenfuchs (author)
Wed Feb 20 11:11:20 -0800 2008
commit  1ad1b56b4a6c9284534b0afbb9d5d87715ae4312
tree    adc435b61f05728a991fd314188bc3e75cfb6038
parent  2772ec18227b04b3cb618748a2900a7b93b84d94
mephisto / vendor / plugins / engines / lib / engines / rails_extensions / action_mailer.rb
100644 85 lines (78 sloc) 4.044 kb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# The way ActionMailer is coded in terms of finding templates is very restrictive, to the point
# where all templates for rendering must exist under the single base path. This is difficult to
# work around without re-coding significant parts of the action mailer code.
#
# ---
#
# The MailTemplates module overrides two (private) methods from ActionMailer to enable mail
# templates within plugins:
#
# [+template_path+] which now produces the contents of #template_paths
# [+initialize_template_class+] which now find the first matching template and creates
# an ActionVew::Base instance with the correct view_paths
#
# Ideally ActionMailer would use the same template-location logic as ActionView, and the same
# view paths as ActionController::Base.view_paths, but it currently does not.
module Engines::RailsExtensions::ActionMailer
  def self.included(base) #:nodoc:
    base.class_eval do
      # TODO commented this out because it seems to break ActionMailer
      # how can this be fixed?
      
      alias_method_chain :template_path, :engine_additions
      alias_method_chain :initialize_template_class, :engine_additions
    end
  end
 
  private
  
    #--
    # ActionMailer::Base#create uses two mechanisms to determine the proper template file(s)
    # to load. Firstly, it searches within the template_root for files that much the explicit
    # (or implicit) part encodings (like signup.text.plain.erb for the signup action).
    # This is how implicit multipart emails are built, by the way.
    #
    # Secondly, it then creates an ActionMailer::Base instance with it's view_paths parameter
    # set to the template_root, so that ActionMailer will then take over rendering the
    # templates.
    #
    # Ideally, ActionMailer would pass the same set of view paths as it gets in a normal
    # request (i.e. ActionController::Base.view_paths), so that all possible view paths
    # were searched. However, this seems to introduce some problems with helper modules.
    #
    # So instead, and because we have to fool these two independent parts of ActionMailer,
    # we fudge with the mechanisms it uses to find the templates (via template_paths, and
    # template_path_with_engine_additions), and then intercept the creation of the ActionView
    # instance so we can set the view_paths (in initialize_template_class_with_engine_additions).
    #++
  
    # Returns all possible template paths for the current mailer, including those
    # within the loaded plugins.
    def template_paths
      paths = Engines.plugins.by_precedence.map { |p| "#{p.directory}/app/views/#{mailer_name}" }
      paths.unshift(template_path_without_engine_additions) unless Engines.disable_application_view_loading
      paths
    end
 
    # Return something that Dir[] can glob against. This method is called in
    # ActionMailer::Base#create! and used as part of an argument to Dir. We can
    # take advantage of this by using some of the features of Dir.glob to search
    # multiple paths for matching files.
    def template_path_with_engine_additions
      "{#{template_paths.join(",")}}"
    end
 
    # Return an instance of ActionView::Base with the view paths set to all paths
    # in ActionController::Base.view_paths (i.e. including all plugin view paths)
    def initialize_template_class_with_engine_additions(assigns)
      # I'd like to just return this, but I get problems finding methods in helper
      # modules if the method implemention from the regular class is not called
      #
      # ActionView::Base.new(ActionController::Base.view_paths.dup, assigns, self)
      renderer = initialize_template_class_without_engine_additions(assigns)
      renderer.view_paths = ActionController::Base.view_paths.dup
      renderer
    end
end
 
# We don't need to do this if ActionMailer hasn't been loaded.
if Object.const_defined?(:ActionMailer)
  module ::ActionMailer #:nodoc:
    class Base #:nodoc:
      include Engines::RailsExtensions::ActionMailer
    end
  end
end