aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack/lib')
-rw-r--r--actionpack/lib/abstract_controller.rb1
-rw-r--r--actionpack/lib/abstract_controller/collector.rb30
-rw-r--r--actionpack/lib/abstract_controller/layouts.rb3
-rw-r--r--actionpack/lib/abstract_controller/rendering.rb4
-rw-r--r--actionpack/lib/action_controller/metal/helpers.rb79
-rw-r--r--actionpack/lib/action_controller/metal/mime_responds.rb29
-rw-r--r--actionpack/lib/action_controller/metal/rendering.rb4
-rw-r--r--actionpack/lib/action_controller/railtie.rb4
-rw-r--r--actionpack/lib/action_dispatch/middleware/stack.rb14
-rw-r--r--actionpack/lib/action_dispatch/routing/mapper.rb5
-rw-r--r--actionpack/lib/action_view/base.rb6
-rw-r--r--actionpack/lib/action_view/helpers/translation_helper.rb8
-rw-r--r--actionpack/lib/action_view/template.rb4
-rw-r--r--actionpack/lib/action_view/template/resolver.rb13
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