aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack
diff options
context:
space:
mode:
Diffstat (limited to 'actionpack')
-rw-r--r--actionpack/lib/abstract_controller.rb1
-rw-r--r--actionpack/lib/abstract_controller/rendering.rb30
-rw-r--r--actionpack/lib/abstract_controller/view_paths.rb3
-rw-r--r--actionpack/lib/action_controller/metal/http_authentication.rb22
-rw-r--r--actionpack/lib/action_dispatch/http/mime_negotiation.rb15
-rw-r--r--actionpack/lib/action_view.rb1
-rw-r--r--actionpack/lib/action_view/base.rb2
-rw-r--r--actionpack/lib/action_view/lookup_context.rb57
-rw-r--r--actionpack/lib/action_view/template.rb32
-rw-r--r--actionpack/lib/action_view/template/resolver.rb36
-rw-r--r--actionpack/lib/action_view/template/text.rb6
-rw-r--r--actionpack/test/lib/fixture_template.rb8
-rw-r--r--actionpack/test/template/compiled_templates_test.rb3
-rw-r--r--actionpack/test/template/render_test.rb8
14 files changed, 110 insertions, 114 deletions
diff --git a/actionpack/lib/abstract_controller.rb b/actionpack/lib/abstract_controller.rb
index 7028cd0379..2da4dc052c 100644
--- a/actionpack/lib/abstract_controller.rb
+++ b/actionpack/lib/abstract_controller.rb
@@ -7,6 +7,7 @@ require 'active_support/core_ext/class/attribute'
require 'active_support/core_ext/module/attr_internal'
require 'active_support/core_ext/module/delegation'
require 'active_support/core_ext/module/anonymous'
+require 'active_support/i18n'
module AbstractController
extend ActiveSupport::Autoload
diff --git a/actionpack/lib/abstract_controller/rendering.rb b/actionpack/lib/abstract_controller/rendering.rb
index 5048754e33..42f4939108 100644
--- a/actionpack/lib/abstract_controller/rendering.rb
+++ b/actionpack/lib/abstract_controller/rendering.rb
@@ -9,10 +9,38 @@ module AbstractController
end
end
+ # This is a class to fix I18n global state. Whenever you provide I18n.locale during a request,
+ # it will trigger the lookup_context and consequently expire the cache.
+ # TODO Add some deprecation warnings to remove I18n.locale from controllers
+ class I18nProxy < ::I18n::Config #:nodoc:
+ attr_reader :i18n_config, :lookup_context
+
+ def initialize(i18n_config, lookup_context)
+ @i18n_config, @lookup_context = i18n_config, lookup_context
+ end
+
+ def locale
+ @i18n_config.locale
+ end
+
+ def locale=(value)
+ @i18n_config.locale = value
+ @lookup_context.update_details(:locale => @i18n_config.locale)
+ end
+ end
+
module Rendering
extend ActiveSupport::Concern
include AbstractController::ViewPaths
+ # Overwrite process to setup I18n proxy.
+ def process(*) #:nodoc:
+ old_config, I18n.config = I18n.config, I18nProxy.new(I18n.config, lookup_context)
+ super
+ ensure
+ I18n.config = old_config
+ end
+
# An instance of a view class. The default view class is ActionView::Base
#
# The view class must have the following methods:
@@ -108,7 +136,7 @@ module AbstractController
end
def _with_template_hook(template)
- self.formats = template.details[:formats]
+ self.formats = template.formats
end
end
end
diff --git a/actionpack/lib/abstract_controller/view_paths.rb b/actionpack/lib/abstract_controller/view_paths.rb
index 6513c0778e..c2a9f6336d 100644
--- a/actionpack/lib/abstract_controller/view_paths.rb
+++ b/actionpack/lib/abstract_controller/view_paths.rb
@@ -7,7 +7,8 @@ module AbstractController
self._view_paths = ActionView::PathSet.new
end
- delegate :template_exists?, :view_paths, :formats, :formats=, :to => :lookup_context
+ delegate :template_exists?, :view_paths, :formats, :formats=,
+ :locale, :locale=, :to => :lookup_context
# LookupContext is the object responsible to hold all information required to lookup
# templates, i.e. view paths and details. Check ActionView::LookupContext for more
diff --git a/actionpack/lib/action_controller/metal/http_authentication.rb b/actionpack/lib/action_controller/metal/http_authentication.rb
index f1355a83a3..6ec788f302 100644
--- a/actionpack/lib/action_controller/metal/http_authentication.rb
+++ b/actionpack/lib/action_controller/metal/http_authentication.rb
@@ -124,7 +124,7 @@ module ActionController
end
def authenticate(request, &login_procedure)
- unless authorization(request).blank?
+ unless request.authorization.blank?
login_procedure.call(*user_name_and_password(request))
end
end
@@ -133,15 +133,8 @@ module ActionController
decode_credentials(request).split(/:/, 2)
end
- def authorization(request)
- request.env['HTTP_AUTHORIZATION'] ||
- request.env['X-HTTP_AUTHORIZATION'] ||
- request.env['X_HTTP_AUTHORIZATION'] ||
- request.env['REDIRECT_X_HTTP_AUTHORIZATION']
- end
-
def decode_credentials(request)
- ActiveSupport::Base64.decode64(authorization(request).split(' ', 2).last || '')
+ ActiveSupport::Base64.decode64(request.authorization.split(' ', 2).last || '')
end
def encode_credentials(user_name, password)
@@ -176,14 +169,7 @@ module ActionController
# Returns false on a valid response, true otherwise
def authenticate(secret_key, request, realm, &password_procedure)
- authorization(request) && validate_digest_response(secret_key, request, realm, &password_procedure)
- end
-
- def authorization(request)
- request.env['HTTP_AUTHORIZATION'] ||
- request.env['X-HTTP_AUTHORIZATION'] ||
- request.env['X_HTTP_AUTHORIZATION'] ||
- request.env['REDIRECT_X_HTTP_AUTHORIZATION']
+ request.authorization && validate_digest_response(secret_key, request, realm, &password_procedure)
end
# Returns false unless the request credentials response value matches the expected value.
@@ -226,7 +212,7 @@ module ActionController
end
def decode_credentials_header(request)
- decode_credentials(authorization(request))
+ decode_credentials(request.authorization)
end
def decode_credentials(header)
diff --git a/actionpack/lib/action_dispatch/http/mime_negotiation.rb b/actionpack/lib/action_dispatch/http/mime_negotiation.rb
index 40617e239a..fec250e928 100644
--- a/actionpack/lib/action_dispatch/http/mime_negotiation.rb
+++ b/actionpack/lib/action_dispatch/http/mime_negotiation.rb
@@ -67,21 +67,6 @@ module ActionDispatch
@env["action_dispatch.request.formats"] = [Mime::Type.lookup_by_extension(parameters[:format])]
end
- # Returns a symbolized version of the <tt>:format</tt> parameter of the request.
- # If no \format is given it returns <tt>:js</tt>for Ajax requests and <tt>:html</tt>
- # otherwise.
- def template_format
- parameter_format = parameters[:format]
-
- if parameter_format
- parameter_format
- elsif xhr?
- :js
- else
- :html
- end
- end
-
# Receives an array of mimes and return the first user sent mime that
# matches the order array.
#
diff --git a/actionpack/lib/action_view.rb b/actionpack/lib/action_view.rb
index 7e9ac8720c..afe6386105 100644
--- a/actionpack/lib/action_view.rb
+++ b/actionpack/lib/action_view.rb
@@ -58,6 +58,7 @@ module ActionView
autoload :TestCase, 'action_view/test_case'
end
+require 'active_support/i18n'
require 'active_support/core_ext/string/output_safety'
I18n.load_path << "#{File.dirname(__FILE__)}/action_view/locale/en.yml"
diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb
index 564ea6684c..ffe3060404 100644
--- a/actionpack/lib/action_view/base.rb
+++ b/actionpack/lib/action_view/base.rb
@@ -194,7 +194,7 @@ module ActionView #:nodoc:
attr_accessor :base_path, :assigns, :template_extension, :lookup_context
attr_internal :captures, :request, :layout, :controller, :template, :config
- delegate :find, :exists?, :formats, :formats=,
+ delegate :find, :exists?, :formats, :formats=, :locale, :locale=,
:view_paths, :view_paths=, :with_fallbacks, :update_details, :to => :lookup_context
delegate :request_forgery_protection_token, :template, :params, :session, :cookies, :response, :headers,
diff --git a/actionpack/lib/action_view/lookup_context.rb b/actionpack/lib/action_view/lookup_context.rb
index 4a4dc0d06c..91885c7370 100644
--- a/actionpack/lib/action_view/lookup_context.rb
+++ b/actionpack/lib/action_view/lookup_context.rb
@@ -1,4 +1,5 @@
require 'active_support/core_ext/object/try'
+require 'active_support/core_ext/object/blank'
module ActionView
# LookupContext is the object responsible to hold all information required to lookup
@@ -14,16 +15,14 @@ module ActionView
def self.register_detail(name, options = {})
registered_details[name] = lambda do |value|
- value = (value.blank? || options[:accessible] == false) ?
- Array(yield) : Array(value)
+ value = Array(value.presence || yield)
value |= [nil] unless options[:allow_nil] == false
value
end
end
register_detail(:formats) { Mime::SET.symbols }
- register_detail(:locale, :accessible => false) { [I18n.locale] }
- register_detail(:handlers, :accessible => false) { Template::Handlers.extensions }
+ register_detail(:locale) { [I18n.locale] }
class DetailsKey #:nodoc:
attr_reader :details
@@ -38,16 +37,12 @@ module ActionView
def initialize(details)
@details, @hash = details, details.hash
end
-
- def outdated?(details)
- @details != details
- end
end
def initialize(view_paths, details = {})
+ @details_key = nil
self.view_paths = view_paths
self.details = details
- @details_key = nil
end
module ViewPaths
@@ -60,18 +55,15 @@ module ActionView
end
def find(name, prefix = nil, partial = false)
- key = details_key
- @view_paths.find(name, prefix, partial || false, key.details, key)
+ @view_paths.find(name, prefix, partial || false, details, details_key)
end
def find_all(name, prefix = nil, partial = false)
- key = details_key
- @view_paths.find_all(name, prefix, partial || false, key.details, key)
+ @view_paths.find_all(name, prefix, partial || false, details, details_key)
end
def exists?(name, prefix = nil, partial = false)
- key = details_key
- @view_paths.exists?(name, prefix, partial || false, key.details, key)
+ @view_paths.exists?(name, prefix, partial || false, details, details_key)
end
# Add fallbacks to the view paths. Useful in cases you are rendering a file.
@@ -89,25 +81,20 @@ module ActionView
end
module Details
- def details
- @details = normalize_details(@details)
- end
+ attr_reader :details
- def details=(new_details)
- @details = new_details
- details
+ def details=(details)
+ @details = normalize_details(details)
+ @details_key = nil if @details_key && @details_key.details != @details
end
- # TODO This is too expensive. Revisit this.
def details_key
- latest_details = self.details
- @details_key = nil if @details_key.try(:outdated?, latest_details)
- @details_key ||= DetailsKey.get(latest_details)
+ @details_key ||= DetailsKey.get(@details)
end
# Shortcut to read formats from details.
def formats
- self.details[:formats]
+ @details[:formats].compact
end
# Shortcut to set formats in details.
@@ -115,11 +102,25 @@ module ActionView
self.details = @details.merge(:formats => value)
end
+ # Shortcut to read locale.
+ def locale
+ I18n.locale
+ end
+
+ # Shortcut to set locale in details and I18n.
+ def locale=(value)
+ I18n.locale = value
+
+ unless I18n.config.respond_to?(:lookup_context)
+ self.details = @details.merge(:locale => value)
+ end
+ end
+
# Update the details keys by merging the given hash into the current
# details hash. If a block is given, the details are modified just during
# the execution of the block and reverted to the previous value after.
def update_details(new_details)
- old_details = self.details
+ old_details = @details
self.details = old_details.merge(new_details)
if block_given?
@@ -140,7 +141,7 @@ module ActionView
self.class.registered_details.each do |k, v|
details[k] = v.call(details[k])
end
- details
+ details.freeze
end
end
diff --git a/actionpack/lib/action_view/template.rb b/actionpack/lib/action_view/template.rb
index cd6b1930a1..b4fdb49d3b 100644
--- a/actionpack/lib/action_view/template.rb
+++ b/actionpack/lib/action_view/template.rb
@@ -16,23 +16,22 @@ module ActionView
end
extend Template::Handlers
- attr_reader :source, :identifier, :handler, :mime_type, :formats, :details
+
+ attr_reader :source, :identifier, :handler, :virtual_path, :formats
def initialize(source, identifier, handler, details)
@source = source
@identifier = identifier
@handler = handler
- @details = details
+
+ @partial = details[:partial]
+ @virtual_path = details[:virtual_path]
@method_names = {}
- format = details.delete(:format) || begin
- # TODO: Clean this up
- handler.respond_to?(:default_format) ? handler.default_format.to_sym.to_s : "html"
- end
- @mime_type = Mime::Type.lookup_by_extension(format.to_s)
- @formats = [format.to_sym]
- @formats << :html if format == :js
- @details[:formats] = Array.wrap(format.to_sym)
+ format = details[:format]
+ format ||= handler.default_format.to_sym if handler.respond_to?(:default_format)
+ format ||= :html
+ @formats = [format.to_sym]
end
def render(view, locals, &block)
@@ -47,19 +46,20 @@ module ActionView
end
end
- # TODO: Figure out how to abstract this
+ def mime_type
+ @mime_type ||= Mime::Type.lookup_by_extension(@formats.first.to_s) if @formats.first
+ end
+
def variable_name
- @variable_name ||= identifier[%r'_?(\w+)(\.\w+)*$', 1].to_sym
+ @variable_name ||= @virtual_path[%r'_?(\w+)(\.\w+)*$', 1].to_sym
end
- # TODO: Figure out how to abstract this
def counter_name
@counter_name ||= "#{variable_name}_counter".to_sym
end
- # TODO: kill hax
def partial?
- @details[:partial]
+ @partial
end
def inspect
@@ -87,7 +87,7 @@ module ActionView
source = <<-end_src
def #{method_name}(local_assigns)
- _old_virtual_path, @_virtual_path = @_virtual_path, #{@details[:virtual_path].inspect};_old_output_buffer = output_buffer;#{locals_code};#{code}
+ _old_virtual_path, @_virtual_path = @_virtual_path, #{@virtual_path.inspect};_old_output_buffer = output_buffer;#{locals_code};#{code}
ensure
@_virtual_path, self.output_buffer = _old_virtual_path, _old_output_buffer
end
diff --git a/actionpack/lib/action_view/template/resolver.rb b/actionpack/lib/action_view/template/resolver.rb
index 6e6c4c21ee..a43597e728 100644
--- a/actionpack/lib/action_view/template/resolver.rb
+++ b/actionpack/lib/action_view/template/resolver.rb
@@ -21,6 +21,7 @@ module ActionView
# Normalizes the arguments and passes it on to find_template.
def find_all(name, prefix=nil, partial=false, details={}, key=nil)
name, prefix = normalize_name(name, prefix)
+ details = details.merge(:handlers => default_handlers)
cached(key, prefix, name, partial) do
find_templates(name, prefix, partial, details)
@@ -33,6 +34,10 @@ module ActionView
@caching ||= !defined?(Rails.application) || Rails.application.config.cache_classes
end
+ def default_handlers
+ Template::Handlers.extensions + [nil]
+ end
+
# This is what child classes implement. No defaults are needed
# because Resolver guarantees that the arguments are present and
# normalized.
@@ -74,7 +79,7 @@ module ActionView
def find_templates(name, prefix, partial, details)
path = build_path(name, prefix, partial, details)
- query(path, EXTENSION_ORDER.map { |ext| details[ext] })
+ query(partial, path, EXTENSION_ORDER.map { |ext| details[ext] })
end
def build_path(name, prefix, partial, details)
@@ -84,34 +89,27 @@ module ActionView
path
end
- def query(path, exts)
+ def query(partial, path, exts)
query = File.join(@path, path)
+
exts.each do |ext|
query << '{' << ext.map {|e| e && ".#{e}" }.join(',') << '}'
end
Dir[query].reject { |p| File.directory?(p) }.map do |p|
- Template.new(File.read(p), File.expand_path(p), *path_to_details(p))
+ handler, format = extract_handler_and_format(p)
+ Template.new(File.read(p), File.expand_path(p), handler,
+ :partial => partial, :virtual_path => path, :format => format)
end
end
- # # TODO: fix me
- # # :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[3] == '_'
- details = (m[4]||"").split('.').reject { |e| e.empty? }
- handler = Template.handler_class_for_extension(m[5])
+ def extract_handler_and_format(path)
+ pieces = File.basename(path).split(".")
+ pieces.shift
- format = Mime[details.last] && details.pop.to_sym
- locale = details.last && details.pop.to_sym
-
- virtual_path = (m[1].gsub("#{@path}/", "") << details.join("."))
-
- return handler, :format => format, :locale => locale, :partial => partial,
- :virtual_path => virtual_path
- end
+ handler = Template.handler_class_for_extension(pieces.pop)
+ format = pieces.last && Mime[pieces.last] && pieces.pop.to_sym
+ [handler, format]
end
end
diff --git a/actionpack/lib/action_view/template/text.rb b/actionpack/lib/action_view/template/text.rb
index 5978a8a3ac..df394b0fb0 100644
--- a/actionpack/lib/action_view/template/text.rb
+++ b/actionpack/lib/action_view/template/text.rb
@@ -7,10 +7,6 @@ module ActionView #:nodoc:
@content_type ||= Mime::TEXT
end
- def details
- {:formats => [@content_type.to_sym]}
- end
-
def identifier
'text template'
end
@@ -28,7 +24,7 @@ module ActionView #:nodoc:
end
def formats
- [mime_type]
+ [@content_type.to_sym]
end
def partial?
diff --git a/actionpack/test/lib/fixture_template.rb b/actionpack/test/lib/fixture_template.rb
index a7f0490984..d287fae470 100644
--- a/actionpack/test/lib/fixture_template.rb
+++ b/actionpack/test/lib/fixture_template.rb
@@ -7,7 +7,7 @@ module ActionView #:nodoc:
private
- def query(path, exts)
+ def query(partial, path, exts)
query = Regexp.escape(path)
exts.each do |ext|
query << '(?:' << ext.map {|e| e && Regexp.escape(".#{e}") }.join('|') << ')'
@@ -15,9 +15,11 @@ module ActionView #:nodoc:
templates = []
@hash.select { |k,v| k =~ /^#{query}$/ }.each do |path, source|
- templates << Template.new(source, path, *path_to_details(path))
+ handler, format = extract_handler_and_format(path)
+ templates << Template.new(source, path, handler,
+ :partial => partial, :virtual_path => path, :format => format)
end
- templates.sort_by {|t| -t.details.values.compact.size }
+ templates.sort_by {|t| -t.formats.size }
end
end
diff --git a/actionpack/test/template/compiled_templates_test.rb b/actionpack/test/template/compiled_templates_test.rb
index 0a3409064f..2c719757e4 100644
--- a/actionpack/test/template/compiled_templates_test.rb
+++ b/actionpack/test/template/compiled_templates_test.rb
@@ -14,9 +14,6 @@ class CompiledTemplatesTest < Test::Unit::TestCase
assert_equal "two", render(:file => "test/render_file_with_locals_and_default.erb", :locals => { :secret => "two" })
end
- # This is broken in 1.8.6 (not supported in Rails 3.0) because the cache uses a Hash
- # key. Since Ruby 1.8.6 implements Hash#hash using the hash's object_id, it will never
- # successfully get a cache hit here.
def test_template_changes_are_not_reflected_with_cached_templates
assert_equal "Hello world!", render(:file => "test/hello_world.erb")
modify_template "test/hello_world.erb", "Goodbye world!" do
diff --git a/actionpack/test/template/render_test.rb b/actionpack/test/template/render_test.rb
index 37a3975a54..cea8ab1bce 100644
--- a/actionpack/test/template/render_test.rb
+++ b/actionpack/test/template/render_test.rb
@@ -33,17 +33,17 @@ module RenderTestCases
end
def test_render_file_with_localization
- old_locale, I18n.locale = I18n.locale, :da
+ old_locale, @view.locale = @view.locale, :da
assert_equal "Hey verden", @view.render(:file => "test/hello_world")
ensure
- I18n.locale = old_locale
+ @view.locale = old_locale
end
def test_render_file_with_dashed_locale
- old_locale, I18n.locale = I18n.locale, :"pt-BR"
+ old_locale, @view.locale = @view.locale, :"pt-BR"
assert_equal "Ola mundo", @view.render(:file => "test/hello_world")
ensure
- I18n.locale = old_locale
+ @view.locale = old_locale
end
def test_render_file_at_top_level