diff options
Diffstat (limited to 'actionpack/lib')
-rw-r--r-- | actionpack/lib/abstract_controller.rb | 1 | ||||
-rw-r--r-- | actionpack/lib/abstract_controller/collector.rb | 30 | ||||
-rw-r--r-- | actionpack/lib/abstract_controller/layouts.rb | 3 | ||||
-rw-r--r-- | actionpack/lib/abstract_controller/rendering.rb | 4 | ||||
-rw-r--r-- | actionpack/lib/action_controller/metal/helpers.rb | 79 | ||||
-rw-r--r-- | actionpack/lib/action_controller/metal/mime_responds.rb | 29 | ||||
-rw-r--r-- | actionpack/lib/action_controller/metal/rendering.rb | 4 | ||||
-rw-r--r-- | actionpack/lib/action_controller/railtie.rb | 4 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/middleware/stack.rb | 14 | ||||
-rw-r--r-- | actionpack/lib/action_dispatch/routing/mapper.rb | 5 | ||||
-rw-r--r-- | actionpack/lib/action_view/base.rb | 6 | ||||
-rw-r--r-- | actionpack/lib/action_view/helpers/translation_helper.rb | 8 | ||||
-rw-r--r-- | actionpack/lib/action_view/template.rb | 4 | ||||
-rw-r--r-- | actionpack/lib/action_view/template/resolver.rb | 13 |
14 files changed, 124 insertions, 80 deletions
diff --git a/actionpack/lib/abstract_controller.rb b/actionpack/lib/abstract_controller.rb index 725d8fb8fc..2c2ef16622 100644 --- a/actionpack/lib/abstract_controller.rb +++ b/actionpack/lib/abstract_controller.rb @@ -10,6 +10,7 @@ module AbstractController autoload :Base autoload :Callbacks + autoload :Collector autoload :Helpers autoload :Layouts autoload :LocalizedCache diff --git a/actionpack/lib/abstract_controller/collector.rb b/actionpack/lib/abstract_controller/collector.rb new file mode 100644 index 0000000000..d429333661 --- /dev/null +++ b/actionpack/lib/abstract_controller/collector.rb @@ -0,0 +1,30 @@ +module AbstractController + module Collector + def self.generate_method_for_mime(mime) + sym = mime.is_a?(Symbol) ? mime : mime.to_sym + const = sym.to_s.upcase + class_eval <<-RUBY, __FILE__, __LINE__ + 1 + def #{sym}(*args, &block) # def html(*args, &block) + custom(Mime::#{const}, *args, &block) # custom(Mime::HTML, *args, &block) + end # end + RUBY + end + + Mime::SET.each do |mime| + generate_method_for_mime(mime) + end + + protected + + def method_missing(symbol, &block) + mime_constant = Mime.const_get(symbol.to_s.upcase) + + if Mime::SET.include?(mime_constant) + AbstractController::Collector.generate_method_for_mime(mime_constant) + send(symbol, &block) + else + super + end + end + end +end
\ No newline at end of file diff --git a/actionpack/lib/abstract_controller/layouts.rb b/actionpack/lib/abstract_controller/layouts.rb index 6fbf6bc392..56ddf9bf01 100644 --- a/actionpack/lib/abstract_controller/layouts.rb +++ b/actionpack/lib/abstract_controller/layouts.rb @@ -270,6 +270,9 @@ module AbstractController end end ruby_eval + when Proc + define_method :_layout_from_proc, &@_layout + self.class_eval %{def _layout(details) _layout_from_proc(self) end} when false self.class_eval %{def _layout(details) end} when true diff --git a/actionpack/lib/abstract_controller/rendering.rb b/actionpack/lib/abstract_controller/rendering.rb index a168b1b4c5..1dec3f2c3e 100644 --- a/actionpack/lib/abstract_controller/rendering.rb +++ b/actionpack/lib/abstract_controller/rendering.rb @@ -41,10 +41,6 @@ module AbstractController # Mostly abstracts the fact that calling render twice is a DoubleRenderError. # Delegates render_to_body and sticks the result in self.response_body. def render(*args, &block) - if response_body - raise AbstractController::DoubleRenderError - end - options = _normalize_options(*args, &block) self.response_body = render_to_body(options) end diff --git a/actionpack/lib/action_controller/metal/helpers.rb b/actionpack/lib/action_controller/metal/helpers.rb index 0e3db86861..03ba4b3f83 100644 --- a/actionpack/lib/action_controller/metal/helpers.rb +++ b/actionpack/lib/action_controller/metal/helpers.rb @@ -50,12 +50,19 @@ module ActionController include AbstractController::Helpers included do - extlib_inheritable_accessor(:helpers_path) do - defined?(Rails::Application) ? Rails::Application.paths.app.helpers.to_a : [] - end + extlib_inheritable_accessor(:helpers_path) + self.helpers_path = [] end module ClassMethods + def helpers_dir + self.helpers_path + end + + def helpers_dir=(value) + self.helpers_path = Array(value) + end + def inherited(klass) klass.class_eval { default_helper_module! unless name.blank? } super @@ -79,42 +86,42 @@ module ActionController @helper_proxy ||= ActionView::Base.new.extend(_helpers) end - private - # Overwrite _modules_for_helpers to accept :all as argument, which loads - # all helpers in helpers_dir. - # - # ==== Parameters - # args<Array[String, Symbol, Module, all]>:: A list of helpers - # - # ==== Returns - # Array[Module]:: A normalized list of modules for the list of - # helpers provided. - def _modules_for_helpers(args) - args += all_application_helpers if args.delete(:all) - super(args) - end + private + # Overwrite _modules_for_helpers to accept :all as argument, which loads + # all helpers in helpers_dir. + # + # ==== Parameters + # args<Array[String, Symbol, Module, all]>:: A list of helpers + # + # ==== Returns + # Array[Module]:: A normalized list of modules for the list of + # helpers provided. + def _modules_for_helpers(args) + args += all_application_helpers if args.delete(:all) + super(args) + end - def default_helper_module! - module_name = name.sub(/Controller$/, '') - module_path = module_name.underscore - helper module_path - rescue MissingSourceFile => e - raise e unless e.is_missing? "helpers/#{module_path}_helper" - rescue NameError => e - raise e unless e.missing_name? "#{module_name}Helper" - end + def default_helper_module! + module_name = name.sub(/Controller$/, '') + module_path = module_name.underscore + helper module_path + rescue MissingSourceFile => e + raise e unless e.is_missing? "helpers/#{module_path}_helper" + rescue NameError => e + raise e unless e.missing_name? "#{module_name}Helper" + end - # Extract helper names from files in app/helpers/**/*_helper.rb - def all_application_helpers - helpers = [] - helpers_path.each do |path| - extract = /^#{Regexp.quote(path)}\/?(.*)_helper.rb$/ - helpers += Dir["#{path}/**/*_helper.rb"].map { |file| file.sub(extract, '\1') } + # Extract helper names from files in app/helpers/**/*_helper.rb + def all_application_helpers + helpers = [] + helpers_path.each do |path| + extract = /^#{Regexp.quote(path)}\/?(.*)_helper.rb$/ + helpers += Dir["#{path}/**/*_helper.rb"].map { |file| file.sub(extract, '\1') } + end + helpers.sort! + helpers.uniq! + helpers end - helpers.sort! - helpers.uniq! - helpers - end end end end diff --git a/actionpack/lib/action_controller/metal/mime_responds.rb b/actionpack/lib/action_controller/metal/mime_responds.rb index 4c02677729..08599d660e 100644 --- a/actionpack/lib/action_controller/metal/mime_responds.rb +++ b/actionpack/lib/action_controller/metal/mime_responds.rb @@ -1,3 +1,5 @@ +require 'abstract_controller/collector' + module ActionController #:nodoc: module MimeResponds #:nodoc: extend ActiveSupport::Concern @@ -265,6 +267,7 @@ module ActionController #:nodoc: end class Collector #:nodoc: + include AbstractController::Collector attr_accessor :order def initialize(&block) @@ -289,32 +292,6 @@ module ActionController #:nodoc: def response_for(mime) @responses[mime] || @responses[Mime::ALL] || @default_response end - - def self.generate_method_for_mime(mime) - sym = mime.is_a?(Symbol) ? mime : mime.to_sym - const = sym.to_s.upcase - class_eval <<-RUBY, __FILE__, __LINE__ + 1 - def #{sym}(&block) # def html(&block) - custom(Mime::#{const}, &block) # custom(Mime::HTML, &block) - end # end - RUBY - end - - Mime::SET.each do |mime| - generate_method_for_mime(mime) - end - - def method_missing(symbol, &block) - mime_constant = Mime.const_get(symbol.to_s.upcase) - - if Mime::SET.include?(mime_constant) - self.class.generate_method_for_mime(mime_constant) - send(symbol, &block) - else - super - end - end - end end end diff --git a/actionpack/lib/action_controller/metal/rendering.rb b/actionpack/lib/action_controller/metal/rendering.rb index 72e2bbd00e..8f03035b2b 100644 --- a/actionpack/lib/action_controller/metal/rendering.rb +++ b/actionpack/lib/action_controller/metal/rendering.rb @@ -13,6 +13,10 @@ module ActionController end def render(*args) + if response_body + raise ::AbstractController::DoubleRenderError + end + args << {} unless args.last.is_a?(Hash) super(*args) self.content_type ||= args.last[:_template].mime_type.to_s diff --git a/actionpack/lib/action_controller/railtie.rb b/actionpack/lib/action_controller/railtie.rb index 29a0a346ec..9151de4462 100644 --- a/actionpack/lib/action_controller/railtie.rb +++ b/actionpack/lib/action_controller/railtie.rb @@ -21,5 +21,9 @@ module ActionController initializer "action_controller.initialize_framework_caches" do ActionController::Base.cache_store ||= RAILS_CACHE end + + initializer "action_controller.set_helpers_path" do |app| + ActionController::Base.helpers_path = app.config.paths.app.helpers.to_a + end end end diff --git a/actionpack/lib/action_dispatch/middleware/stack.rb b/actionpack/lib/action_dispatch/middleware/stack.rb index 0dc1d70e37..18a2922fa7 100644 --- a/actionpack/lib/action_dispatch/middleware/stack.rb +++ b/actionpack/lib/action_dispatch/middleware/stack.rb @@ -55,7 +55,11 @@ module ActionDispatch when Class klass == middleware else - klass == ActiveSupport::Inflector.constantize(middleware.to_s) + if lazy_compare?(@klass) && lazy_compare?(middleware) + normalize(@klass) == normalize(middleware) + else + klass == ActiveSupport::Inflector.constantize(middleware.to_s) + end end end @@ -72,6 +76,14 @@ module ActionDispatch end private + def lazy_compare?(object) + object.is_a?(String) || object.is_a?(Symbol) + end + + def normalize(object) + object.to_s.strip.sub(/^::/, '') + end + def build_args Array(args).map { |arg| arg.respond_to?(:call) ? arg.call : arg } end diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index fcbb70749f..5199984814 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -157,10 +157,11 @@ module ActionDispatch end # Invokes Rack::Mount::Utils.normalize path and ensure that - # (:locale) becomes (/:locale) instead of /(:locale). + # (:locale) becomes (/:locale) instead of /(:locale). Except + # for root cases, where the latter is the correct one. def self.normalize_path(path) path = Rack::Mount::Utils.normalize_path(path) - path.sub!(%r{/\(+/?:}, '(/:') + path.sub!(%r{/(\(+)/?:}, '\1/:') unless path =~ %r{^/\(+:.*\)$} path end diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index c4b0455c2a..af13f2cd3e 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -276,9 +276,11 @@ module ActionView #:nodoc: @config = nil @formats = formats @assigns = assigns_for_first_render.each { |key, value| instance_variable_set("@#{key}", value) } - @_controller = controller @helpers = self.class.helpers || Module.new - @_content_for = Hash.new {|h,k| h[k] = ActionView::SafeBuffer.new } + + @_controller = controller + @_content_for = Hash.new {|h,k| h[k] = ActionView::SafeBuffer.new } + @_virtual_path = nil self.view_paths = view_paths end diff --git a/actionpack/lib/action_view/helpers/translation_helper.rb b/actionpack/lib/action_view/helpers/translation_helper.rb index 35c431d78d..ad18339c60 100644 --- a/actionpack/lib/action_view/helpers/translation_helper.rb +++ b/actionpack/lib/action_view/helpers/translation_helper.rb @@ -25,11 +25,15 @@ module ActionView end alias :l :localize - private + def scope_key_by_partial(key) if key.to_s.first == "." - template.path_without_format_and_extension.gsub(%r{/_?}, ".") + key.to_s + if @_virtual_path + @_virtual_path.gsub(%r{/_?}, ".") + key.to_s + else + raise "Cannot use t(#{key.inspect}) shortcut because path is not available" + end else key end diff --git a/actionpack/lib/action_view/template.rb b/actionpack/lib/action_view/template.rb index adaf6544a7..cd6b1930a1 100644 --- a/actionpack/lib/action_view/template.rb +++ b/actionpack/lib/action_view/template.rb @@ -87,9 +87,9 @@ module ActionView source = <<-end_src def #{method_name}(local_assigns) - old_output_buffer = output_buffer;#{locals_code};#{code} + _old_virtual_path, @_virtual_path = @_virtual_path, #{@details[:virtual_path].inspect};_old_output_buffer = output_buffer;#{locals_code};#{code} ensure - self.output_buffer = old_output_buffer + @_virtual_path, self.output_buffer = _old_virtual_path, _old_output_buffer end end_src diff --git a/actionpack/lib/action_view/template/resolver.rb b/actionpack/lib/action_view/template/resolver.rb index c6a17907ff..340a6afe5e 100644 --- a/actionpack/lib/action_view/template/resolver.rb +++ b/actionpack/lib/action_view/template/resolver.rb @@ -117,15 +117,18 @@ module ActionView # # :api: plugin def path_to_details(path) # [:erb, :format => :html, :locale => :en, :partial => true/false] - if m = path.match(%r'(?:^|/)(_)?[\w-]+((?:\.[\w-]+)*)\.(\w+)$') - partial = m[1] == '_' - details = (m[2]||"").split('.').reject { |e| e.empty? } - handler = Template.handler_class_for_extension(m[3]) + if m = path.match(%r'((^|.*/)(_)?[\w-]+)((?:\.[\w-]+)*)\.(\w+)$') + partial = m[3] == '_' + details = (m[4]||"").split('.').reject { |e| e.empty? } + handler = Template.handler_class_for_extension(m[5]) format = Mime[details.last] && details.pop.to_sym locale = details.last && details.pop.to_sym - return handler, :format => format, :locale => locale, :partial => partial + virtual_path = (m[1].gsub("#{@path}/", "") << details.join(".")) + + return handler, :format => format, :locale => locale, :partial => partial, + :virtual_path => virtual_path end end end |