Froze rails gems
[depot.git] / vendor / rails / actionmailer / lib / action_mailer / helpers.rb
1 module ActionMailer
2 module Helpers #:nodoc:
3 def self.included(base) #:nodoc:
4 # Initialize the base module to aggregate its helpers.
5 base.class_inheritable_accessor :master_helper_module
6 base.master_helper_module = Module.new
7
8 # Extend base with class methods to declare helpers.
9 base.extend(ClassMethods)
10
11 base.class_eval do
12 # Wrap inherited to create a new master helper module for subclasses.
13 class << self
14 alias_method_chain :inherited, :helper
15 end
16
17 # Wrap initialize_template_class to extend new template class
18 # instances with the master helper module.
19 alias_method_chain :initialize_template_class, :helper
20 end
21 end
22
23 module ClassMethods
24 # Makes all the (instance) methods in the helper module available to templates rendered through this controller.
25 # See ActionView::Helpers (link:classes/ActionView/Helpers.html) for more about making your own helper modules
26 # available to the templates.
27 def add_template_helper(helper_module) #:nodoc:
28 master_helper_module.module_eval "include #{helper_module}"
29 end
30
31 # Declare a helper:
32 # helper :foo
33 # requires 'foo_helper' and includes FooHelper in the template class.
34 # helper FooHelper
35 # includes FooHelper in the template class.
36 # helper { def foo() "#{bar} is the very best" end }
37 # evaluates the block in the template class, adding method +foo+.
38 # helper(:three, BlindHelper) { def mice() 'mice' end }
39 # does all three.
40 def helper(*args, &block)
41 args.flatten.each do |arg|
42 case arg
43 when Module
44 add_template_helper(arg)
45 when String, Symbol
46 file_name = arg.to_s.underscore + '_helper'
47 class_name = file_name.camelize
48
49 begin
50 require_dependency(file_name)
51 rescue LoadError => load_error
52 requiree = / -- (.*?)(\.rb)?$/.match(load_error.message).to_a[1]
53 msg = (requiree == file_name) ? "Missing helper file helpers/#{file_name}.rb" : "Can't load file: #{requiree}"
54 raise LoadError.new(msg).copy_blame!(load_error)
55 end
56
57 add_template_helper(class_name.constantize)
58 else
59 raise ArgumentError, 'helper expects String, Symbol, or Module argument'
60 end
61 end
62
63 # Evaluate block in template class if given.
64 master_helper_module.module_eval(&block) if block_given?
65 end
66
67 # Declare a controller method as a helper. For example,
68 # helper_method :link_to
69 # def link_to(name, options) ... end
70 # makes the link_to controller method available in the view.
71 def helper_method(*methods)
72 methods.flatten.each do |method|
73 master_helper_module.module_eval <<-end_eval
74 def #{method}(*args, &block)
75 controller.__send__(%(#{method}), *args, &block)
76 end
77 end_eval
78 end
79 end
80
81 # Declare a controller attribute as a helper. For example,
82 # helper_attr :name
83 # attr_accessor :name
84 # makes the name and name= controller methods available in the view.
85 # The is a convenience wrapper for helper_method.
86 def helper_attr(*attrs)
87 attrs.flatten.each { |attr| helper_method(attr, "#{attr}=") }
88 end
89
90 private
91 def inherited_with_helper(child)
92 inherited_without_helper(child)
93 begin
94 child.master_helper_module = Module.new
95 child.master_helper_module.__send__(:include, master_helper_module)
96 child.helper child.name.to_s.underscore
97 rescue MissingSourceFile => e
98 raise unless e.is_missing?("helpers/#{child.name.to_s.underscore}_helper")
99 end
100 end
101 end
102
103 private
104 # Extend the template class instance with our controller's helper module.
105 def initialize_template_class_with_helper(assigns)
106 returning(template = initialize_template_class_without_helper(assigns)) do
107 template.extend self.class.master_helper_module
108 end
109 end
110 end
111 end