Ruby on Rails | Screencasts | Download | Documentation | Weblog | Community | Source

root/branches/1-2-stable/actionpack/lib/action_controller/helpers.rb

Revision 4952, 5.2 kB (checked in by david, 2 years ago)

Added deprecation language for in_place_editor and auto_complete_field that both pieces will become plugins by Rails 2.0 [DHH]

Line 
1 module ActionController #:nodoc:
2   module Helpers #:nodoc:
3     def self.included(base)
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       end
17     end
18
19     # The template helpers serve to relieve the templates from including the same inline code again and again. It's a
20     # set of standardized methods for working with forms (FormHelper), dates (DateHelper), texts (TextHelper), and
21     # Active Records (ActiveRecordHelper) that's available to all templates by default.
22     #
23     # It's also really easy to make your own helpers and it's much encouraged to keep the template files free
24     # from complicated logic. It's even encouraged to bundle common compositions of methods from other helpers
25     # (often the common helpers) as they're used by the specific application.
26     #
27     #   module MyHelper
28     #     def hello_world() "hello world" end
29     #   end
30     #
31     # MyHelper can now be included in a controller, like this:
32     #
33     #   class MyController < ActionController::Base
34     #     helper :my_helper
35     #   end
36     #
37     # ...and, same as above, used in any template rendered from MyController, like this:
38     #
39     # Let's hear what the helper has to say: <tt><%= hello_world %></tt>
40     module ClassMethods
41       # Makes all the (instance) methods in the helper module available to templates rendered through this controller.
42       # See ActionView::Helpers (link:classes/ActionView/Helpers.html) for more about making your own helper modules
43       # available to the templates.
44       def add_template_helper(helper_module) #:nodoc:
45         master_helper_module.send(:include, helper_module)
46       end
47
48       # Declare a helper:
49       #   helper :foo
50       # requires 'foo_helper' and includes FooHelper in the template class.
51       #   helper FooHelper
52       # includes FooHelper in the template class.
53       #   helper { def foo() "#{bar} is the very best" end }
54       # evaluates the block in the template class, adding method #foo.
55       #   helper(:three, BlindHelper) { def mice() 'mice' end }
56       # does all three.
57       def helper(*args, &block)
58         args.flatten.each do |arg|
59           case arg
60             when Module
61               add_template_helper(arg)
62             when String, Symbol
63               file_name  = arg.to_s.underscore + '_helper'
64               class_name = file_name.camelize
65                
66               begin
67                 require_dependency(file_name)
68               rescue LoadError => load_error
69                 requiree = / -- (.*?)(\.rb)?$/.match(load_error).to_a[1]
70                 msg = (requiree == file_name) ? "Missing helper file helpers/#{file_name}.rb" : "Can't load file: #{requiree}"
71                 raise LoadError.new(msg).copy_blame!(load_error)
72               end
73
74               add_template_helper(class_name.constantize)
75             else
76               raise ArgumentError, 'helper expects String, Symbol, or Module argument'
77           end
78         end
79
80         # Evaluate block in template class if given.
81         master_helper_module.module_eval(&block) if block_given?
82       end
83
84       # Declare a controller method as a helper.  For example,
85       #   helper_method :link_to
86       #   def link_to(name, options) ... end
87       # makes the link_to controller method available in the view.
88       def helper_method(*methods)
89         methods.flatten.each do |method|
90           master_helper_module.module_eval <<-end_eval
91             def #{method}(*args, &block)
92               controller.send(%(#{method}), *args, &block)
93             end
94           end_eval
95         end
96       end
97
98       # Declare a controller attribute as a helper.  For example,
99       #   helper_attr :name
100       #   attr_accessor :name
101       # makes the name and name= controller methods available in the view.
102       # The is a convenience wrapper for helper_method.
103       def helper_attr(*attrs)
104         attrs.flatten.each { |attr| helper_method(attr, "#{attr}=") }
105       end
106
107       private
108         def default_helper_module!
109           module_name = name.sub(/Controller$|$/, 'Helper')
110           module_path = module_name.split('::').map { |m| m.underscore }.join('/')
111           require_dependency module_path
112           helper module_name.constantize
113         rescue LoadError
114           logger.debug("#{name}: missing default helper path #{module_path}") if logger
115         rescue NameError
116           logger.debug("#{name}: missing default helper module #{module_name}") if logger
117         end
118
119         def inherited_with_helper(child)
120           inherited_without_helper(child)
121           begin
122             child.master_helper_module = Module.new
123             child.master_helper_module.send :include, master_helper_module
124             child.send :default_helper_module!
125           rescue MissingSourceFile => e
126             raise unless e.is_missing?("helpers/#{child.controller_path}_helper")
127           end
128         end
129     end
130   end
131 end
Note: See TracBrowser for help on using the browser.