From b4b0c4cb4154984c89a3bbbcd9970a00d8bd3cb5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Wed, 3 Mar 2010 09:25:41 +0100 Subject: Add missing super call in AC::Metal. [#4085 status:resolved] --- actionpack/lib/action_controller/metal.rb | 1 + 1 file changed, 1 insertion(+) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/metal.rb b/actionpack/lib/action_controller/metal.rb index 4fd37e7f31..5e0ed201cb 100644 --- a/actionpack/lib/action_controller/metal.rb +++ b/actionpack/lib/action_controller/metal.rb @@ -103,6 +103,7 @@ module ActionController def self.inherited(base) self.middleware_stack = base.middleware_stack.dup + super end def self.use(*args) -- cgit v1.2.3 From 9dae645c5f8a2aaa70b19e05daf9a7d270facb72 Mon Sep 17 00:00:00 2001 From: Carl Lerche Date: Wed, 3 Mar 2010 00:42:51 -0800 Subject: Actually move ImplicitRender into it's own file --- actionpack/lib/action_controller.rb | 1 + actionpack/lib/action_controller/base.rb | 23 ---------------------- .../lib/action_controller/metal/implicit_render.rb | 21 ++++++++++++++++++++ 3 files changed, 22 insertions(+), 23 deletions(-) create mode 100644 actionpack/lib/action_controller/metal/implicit_render.rb (limited to 'actionpack') diff --git a/actionpack/lib/action_controller.rb b/actionpack/lib/action_controller.rb index 759e52b135..a449a3364c 100644 --- a/actionpack/lib/action_controller.rb +++ b/actionpack/lib/action_controller.rb @@ -20,6 +20,7 @@ module ActionController autoload :Helpers autoload :HideActions autoload :HttpAuthentication + autoload :ImplicitRender autoload :Instrumentation autoload :MimeResponds autoload :RackDelegation diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb index 13139358c7..aec14165b6 100644 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -36,29 +36,6 @@ module ActionController # Add instrumentations hooks at the bottom, to ensure they instrument # all the methods properly. include ActionController::Instrumentation - - # TODO: Extract into its own module - # This should be moved together with other normalizing behavior - module ImplicitRender - def send_action(*) - ret = super - default_render unless response_body - ret - end - - def default_render - render - end - - def method_for_action(action_name) - super || begin - if view_paths.exists?(action_name.to_s, details_for_render, controller_path) - "default_render" - end - end - end - end - include ImplicitRender include ActionController::Rescue diff --git a/actionpack/lib/action_controller/metal/implicit_render.rb b/actionpack/lib/action_controller/metal/implicit_render.rb new file mode 100644 index 0000000000..ba2d9b686e --- /dev/null +++ b/actionpack/lib/action_controller/metal/implicit_render.rb @@ -0,0 +1,21 @@ +module ActionController + module ImplicitRender + def send_action(*) + ret = super + default_render unless response_body + ret + end + + def default_render + render + end + + def method_for_action(action_name) + super || begin + if view_paths.exists?(action_name.to_s, details_for_render, controller_path) + "default_render" + end + end + end + end +end \ No newline at end of file -- cgit v1.2.3 From 29158d4158e9ae800c5be31a796940888bd03cc5 Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Tue, 2 Mar 2010 15:09:15 -0800 Subject: Remove a failed attempt at refactoring AC configuration --- actionpack/lib/action_controller.rb | 1 - actionpack/lib/action_controller/base.rb | 1 - .../lib/action_controller/metal/configuration.rb | 28 ---------------------- .../action_controller/metal/session_management.rb | 2 -- 4 files changed, 32 deletions(-) delete mode 100644 actionpack/lib/action_controller/metal/configuration.rb (limited to 'actionpack') diff --git a/actionpack/lib/action_controller.rb b/actionpack/lib/action_controller.rb index a449a3364c..3b97f38498 100644 --- a/actionpack/lib/action_controller.rb +++ b/actionpack/lib/action_controller.rb @@ -13,7 +13,6 @@ module ActionController autoload_under "metal" do autoload :Compatibility autoload :ConditionalGet - autoload :Configuration autoload :Cookies autoload :Flash autoload :Head diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb index aec14165b6..ace0276a31 100644 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -15,7 +15,6 @@ module ActionController include ActionController::Renderers::All include ActionController::ConditionalGet include ActionController::RackDelegation - include ActionController::Configuration # Legacy modules include SessionManagement diff --git a/actionpack/lib/action_controller/metal/configuration.rb b/actionpack/lib/action_controller/metal/configuration.rb deleted file mode 100644 index 5c829853b7..0000000000 --- a/actionpack/lib/action_controller/metal/configuration.rb +++ /dev/null @@ -1,28 +0,0 @@ -module ActionController - module Configuration - extend ActiveSupport::Concern - - def config - @config ||= self.class.config - end - - def config=(config) - @config = config - end - - module ClassMethods - def default_config - @default_config ||= {} - end - - def config - self.config ||= default_config - end - - def config=(config) - @config = ActiveSupport::OrderedHash.new - @config.merge!(config) - end - end - end -end \ No newline at end of file diff --git a/actionpack/lib/action_controller/metal/session_management.rb b/actionpack/lib/action_controller/metal/session_management.rb index d70f40ce7a..6997257844 100644 --- a/actionpack/lib/action_controller/metal/session_management.rb +++ b/actionpack/lib/action_controller/metal/session_management.rb @@ -2,8 +2,6 @@ module ActionController #:nodoc: module SessionManagement #:nodoc: extend ActiveSupport::Concern - include ActionController::Configuration - module ClassMethods # Set the session store to be used for keeping the session data between requests. # By default, sessions are stored in browser cookies (:cookie_store), -- cgit v1.2.3 From bf9913f8f43a2436c644ad893d3d7034f7d7e256 Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Tue, 2 Mar 2010 16:22:53 -0800 Subject: Move session_store and session_options to the AC configuration object --- actionpack/lib/action_controller/metal.rb | 17 +++++++++++ .../lib/action_controller/metal/compatibility.rb | 3 -- .../action_controller/metal/http_authentication.rb | 28 ++++++++--------- .../action_controller/metal/session_management.rb | 35 +++++++++++++++------- .../controller/http_digest_authentication_test.rb | 5 ++-- 5 files changed, 57 insertions(+), 31 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/metal.rb b/actionpack/lib/action_controller/metal.rb index 5e0ed201cb..fbc8a9a15e 100644 --- a/actionpack/lib/action_controller/metal.rb +++ b/actionpack/lib/action_controller/metal.rb @@ -1,4 +1,13 @@ require 'active_support/core_ext/class/attribute' +require 'active_support/ordered_options' + +module ActiveSupport + class InheritableOptions < OrderedOptions + def initialize(parent) + super() { |h,k| parent[k] } + end + end +end module ActionController # ActionController::Metal provides a way to get a valid Rack application from a controller. @@ -10,6 +19,14 @@ module ActionController class Metal < AbstractController::Base abstract! + def self.config + @config ||= ActiveSupport::InheritableOptions.new(superclass < Metal ? superclass.config : {}) + end + + def config + self.class.config + end + # :api: public attr_internal :params, :env diff --git a/actionpack/lib/action_controller/metal/compatibility.rb b/actionpack/lib/action_controller/metal/compatibility.rb index 2b1ada1426..d1c86b296d 100644 --- a/actionpack/lib/action_controller/metal/compatibility.rb +++ b/actionpack/lib/action_controller/metal/compatibility.rb @@ -12,9 +12,6 @@ module ActionController ::ActionController::UnknownAction = ::AbstractController::ActionNotFound ::ActionController::DoubleRenderError = ::AbstractController::DoubleRenderError - cattr_accessor :session_options - self.session_options = {} - cattr_accessor :relative_url_root self.relative_url_root = ENV['RAILS_RELATIVE_URL_ROOT'] diff --git a/actionpack/lib/action_controller/metal/http_authentication.rb b/actionpack/lib/action_controller/metal/http_authentication.rb index 0f35a7c040..5c6641c948 100644 --- a/actionpack/lib/action_controller/metal/http_authentication.rb +++ b/actionpack/lib/action_controller/metal/http_authentication.rb @@ -165,7 +165,7 @@ module ActionController # Authenticate with HTTP Digest, returns true or false def authenticate_with_http_digest(realm = "Application", &password_procedure) - HttpAuthentication::Digest.authenticate(request, realm, &password_procedure) + HttpAuthentication::Digest.authenticate(config.session_options[:secret], request, realm, &password_procedure) end # Render output including the HTTP Digest authentication header @@ -175,8 +175,8 @@ module ActionController end # Returns false on a valid response, true otherwise - def authenticate(request, realm, &password_procedure) - authorization(request) && validate_digest_response(request, realm, &password_procedure) + def authenticate(secret_key, request, realm, &password_procedure) + authorization(request) && validate_digest_response(secret_key, request, realm, &password_procedure) end def authorization(request) @@ -189,11 +189,11 @@ module ActionController # Returns false unless the request credentials response value matches the expected value. # First try the password as a ha1 digest password. If this fails, then try it as a plain # text password. - def validate_digest_response(request, realm, &password_procedure) + def validate_digest_response(secret_key, request, realm, &password_procedure) credentials = decode_credentials_header(request) - valid_nonce = validate_nonce(request, credentials[:nonce]) + valid_nonce = validate_nonce(secret_key, request, credentials[:nonce]) - if valid_nonce && realm == credentials[:realm] && opaque == credentials[:opaque] + if valid_nonce && realm == credentials[:realm] && opaque(secret_key) == credentials[:opaque] password = password_procedure.call(credentials[:username]) return false unless password @@ -238,6 +238,9 @@ module ActionController end def authentication_header(controller, realm) + secret_key = controller.config.session_options[:secret] + nonce = self.nonce(secret_key) + opaque = opaque(secret_key) controller.headers["WWW-Authenticate"] = %(Digest realm="#{realm}", qop="auth", algorithm=MD5, nonce="#{nonce}", opaque="#{opaque}") end @@ -280,7 +283,7 @@ module ActionController # The nonce is opaque to the client. Composed of Time, and hash of Time with secret # key from the Rails session secret generated upon creation of project. Ensures # the time cannot be modified by client. - def nonce(time = Time.now) + def nonce(secret_key, time = Time.now) t = time.to_i hashed = [t, secret_key] digest = ::Digest::MD5.hexdigest(hashed.join(":")) @@ -292,21 +295,16 @@ module ActionController # Can be much shorter if the Stale directive is implemented. This would # allow a user to use new nonce without prompting user again for their # username and password. - def validate_nonce(request, value, seconds_to_timeout=5*60) + def validate_nonce(secret_key, request, value, seconds_to_timeout=5*60) t = ActiveSupport::Base64.decode64(value).split(":").first.to_i - nonce(t) == value && (t - Time.now.to_i).abs <= seconds_to_timeout + nonce(secret_key, t) == value && (t - Time.now.to_i).abs <= seconds_to_timeout end # Opaque based on random generation - but changing each request? - def opaque() + def opaque(secret_key) ::Digest::MD5.hexdigest(secret_key) end - # Set in /initializers/session_store.rb, and loaded even if sessions are not in use. - def secret_key - ActionController::Base.session_options[:secret] - end - end end end diff --git a/actionpack/lib/action_controller/metal/session_management.rb b/actionpack/lib/action_controller/metal/session_management.rb index 6997257844..264250db1a 100644 --- a/actionpack/lib/action_controller/metal/session_management.rb +++ b/actionpack/lib/action_controller/metal/session_management.rb @@ -2,27 +2,40 @@ module ActionController #:nodoc: module SessionManagement #:nodoc: extend ActiveSupport::Concern + included do + self.config.session_store ||= :cookie_store + self.config.session_options ||= {} + end + module ClassMethods # Set the session store to be used for keeping the session data between requests. # By default, sessions are stored in browser cookies (:cookie_store), # but you can also specify one of the other included stores (:active_record_store, # :mem_cache_store, or your own custom class. def session_store=(store) - if store == :active_record_store - self.session_store = ActiveRecord::SessionStore - else - @@session_store = store.is_a?(Symbol) ? - ActionDispatch::Session.const_get(store.to_s.camelize) : - store - end + ActiveSupport::Deprecation.warn "Setting session_store directly on ActionController::Base is deprecated. " \ + "Please set it on config.action_controller.session_store" + config.session_store = store + end + + def session_options=(opts) + ActiveSupport::Deprecation.warn "Setting seession_options directly on ActionController::Base is deprecated. " \ + "Please set it on config.action_controller.session_options" + config.session_store = opts + end + + def session_options + config.session_options end - # Returns the session store class currently used. def session_store - if defined? @@session_store - @@session_store + case store = config.session_store + when :active_record_store + ActiveRecord::SessionStore + when Symbol + ActionDispatch::Session.const_get(store.to_s.camelize) else - ActionDispatch::Session::CookieStore + store end end diff --git a/actionpack/test/controller/http_digest_authentication_test.rb b/actionpack/test/controller/http_digest_authentication_test.rb index 7e9a2625f1..22d2e23de1 100644 --- a/actionpack/test/controller/http_digest_authentication_test.rb +++ b/actionpack/test/controller/http_digest_authentication_test.rb @@ -40,7 +40,8 @@ class HttpDigestAuthenticationTest < ActionController::TestCase setup do # Used as secret in generating nonce to prevent tampering of timestamp - @old_secret, ActionController::Base.session_options[:secret] = ActionController::Base.session_options[:secret], "session_options_secret" + @secret = "session_options_secret" + @old_secret, ActionController::Base.session_options[:secret] = ActionController::Base.session_options[:secret], @secret end teardown do @@ -202,7 +203,7 @@ class HttpDigestAuthenticationTest < ActionController::TestCase test "validate_digest_response should fail with nil returning password_procedure" do @request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => nil, :password => nil) - assert !ActionController::HttpAuthentication::Digest.validate_digest_response(@request, "SuperSecret"){nil} + assert !ActionController::HttpAuthentication::Digest.validate_digest_response(@secret, @request, "SuperSecret"){nil} end private -- cgit v1.2.3 From 664090348154ccbf1274a13bbc3d3c37ba35bc7d Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Tue, 2 Mar 2010 17:18:01 -0800 Subject: Move InheritableOptions into ActiveSupport --- actionpack/lib/action_controller/metal.rb | 8 -------- 1 file changed, 8 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/metal.rb b/actionpack/lib/action_controller/metal.rb index fbc8a9a15e..1f6bbeb7c5 100644 --- a/actionpack/lib/action_controller/metal.rb +++ b/actionpack/lib/action_controller/metal.rb @@ -1,14 +1,6 @@ require 'active_support/core_ext/class/attribute' require 'active_support/ordered_options' -module ActiveSupport - class InheritableOptions < OrderedOptions - def initialize(parent) - super() { |h,k| parent[k] } - end - end -end - module ActionController # ActionController::Metal provides a way to get a valid Rack application from a controller. # -- cgit v1.2.3 From bcfb77782b9d7f28f0c19005da909162e5e27690 Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Tue, 2 Mar 2010 17:20:13 -0800 Subject: Work on deprecating ActionController::Base.relative_url_root --- .../lib/action_controller/metal/compatibility.rb | 41 ++++++++++++++++++++-- .../action_controller/metal/session_management.rb | 16 --------- actionpack/lib/action_controller/metal/url_for.rb | 4 +++ actionpack/lib/action_controller/url_rewriter.rb | 4 ++- .../lib/action_view/helpers/asset_tag_helper.rb | 4 +-- actionpack/test/controller/url_for_test.rb | 15 +++----- actionpack/test/dispatch/request_test.rb | 8 ----- actionpack/test/template/asset_tag_helper_test.rb | 38 ++++++++++---------- 8 files changed, 70 insertions(+), 60 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/metal/compatibility.rb b/actionpack/lib/action_controller/metal/compatibility.rb index d1c86b296d..93f7b8ca49 100644 --- a/actionpack/lib/action_controller/metal/compatibility.rb +++ b/actionpack/lib/action_controller/metal/compatibility.rb @@ -7,13 +7,17 @@ module ActionController class ::ActionController::ActionControllerError < StandardError #:nodoc: end + module ClassMethods + end + # Temporary hax included do ::ActionController::UnknownAction = ::AbstractController::ActionNotFound ::ActionController::DoubleRenderError = ::AbstractController::DoubleRenderError - cattr_accessor :relative_url_root - self.relative_url_root = ENV['RAILS_RELATIVE_URL_ROOT'] + # ROUTES TODO: This should be handled by a middleware and route generation + # should be able to handle SCRIPT_NAME + self.config.relative_url_root = ENV['RAILS_RELATIVE_URL_ROOT'] class << self delegate :default_charset=, :to => "ActionDispatch::Response" @@ -47,6 +51,39 @@ module ActionController cattr_accessor :trusted_proxies end + def self.deprecated_config_accessor(option, message = nil) + deprecated_config_reader(option, message) + deprecated_config_writer(option, message) + end + + def self.deprecated_config_reader(option, message = nil) + message ||= "Reading #{option} directly from ActionController::Base is deprecated. " \ + "Please read it from config.#{option}" + + ClassMethods.class_eval <<-RUBY, __FILE__, __LINE__ + 1 + def #{option} + ActiveSupport::Deprecation.warn #{message.inspect} + config.#{option} + end + RUBY + end + + def self.deprecated_config_writer(option, message = nil) + message ||= "Setting #{option} directly on ActionController::Base is deprecated. " \ + "Please set it on config.action_controller.#{option}" + + ClassMethods.class_eval <<-RUBY, __FILE__, __LINE__ + 1 + def #{option}=(val) + ActiveSupport::Deprecation.warn #{message.inspect} + config.#{option} = val + end + RUBY + end + + deprecated_config_writer :session_store + deprecated_config_writer :session_options + deprecated_config_accessor :relative_url_root, "relative_url_root is ineffective. Please stop using it" + # For old tests def initialize_template_class(*) end def assign_shortcuts(*) end diff --git a/actionpack/lib/action_controller/metal/session_management.rb b/actionpack/lib/action_controller/metal/session_management.rb index 264250db1a..09ef9261a4 100644 --- a/actionpack/lib/action_controller/metal/session_management.rb +++ b/actionpack/lib/action_controller/metal/session_management.rb @@ -8,22 +8,6 @@ module ActionController #:nodoc: end module ClassMethods - # Set the session store to be used for keeping the session data between requests. - # By default, sessions are stored in browser cookies (:cookie_store), - # but you can also specify one of the other included stores (:active_record_store, - # :mem_cache_store, or your own custom class. - def session_store=(store) - ActiveSupport::Deprecation.warn "Setting session_store directly on ActionController::Base is deprecated. " \ - "Please set it on config.action_controller.session_store" - config.session_store = store - end - - def session_options=(opts) - ActiveSupport::Deprecation.warn "Setting seession_options directly on ActionController::Base is deprecated. " \ - "Please set it on config.action_controller.session_options" - config.session_store = opts - end - def session_options config.session_options end diff --git a/actionpack/lib/action_controller/metal/url_for.rb b/actionpack/lib/action_controller/metal/url_for.rb index 8a06f34d23..c890dc51d4 100644 --- a/actionpack/lib/action_controller/metal/url_for.rb +++ b/actionpack/lib/action_controller/metal/url_for.rb @@ -9,6 +9,10 @@ module ActionController super.reverse_merge( :host => request.host_with_port, :protocol => request.protocol, + # ROUTES TODO: relative_url_root should be middleware + # and the generator should take SCRIPT_NAME into + # consideration + :relative_url_root => config.relative_url_root, :_path_segments => request.symbolized_path_parameters ) end diff --git a/actionpack/lib/action_controller/url_rewriter.rb b/actionpack/lib/action_controller/url_rewriter.rb index 807b21cd0e..973a6facd7 100644 --- a/actionpack/lib/action_controller/url_rewriter.rb +++ b/actionpack/lib/action_controller/url_rewriter.rb @@ -32,6 +32,7 @@ module ActionController # ROUTES TODO: Fix the tests segments = options.delete(:_path_segments) + relative_url_root = options.delete(:relative_url_root).to_s path_segments = path_segments ? path_segments.merge(segments || {}) : segments unless options[:only_path] @@ -49,7 +50,8 @@ module ActionController path_options = yield(path_options) if block_given? path = router.generate(path_options, path_segments || {}) - rewritten_url << ActionController::Base.relative_url_root.to_s unless options[:skip_relative_url_root] + # ROUTES TODO: This can be called directly, so relative_url_root should probably be set in the router + rewritten_url << relative_url_root rewritten_url << (options[:trailing_slash] ? path.sub(/\?|\z/) { "/" + $& } : path) rewritten_url << "##{Rack::Utils.escape(options[:anchor].to_param.to_s)}" if options[:anchor] diff --git a/actionpack/lib/action_view/helpers/asset_tag_helper.rb b/actionpack/lib/action_view/helpers/asset_tag_helper.rb index 96976ce45f..5f76ff456e 100644 --- a/actionpack/lib/action_view/helpers/asset_tag_helper.rb +++ b/actionpack/lib/action_view/helpers/asset_tag_helper.rb @@ -648,8 +648,8 @@ module ActionView source = rewrite_asset_path(source) if has_request && include_host - unless source =~ %r{^#{ActionController::Base.relative_url_root}/} - source = "#{ActionController::Base.relative_url_root}#{source}" + unless source =~ %r{^#{controller.config.relative_url_root}/} + source = "#{controller.config.relative_url_root}#{source}" end end end diff --git a/actionpack/test/controller/url_for_test.rb b/actionpack/test/controller/url_for_test.rb index a7b77edc6e..07809aa480 100644 --- a/actionpack/test/controller/url_for_test.rb +++ b/actionpack/test/controller/url_for_test.rb @@ -113,15 +113,13 @@ module AbstractController end def test_relative_url_root_is_respected - orig_relative_url_root = ActionController::Base.relative_url_root - ActionController::Base.relative_url_root = '/subdir' + # ROUTES TODO: Tests should not have to pass :relative_url_root directly. This + # should probably come from the router. add_host! assert_equal('https://www.basecamphq.com/subdir/c/a/i', - W.new.url_for(:controller => 'c', :action => 'a', :id => 'i', :protocol => 'https') + W.new.url_for(:controller => 'c', :action => 'a', :id => 'i', :protocol => 'https', :relative_url_root => '/subdir') ) - ensure - ActionController::Base.relative_url_root = orig_relative_url_root end def test_named_routes @@ -146,9 +144,6 @@ module AbstractController end def test_relative_url_root_is_respected_for_named_routes - orig_relative_url_root = ActionController::Base.relative_url_root - ActionController::Base.relative_url_root = '/subdir' - with_routing do |set| set.draw do |map| match '/home/sweet/home/:user', :to => 'home#index', :as => :home @@ -158,10 +153,8 @@ module AbstractController controller = kls.new assert_equal 'http://www.basecamphq.com/subdir/home/sweet/home/again', - controller.send(:home_url, :host => 'www.basecamphq.com', :user => 'again') + controller.send(:home_url, :host => 'www.basecamphq.com', :user => 'again', :relative_url_root => "/subdir") end - ensure - ActionController::Base.relative_url_root = orig_relative_url_root end def test_only_path diff --git a/actionpack/test/dispatch/request_test.rb b/actionpack/test/dispatch/request_test.rb index cc6acead6e..703f03fa96 100644 --- a/actionpack/test/dispatch/request_test.rb +++ b/actionpack/test/dispatch/request_test.rb @@ -1,14 +1,6 @@ require 'abstract_unit' class RequestTest < ActiveSupport::TestCase - def setup - ActionController::Base.relative_url_root = nil - end - - def teardown - ActionController::Base.relative_url_root = nil - end - test "remote ip" do request = stub_request 'REMOTE_ADDR' => '1.2.3.4' assert_equal '1.2.3.4', request.remote_ip diff --git a/actionpack/test/template/asset_tag_helper_test.rb b/actionpack/test/template/asset_tag_helper_test.rb index 586de66714..ccc39e9af6 100644 --- a/actionpack/test/template/asset_tag_helper_test.rb +++ b/actionpack/test/template/asset_tag_helper_test.rb @@ -1,4 +1,13 @@ require 'abstract_unit' +require 'active_support/ordered_options' + +class FakeController + attr_accessor :request + + def config + @config ||= ActiveSupport::InheritableOptions.new(ActionController::Metal.config) + end +end class AssetTagHelperTest < ActionView::TestCase tests ActionView::Helpers::AssetTagHelper @@ -32,8 +41,7 @@ class AssetTagHelperTest < ActionView::TestCase ) end - @controller = Class.new do - attr_accessor :request + @controller = Class.new(FakeController) do def url_for(*args) "http://www.example.com" end end.new @@ -372,11 +380,9 @@ class AssetTagHelperTest < ActionView::TestCase end def test_timebased_asset_id_with_relative_url_root - ActionController::Base.relative_url_root = "/collaboration/hieraki" - expected_time = File.stat(File.expand_path(File.dirname(__FILE__) + "/../fixtures/public/images/rails.png")).mtime.to_i.to_s - assert_equal %(Rails), image_tag("rails.png") - ensure - ActionController::Base.relative_url_root = "" + @controller.config.relative_url_root = "/collaboration/hieraki" + expected_time = File.stat(File.expand_path(File.dirname(__FILE__) + "/../fixtures/public/images/rails.png")).mtime.to_i.to_s + assert_equal %(Rails), image_tag("rails.png") end def test_should_skip_asset_id_on_complete_url @@ -606,7 +612,7 @@ class AssetTagHelperTest < ActionView::TestCase def test_caching_javascript_include_tag_with_relative_url_root ENV["RAILS_ASSET_ID"] = "" - ActionController::Base.relative_url_root = "/collaboration/hieraki" + @controller.config.relative_url_root = "/collaboration/hieraki" ActionController::Base.perform_caching = true assert_dom_equal( @@ -624,7 +630,6 @@ class AssetTagHelperTest < ActionView::TestCase assert File.exist?(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'money.js')) ensure - ActionController::Base.relative_url_root = nil FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'all.js')) FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::JAVASCRIPTS_DIR, 'money.js')) end @@ -821,7 +826,7 @@ class AssetTagHelperTest < ActionView::TestCase def test_caching_stylesheet_link_tag_with_relative_url_root ENV["RAILS_ASSET_ID"] = "" - ActionController::Base.relative_url_root = "/collaboration/hieraki" + @controller.config.relative_url_root = "/collaboration/hieraki" ActionController::Base.perform_caching = true assert_dom_equal( @@ -841,7 +846,6 @@ class AssetTagHelperTest < ActionView::TestCase assert File.exist?(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'money.css')) ensure - ActionController::Base.relative_url_root = nil FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'all.css')) FileUtils.rm_f(File.join(ActionView::Helpers::AssetTagHelper::STYLESHEETS_DIR, 'money.css')) end @@ -884,16 +888,14 @@ class AssetTagHelperNonVhostTest < ActionView::TestCase def setup super - ActionController::Base.relative_url_root = "/collaboration/hieraki" - - @controller = Class.new do - attr_accessor :request - + @controller = Class.new(FakeController) do def url_for(options) "http://www.example.com/collaboration/hieraki" end end.new + @controller.config.relative_url_root = "/collaboration/hieraki" + @request = Class.new do def protocol 'gopher://' @@ -905,10 +907,6 @@ class AssetTagHelperNonVhostTest < ActionView::TestCase ActionView::Helpers::AssetTagHelper::reset_javascript_include_default end - def teardown - ActionController::Base.relative_url_root = nil - end - def test_should_compute_proper_path assert_dom_equal(%(), auto_discovery_link_tag) assert_dom_equal(%(/collaboration/hieraki/javascripts/xmlhr.js), javascript_path("xmlhr")) -- cgit v1.2.3 From 2a60cc682224f8a0923de1e0bf769d5333084480 Mon Sep 17 00:00:00 2001 From: Yehuda Katz Date: Wed, 3 Mar 2010 16:06:15 -0800 Subject: don't depend on the order of cookies (Hash ordering bug) --- actionpack/test/controller/cookie_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/test/controller/cookie_test.rb b/actionpack/test/controller/cookie_test.rb index f5ccef8aaf..908967a110 100644 --- a/actionpack/test/controller/cookie_test.rb +++ b/actionpack/test/controller/cookie_test.rb @@ -157,7 +157,7 @@ class CookieTest < ActionController::TestCase def assert_cookie_header(expected) header = @response.headers["Set-Cookie"] if header.respond_to?(:to_str) - assert_equal expected, header + assert_equal expected.split("\n").sort, header.split("\n").sort else assert_equal expected.split("\n"), header end -- cgit v1.2.3 From 5e0a05b8cb236d285ebb45de006dd3600c69357d Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Tue, 2 Mar 2010 18:57:02 -0800 Subject: Tweak the semantic of various URL related methods of ActionDispatch::Request --- actionpack/lib/action_controller/test_case.rb | 22 ++++-- actionpack/lib/action_dispatch/http/url.rb | 31 ++------ actionpack/lib/action_view/helpers/url_helper.rb | 5 +- actionpack/lib/action_view/test_case.rb | 2 + .../controller/http_digest_authentication_test.rb | 10 ++- actionpack/test/controller/integration_test.rb | 4 +- actionpack/test/dispatch/request_test.rb | 86 ++-------------------- actionpack/test/template/url_helper_test.rb | 3 - 8 files changed, 41 insertions(+), 122 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb index 64d9bdab2a..7e0a833dfa 100644 --- a/actionpack/lib/action_controller/test_case.rb +++ b/actionpack/lib/action_controller/test_case.rb @@ -322,6 +322,8 @@ module ActionController @controller ||= klass.new rescue nil end + @request.env.delete('PATH_INFO') + if @controller @controller.request = @request @controller.params = {} @@ -333,15 +335,19 @@ module ActionController @request.remote_addr = '208.77.188.166' # example.com end - private - def build_request_uri(action, parameters) - unless @request.env['REQUEST_URI'] - options = @controller.__send__(:url_options).merge(parameters) - options.update(:only_path => true, :action => action) + private + def build_request_uri(action, parameters) + unless @request.env["PATH_INFO"] + options = @controller.__send__(:url_options).merge(parameters) + options.update(:only_path => true, :action => action, :relative_url_root => nil) + rewriter = ActionController::UrlRewriter.new(@request, parameters) - url = ActionController::UrlRewriter.new(@request, parameters) - @request.request_uri = url.rewrite(@router, options) - end + url, query_string = rewriter.rewrite(@router, options).split("?", 2) + + @request.env["SCRIPT_NAME"] = @controller.config.relative_url_root + @request.env["PATH_INFO"] = url + @request.env["QUERY_STRING"] = query_string || "" end + end end end diff --git a/actionpack/lib/action_dispatch/http/url.rb b/actionpack/lib/action_dispatch/http/url.rb index 42ad19044d..e67d970a23 100644 --- a/actionpack/lib/action_dispatch/http/url.rb +++ b/actionpack/lib/action_dispatch/http/url.rb @@ -85,42 +85,23 @@ module ActionDispatch subdomains(tld_length).join('.') end - # Returns the query string, accounting for server idiosyncrasies. + # The query string must always be present def query_string - @env['QUERY_STRING'].present? ? @env['QUERY_STRING'] : (@env['REQUEST_URI'].to_s.split('?', 2)[1] || '') + @env['QUERY_STRING'] end # Returns the request URI, accounting for server idiosyncrasies. # WEBrick includes the full URL. IIS leaves REQUEST_URI blank. def request_uri - if uri = @env['REQUEST_URI'] - # Remove domain, which webrick puts into the request_uri. - (%r{^\w+\://[^/]+(/.*|$)$} =~ uri) ? $1 : uri - else - # Construct IIS missing REQUEST_URI from SCRIPT_NAME and PATH_INFO. - uri = @env['PATH_INFO'].to_s - - if script_filename = @env['SCRIPT_NAME'].to_s.match(%r{[^/]+$}) - uri = uri.sub(/#{script_filename}\//, '') - end - - env_qs = @env['QUERY_STRING'].to_s - uri += "?#{env_qs}" unless env_qs.empty? - - if uri.blank? - @env.delete('REQUEST_URI') - else - @env['REQUEST_URI'] = uri - end - end + uri = "#{@env["SCRIPT_NAME"]}#{@env["PATH_INFO"]}" + uri << "?#{@env["QUERY_STRING"]}" if @env["QUERY_STRING"].present? + uri end # Returns the interpreted \path to requested resource after all the installation # directory of this application was taken into account. def path - path = request_uri.to_s[/\A[^\?]*/] - path.sub!(/\A#{ActionController::Base.relative_url_root}/, '') - path + @env['PATH_INFO'] end private diff --git a/actionpack/lib/action_view/helpers/url_helper.rb b/actionpack/lib/action_view/helpers/url_helper.rb index d9607c0095..148f2868e9 100644 --- a/actionpack/lib/action_view/helpers/url_helper.rb +++ b/actionpack/lib/action_view/helpers/url_helper.rb @@ -544,10 +544,11 @@ module ActionView # submitted url doesn't have any either. This lets the function # work with things like ?order=asc if url_string.index("?") - request_uri = request.request_uri + request_uri = request.fullpath else - request_uri = request.request_uri.split('?').first + request_uri = request.path end + if url_string =~ /^\w+:\/\// url_string == "#{request.protocol}#{request.host_with_port}#{request_uri}" else diff --git a/actionpack/lib/action_view/test_case.rb b/actionpack/lib/action_view/test_case.rb index f639700eaf..12142a3728 100644 --- a/actionpack/lib/action_view/test_case.rb +++ b/actionpack/lib/action_view/test_case.rb @@ -34,6 +34,8 @@ module ActionView @request = ActionController::TestRequest.new @response = ActionController::TestResponse.new + @request.env.delete('PATH_INFO') + @params = {} end end diff --git a/actionpack/test/controller/http_digest_authentication_test.rb b/actionpack/test/controller/http_digest_authentication_test.rb index 22d2e23de1..6f167fe627 100644 --- a/actionpack/test/controller/http_digest_authentication_test.rb +++ b/actionpack/test/controller/http_digest_authentication_test.rb @@ -139,7 +139,7 @@ class HttpDigestAuthenticationTest < ActionController::TestCase test "authentication request with request-uri that doesn't match credentials digest-uri" do @request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => 'pretty', :password => 'please') - @request.env['REQUEST_URI'] = "/http_digest_authentication_test/dummy_digest/altered/uri" + @request.env['PATH_INFO'] = "/http_digest_authentication_test/dummy_digest/altered/uri" get :display assert_response :unauthorized @@ -148,7 +148,8 @@ class HttpDigestAuthenticationTest < ActionController::TestCase test "authentication request with absolute request uri (as in webrick)" do @request.env['HTTP_AUTHORIZATION'] = encode_credentials(:username => 'pretty', :password => 'please') - @request.env['REQUEST_URI'] = "http://test.host/http_digest_authentication_test/dummy_digest" + @request.env["SERVER_NAME"] = "test.host" + @request.env['PATH_INFO'] = "/http_digest_authentication_test/dummy_digest" get :display @@ -171,7 +172,8 @@ class HttpDigestAuthenticationTest < ActionController::TestCase test "authentication request with absolute uri in both request and credentials (as in Webrick with IE)" do @request.env['HTTP_AUTHORIZATION'] = encode_credentials(:url => "http://test.host/http_digest_authentication_test/dummy_digest", :username => 'pretty', :password => 'please') - @request.env['REQUEST_URI'] = "http://test.host/http_digest_authentication_test/dummy_digest" + @request.env['SERVER_NAME'] = "test.host" + @request.env['PATH_INFO'] = "/http_digest_authentication_test/dummy_digest" get :display @@ -226,7 +228,7 @@ class HttpDigestAuthenticationTest < ActionController::TestCase credentials = decode_credentials(@response.headers['WWW-Authenticate']) credentials.merge!(options) - credentials.merge!(:uri => @request.env['REQUEST_URI'].to_s) + credentials.merge!(:uri => @request.env['PATH_INFO'].to_s) ActionController::HttpAuthentication::Digest.encode_credentials(method, credentials, password, options[:password_is_ha1]) end diff --git a/actionpack/test/controller/integration_test.rb b/actionpack/test/controller/integration_test.rb index c38348fa68..814699978d 100644 --- a/actionpack/test/controller/integration_test.rb +++ b/actionpack/test/controller/integration_test.rb @@ -346,8 +346,8 @@ class IntegrationProcessTest < ActionController::IntegrationTest def test_get_with_parameters with_test_route_set do get '/get_with_params', :foo => "bar" - assert_equal '/get_with_params', request.env["REQUEST_URI"] - assert_equal '/get_with_params', request.request_uri + assert_equal '/get_with_params', request.env["PATH_INFO"] + assert_equal '/get_with_params', request.path_info assert_equal 'foo=bar', request.env["QUERY_STRING"] assert_equal 'foo=bar', request.query_string assert_equal 'bar', request.parameters['foo'] diff --git a/actionpack/test/dispatch/request_test.rb b/actionpack/test/dispatch/request_test.rb index 703f03fa96..1dfcdaebfd 100644 --- a/actionpack/test/dispatch/request_test.rb +++ b/actionpack/test/dispatch/request_test.rb @@ -144,103 +144,33 @@ class RequestTest < ActiveSupport::TestCase end test "request uri" do - request = stub_request 'REQUEST_URI' => "http://www.rubyonrails.org/path/of/some/uri?mapped=1" + request = stub_request 'SCRIPT_NAME' => '', 'PATH_INFO' => '/path/of/some/uri', 'QUERY_STRING' => 'mapped=1' assert_equal "/path/of/some/uri?mapped=1", request.request_uri assert_equal "/path/of/some/uri", request.path - request = stub_request 'REQUEST_URI' => "http://www.rubyonrails.org/path/of/some/uri" + request = stub_request 'SCRIPT_NAME' => '', 'PATH_INFO' => '/path/of/some/uri' assert_equal "/path/of/some/uri", request.request_uri assert_equal "/path/of/some/uri", request.path - request = stub_request 'REQUEST_URI' => "/path/of/some/uri" - assert_equal "/path/of/some/uri", request.request_uri - assert_equal "/path/of/some/uri", request.path - - request = stub_request 'REQUEST_URI' => "/" + request = stub_request 'SCRIPT_NAME' => '', 'PATH_INFO' => '/' assert_equal "/", request.request_uri assert_equal "/", request.path - request = stub_request 'REQUEST_URI' => "/?m=b" + request = stub_request 'SCRIPT_NAME' => '', 'PATH_INFO' => '/', 'QUERY_STRING' => 'm=b' assert_equal "/?m=b", request.request_uri assert_equal "/", request.path - request = stub_request 'REQUEST_URI' => "/", 'SCRIPT_NAME' => '/dispatch.cgi' - assert_equal "/", request.request_uri - assert_equal "/", request.path - - ActionController::Base.relative_url_root = "/hieraki" - request = stub_request 'REQUEST_URI' => "/hieraki/", 'SCRIPT_NAME' => "/hieraki/dispatch.cgi" + request = stub_request 'SCRIPT_NAME' => '/hieraki', 'PATH_INFO' => '/' assert_equal "/hieraki/", request.request_uri assert_equal "/", request.path - ActionController::Base.relative_url_root = nil - ActionController::Base.relative_url_root = "/collaboration/hieraki" - request = stub_request 'REQUEST_URI' => "/collaboration/hieraki/books/edit/2", - 'SCRIPT_NAME' => "/collaboration/hieraki/dispatch.cgi" + request = stub_request 'SCRIPT_NAME' => '/collaboration/hieraki', 'PATH_INFO' => '/books/edit/2' assert_equal "/collaboration/hieraki/books/edit/2", request.request_uri assert_equal "/books/edit/2", request.path - ActionController::Base.relative_url_root = nil - - # The following tests are for when REQUEST_URI is not supplied (as in IIS) - request = stub_request 'PATH_INFO' => "/path/of/some/uri?mapped=1", - 'SCRIPT_NAME' => nil, - 'REQUEST_URI' => nil - assert_equal "/path/of/some/uri?mapped=1", request.request_uri - assert_equal "/path/of/some/uri", request.path - ActionController::Base.relative_url_root = '/path' - request = stub_request 'PATH_INFO' => "/path/of/some/uri?mapped=1", - 'SCRIPT_NAME' => "/path/dispatch.rb", - 'REQUEST_URI' => nil + request = stub_request 'SCRIPT_NAME' => '/path', 'PATH_INFO' => '/of/some/uri', 'QUERY_STRING' => 'mapped=1' assert_equal "/path/of/some/uri?mapped=1", request.request_uri assert_equal "/of/some/uri", request.path - ActionController::Base.relative_url_root = nil - - request = stub_request 'PATH_INFO' => "/path/of/some/uri", - 'SCRIPT_NAME' => nil, - 'REQUEST_URI' => nil - assert_equal "/path/of/some/uri", request.request_uri - assert_equal "/path/of/some/uri", request.path - - request = stub_request 'PATH_INFO' => '/', 'REQUEST_URI' => nil - assert_equal "/", request.request_uri - assert_equal "/", request.path - - request = stub_request 'PATH_INFO' => '/?m=b', 'REQUEST_URI' => nil - assert_equal "/?m=b", request.request_uri - assert_equal "/", request.path - - request = stub_request 'PATH_INFO' => "/", - 'SCRIPT_NAME' => "/dispatch.cgi", - 'REQUEST_URI' => nil - assert_equal "/", request.request_uri - assert_equal "/", request.path - - ActionController::Base.relative_url_root = '/hieraki' - request = stub_request 'PATH_INFO' => "/hieraki/", - 'SCRIPT_NAME' => "/hieraki/dispatch.cgi", - 'REQUEST_URI' => nil - assert_equal "/hieraki/", request.request_uri - assert_equal "/", request.path - ActionController::Base.relative_url_root = nil - - request = stub_request 'REQUEST_URI' => '/hieraki/dispatch.cgi' - ActionController::Base.relative_url_root = '/hieraki' - assert_equal "/dispatch.cgi", request.path - ActionController::Base.relative_url_root = nil - - request = stub_request 'REQUEST_URI' => '/hieraki/dispatch.cgi' - ActionController::Base.relative_url_root = '/foo' - assert_equal "/hieraki/dispatch.cgi", request.path - ActionController::Base.relative_url_root = nil - - # This test ensures that Rails uses REQUEST_URI over PATH_INFO - ActionController::Base.relative_url_root = nil - request = stub_request 'REQUEST_URI' => "/some/path", - 'PATH_INFO' => "/another/path", - 'SCRIPT_NAME' => "/dispatch.cgi" - assert_equal "/some/path", request.request_uri - assert_equal "/some/path", request.path end @@ -498,7 +428,7 @@ class RequestTest < ActiveSupport::TestCase protected - def stub_request(env={}) + def stub_request(env = {}) ActionDispatch::Request.new(env) end diff --git a/actionpack/test/template/url_helper_test.rb b/actionpack/test/template/url_helper_test.rb index b047466aaf..afec78ddce 100644 --- a/actionpack/test/template/url_helper_test.rb +++ b/actionpack/test/template/url_helper_test.rb @@ -464,8 +464,6 @@ end class LinkToUnlessCurrentWithControllerTest < ActionController::TestCase def setup super - @request = ActionController::TestRequest.new - @response = ActionController::TestResponse.new @controller = TasksController.new end @@ -565,7 +563,6 @@ end class PolymorphicControllerTest < ActionController::TestCase def setup super - @request = ActionController::TestRequest.new @response = ActionController::TestResponse.new end -- cgit v1.2.3 From c92d598abff54270337ad1eddf7bc41a71c4cbda Mon Sep 17 00:00:00 2001 From: Carl Lerche Date: Wed, 3 Mar 2010 00:03:29 -0800 Subject: Rack::Request actually defines #query_string --- actionpack/lib/action_dispatch/http/url.rb | 5 ----- 1 file changed, 5 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/http/url.rb b/actionpack/lib/action_dispatch/http/url.rb index e67d970a23..049e1758fe 100644 --- a/actionpack/lib/action_dispatch/http/url.rb +++ b/actionpack/lib/action_dispatch/http/url.rb @@ -85,11 +85,6 @@ module ActionDispatch subdomains(tld_length).join('.') end - # The query string must always be present - def query_string - @env['QUERY_STRING'] - end - # Returns the request URI, accounting for server idiosyncrasies. # WEBrick includes the full URL. IIS leaves REQUEST_URI blank. def request_uri -- cgit v1.2.3 From eb49bd694997954783632eada901553f041c9507 Mon Sep 17 00:00:00 2001 From: Carl Lerche Date: Wed, 3 Mar 2010 00:03:56 -0800 Subject: Fix tests for the request refactor --- actionpack/test/controller/caching_test.rb | 3 +- actionpack/test/controller/test_test.rb | 6 ++-- actionpack/test/template/url_helper_test.rb | 52 +++++++++++++++++++---------- 3 files changed, 40 insertions(+), 21 deletions(-) (limited to 'actionpack') diff --git a/actionpack/test/controller/caching_test.rb b/actionpack/test/controller/caching_test.rb index 80c968cc04..37f7483427 100644 --- a/actionpack/test/controller/caching_test.rb +++ b/actionpack/test/controller/caching_test.rb @@ -51,6 +51,7 @@ class PageCachingTest < ActionController::TestCase @request = ActionController::TestRequest.new @request.host = 'hostname.com' + @request.env.delete('PATH_INFO') @response = ActionController::TestResponse.new @controller = PageCachingTestController.new @@ -110,7 +111,7 @@ class PageCachingTest < ActionController::TestCase end def test_should_cache_ok_at_custom_path - @request.request_uri = "/index.html" + @request.env['PATH_INFO'] = '/index.html' get :ok assert_response :ok assert File.exist?("#{FILE_STORE_PATH}/index.html") diff --git a/actionpack/test/controller/test_test.rb b/actionpack/test/controller/test_test.rb index d716dc2661..7312c5dfcc 100644 --- a/actionpack/test/controller/test_test.rb +++ b/actionpack/test/controller/test_test.rb @@ -128,6 +128,7 @@ XML @controller = TestController.new @request = ActionController::TestRequest.new @response = ActionController::TestResponse.new + @request.env['PATH_INFO'] = nil end def test_raw_post_handling @@ -199,7 +200,7 @@ XML end def test_process_with_request_uri_with_params_with_explicit_uri - @request.request_uri = "/explicit/uri" + @request.env['PATH_INFO'] = "/explicit/uri" process :test_uri, :id => 7 assert_equal "/explicit/uri", @response.body end @@ -210,7 +211,8 @@ XML end def test_process_with_query_string_with_explicit_uri - @request.request_uri = "/explicit/uri?q=test?extra=question" + @request.env['PATH_INFO'] = '/explicit/uri' + @request.env['QUERY_STRING'] = 'q=test?extra=question' process :test_query_string assert_equal "q=test?extra=question", @response.body end diff --git a/actionpack/test/template/url_helper_test.rb b/actionpack/test/template/url_helper_test.rb index afec78ddce..d8ccb380a6 100644 --- a/actionpack/test/template/url_helper_test.rb +++ b/actionpack/test/template/url_helper_test.rb @@ -1,9 +1,8 @@ # encoding: utf-8 require 'abstract_unit' +require 'active_support/ordered_options' require 'controller/fake_controllers' -RequestMock = Struct.new("Request", :request_uri, :protocol, :host_with_port, :env) - class UrlHelperTest < ActionView::TestCase include ActiveSupport::Configurable DEFAULT_CONFIG = ActionView::DEFAULT_CONFIG @@ -15,8 +14,13 @@ class UrlHelperTest < ActionView::TestCase def url_for(options) url end + def config + ActiveSupport::InheritableOptions.new({}) + end end + @controller = @controller.new + @request = @controller.request = ActionDispatch::TestRequest.new @controller.url = "http://www.example.com" end @@ -38,12 +42,13 @@ class UrlHelperTest < ActionView::TestCase end def test_url_for_with_back - @controller.request = RequestMock.new("http://www.example.com/weblog/show", nil, nil, {'HTTP_REFERER' => 'http://www.example.com/referer'}) + @request.env['HTTP_REFERER'] = 'http://www.example.com/referer' assert_equal 'http://www.example.com/referer', url_for(:back) end def test_url_for_with_back_and_no_referer - @controller.request = RequestMock.new("http://www.example.com/weblog/show", nil, nil, {}) + @request.env['HOST_NAME'] = 'www.example.com' + @request.env['PATH_INFO'] = '/weblog/show' assert_equal 'javascript:history.back()', url_for(:back) end @@ -144,22 +149,28 @@ class UrlHelperTest < ActionView::TestCase end def test_link_tag_with_back - @controller.request = RequestMock.new("http://www.example.com/weblog/show", nil, nil, {'HTTP_REFERER' => 'http://www.example.com/referer'}) + @request.env['HOST_NAME'] = 'www.example.com' + @request.env['PATH_INFO'] = '/weblog/show' + @request.env['HTTP_REFERER'] = 'http://www.example.com/referer' assert_dom_equal "go back", link_to('go back', :back) end def test_link_tag_with_back_and_no_referer - @controller.request = RequestMock.new("http://www.example.com/weblog/show", nil, nil, {}) + @request.env['HOST_NAME'] = 'www.example.com' + @request.env['PATH_INFO'] = '/weblog/show' assert_dom_equal "go back", link_to('go back', :back) end def test_link_tag_with_back - @controller.request = RequestMock.new("http://www.example.com/weblog/show", nil, nil, {'HTTP_REFERER' => 'http://www.example.com/referer'}) + @request.env['HOST_NAME'] = 'www.example.com' + @request.env['PATH_INFO'] = '/weblog/show' + @request.env['HTTP_REFERER'] = 'http://www.example.com/referer' assert_dom_equal "go back", link_to('go back', :back) end def test_link_tag_with_back_and_no_referer - @controller.request = RequestMock.new("http://www.example.com/weblog/show", nil, nil, {}) + @request.env['HOST_NAME'] = 'www.example.com' + @request.env['PATH_INFO'] = '/weblog/show' assert_dom_equal "go back", link_to('go back', :back) end @@ -263,55 +274,60 @@ class UrlHelperTest < ActionView::TestCase end def test_current_page_with_simple_url - @controller.request = RequestMock.new("http://www.example.com/weblog/show") + @request.env['HTTP_HOST'] = 'www.example.com' + @request.env['PATH_INFO'] = '/weblog/show' @controller.url = "http://www.example.com/weblog/show" assert current_page?({ :action => "show", :controller => "weblog" }) assert current_page?("http://www.example.com/weblog/show") end def test_current_page_ignoring_params - @controller.request = RequestMock.new("http://www.example.com/weblog/show?order=desc&page=1") + @request.env['HTTP_HOST'] = 'www.example.com' + @request.env['PATH_INFO'] = '/weblog/show' + @request.env['QUERY_STRING'] = 'order=desc&page=1' @controller.url = "http://www.example.com/weblog/show?order=desc&page=1" assert current_page?({ :action => "show", :controller => "weblog" }) assert current_page?("http://www.example.com/weblog/show") end def test_current_page_with_params_that_match - @controller.request = RequestMock.new("http://www.example.com/weblog/show?order=desc&page=1") + @request.env['HTTP_HOST'] = 'www.example.com' + @request.env['PATH_INFO'] = '/weblog/show' + @request.env['QUERY_STRING'] = 'order=desc&page=1' @controller.url = "http://www.example.com/weblog/show?order=desc&page=1" assert current_page?({ :action => "show", :controller => "weblog", :order => "desc", :page => "1" }) assert current_page?("http://www.example.com/weblog/show?order=desc&page=1") end def test_link_unless_current - @controller.request = RequestMock.new("http://www.example.com/weblog/show") + @request.env['HTTP_HOST'] = 'www.example.com' + @request.env['PATH_INFO'] = '/weblog/show' @controller.url = "http://www.example.com/weblog/show" assert_equal "Showing", link_to_unless_current("Showing", { :action => "show", :controller => "weblog" }) assert_equal "Showing", link_to_unless_current("Showing", "http://www.example.com/weblog/show") - @controller.request = RequestMock.new("http://www.example.com/weblog/show?order=desc") + @request.env['QUERY_STRING'] = 'order=desc' @controller.url = "http://www.example.com/weblog/show" assert_equal "Showing", link_to_unless_current("Showing", { :action => "show", :controller => "weblog" }) assert_equal "Showing", link_to_unless_current("Showing", "http://www.example.com/weblog/show") - @controller.request = RequestMock.new("http://www.example.com/weblog/show?order=desc&page=1") + @request.env['QUERY_STRING'] = 'order=desc&page=1' @controller.url = "http://www.example.com/weblog/show?order=desc&page=1" assert_equal "Showing", link_to_unless_current("Showing", { :action => "show", :controller => "weblog", :order=>'desc', :page=>'1' }) assert_equal "Showing", link_to_unless_current("Showing", "http://www.example.com/weblog/show?order=desc&page=1") assert_equal "Showing", link_to_unless_current("Showing", "http://www.example.com/weblog/show?order=desc&page=1") - @controller.request = RequestMock.new("http://www.example.com/weblog/show?order=desc") + @request.env['QUERY_STRING'] = 'order=desc' @controller.url = "http://www.example.com/weblog/show?order=asc" assert_equal "Showing", link_to_unless_current("Showing", { :action => "show", :controller => "weblog" }) assert_equal "Showing", link_to_unless_current("Showing", "http://www.example.com/weblog/show?order=asc") - @controller.request = RequestMock.new("http://www.example.com/weblog/show?order=desc&page=1") + @request.env['QUERY_STRING'] = 'order=desc&page=1' @controller.url = "http://www.example.com/weblog/show?order=desc&page=2" assert_equal "Showing", link_to_unless_current("Showing", { :action => "show", :controller => "weblog" }) assert_equal "Showing", link_to_unless_current("Showing", "http://www.example.com/weblog/show?order=desc&page=2") - - @controller.request = RequestMock.new("http://www.example.com/weblog/show") + @request.env['QUERY_STRING'] = '' @controller.url = "http://www.example.com/weblog/list" assert_equal "Listing", link_to_unless_current("Listing", :action => "list", :controller => "weblog") -- cgit v1.2.3 From fb14b8c6fddae818b2688ac1e584534390c37f72 Mon Sep 17 00:00:00 2001 From: Carl Lerche Date: Wed, 3 Mar 2010 00:31:55 -0800 Subject: ActionDispatch::Request deprecates #request_uri * Refactored ActionPatch to use fullpath instead --- .../action_controller/metal/http_authentication.rb | 2 +- .../lib/action_controller/metal/instrumentation.rb | 2 +- actionpack/lib/action_dispatch/http/url.rb | 13 +++------- .../lib/action_view/helpers/atom_feed_helper.rb | 2 +- actionpack/test/controller/integration_test.rb | 2 +- actionpack/test/controller/test_test.rb | 2 +- actionpack/test/dispatch/request_test.rb | 30 +++++++++++----------- 7 files changed, 23 insertions(+), 30 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/metal/http_authentication.rb b/actionpack/lib/action_controller/metal/http_authentication.rb index 5c6641c948..afa7674e40 100644 --- a/actionpack/lib/action_controller/metal/http_authentication.rb +++ b/actionpack/lib/action_controller/metal/http_authentication.rb @@ -198,7 +198,7 @@ module ActionController return false unless password method = request.env['rack.methodoverride.original_method'] || request.env['REQUEST_METHOD'] - uri = credentials[:uri][0,1] == '/' ? request.request_uri : request.url + uri = credentials[:uri][0,1] == '/' ? request.fullpath : request.url [true, false].any? do |password_is_ha1| expected = expected_response(method, uri, credentials, password, password_is_ha1) diff --git a/actionpack/lib/action_controller/metal/instrumentation.rb b/actionpack/lib/action_controller/metal/instrumentation.rb index 85035dc09c..d69de65f28 100644 --- a/actionpack/lib/action_controller/metal/instrumentation.rb +++ b/actionpack/lib/action_controller/metal/instrumentation.rb @@ -20,7 +20,7 @@ module ActionController :params => request.filtered_parameters, :formats => request.formats.map(&:to_sym), :method => request.method, - :path => (request.request_uri rescue "unknown") + :path => (request.fullpath rescue "unknown") } ActiveSupport::Notifications.instrument("action_controller.start_processing", raw_payload.dup) diff --git a/actionpack/lib/action_dispatch/http/url.rb b/actionpack/lib/action_dispatch/http/url.rb index 049e1758fe..f7afbe7fed 100644 --- a/actionpack/lib/action_dispatch/http/url.rb +++ b/actionpack/lib/action_dispatch/http/url.rb @@ -3,7 +3,7 @@ module ActionDispatch module URL # Returns the complete URL used for this request. def url - protocol + host_with_port + request_uri + protocol + host_with_port + fullpath end # Returns 'https://' if this is an SSL request and 'http://' otherwise. @@ -88,15 +88,8 @@ module ActionDispatch # Returns the request URI, accounting for server idiosyncrasies. # WEBrick includes the full URL. IIS leaves REQUEST_URI blank. def request_uri - uri = "#{@env["SCRIPT_NAME"]}#{@env["PATH_INFO"]}" - uri << "?#{@env["QUERY_STRING"]}" if @env["QUERY_STRING"].present? - uri - end - - # Returns the interpreted \path to requested resource after all the installation - # directory of this application was taken into account. - def path - @env['PATH_INFO'] + ActiveSupport::Deprecation.warn "Using #request_uri is deprecated. Use fullpath instead." + fullpath end private diff --git a/actionpack/lib/action_view/helpers/atom_feed_helper.rb b/actionpack/lib/action_view/helpers/atom_feed_helper.rb index a26a8c9b4b..58c3a8752e 100644 --- a/actionpack/lib/action_view/helpers/atom_feed_helper.rb +++ b/actionpack/lib/action_view/helpers/atom_feed_helper.rb @@ -114,7 +114,7 @@ module ActionView feed_opts.merge!(options).reject!{|k,v| !k.to_s.match(/^xml/)} xml.feed(feed_opts) do - xml.id(options[:id] || "tag:#{request.host},#{options[:schema_date]}:#{request.request_uri.split(".")[0]}") + xml.id(options[:id] || "tag:#{request.host},#{options[:schema_date]}:#{request.fullpath.split(".")[0]}") xml.link(:rel => 'alternate', :type => 'text/html', :href => options[:root_url] || (request.protocol + request.host_with_port)) xml.link(:rel => 'self', :type => 'application/atom+xml', :href => options[:url] || request.url) diff --git a/actionpack/test/controller/integration_test.rb b/actionpack/test/controller/integration_test.rb index 814699978d..5cb6aa6997 100644 --- a/actionpack/test/controller/integration_test.rb +++ b/actionpack/test/controller/integration_test.rb @@ -333,7 +333,7 @@ class IntegrationProcessTest < ActionController::IntegrationTest with_test_route_set do get '/get_with_params?foo=bar' assert_equal '/get_with_params?foo=bar', request.env["REQUEST_URI"] - assert_equal '/get_with_params?foo=bar', request.request_uri + assert_equal '/get_with_params?foo=bar', request.fullpath assert_equal "foo=bar", request.env["QUERY_STRING"] assert_equal 'foo=bar', request.query_string assert_equal 'bar', request.parameters['foo'] diff --git a/actionpack/test/controller/test_test.rb b/actionpack/test/controller/test_test.rb index 7312c5dfcc..f6ba275849 100644 --- a/actionpack/test/controller/test_test.rb +++ b/actionpack/test/controller/test_test.rb @@ -42,7 +42,7 @@ class TestTest < ActionController::TestCase end def test_uri - render :text => request.request_uri + render :text => request.fullpath end def test_query_string diff --git a/actionpack/test/dispatch/request_test.rb b/actionpack/test/dispatch/request_test.rb index 1dfcdaebfd..84c06ca113 100644 --- a/actionpack/test/dispatch/request_test.rb +++ b/actionpack/test/dispatch/request_test.rb @@ -143,34 +143,34 @@ class RequestTest < ActiveSupport::TestCase assert_equal ":8080", request.port_string end - test "request uri" do + test "full path" do request = stub_request 'SCRIPT_NAME' => '', 'PATH_INFO' => '/path/of/some/uri', 'QUERY_STRING' => 'mapped=1' - assert_equal "/path/of/some/uri?mapped=1", request.request_uri - assert_equal "/path/of/some/uri", request.path + assert_equal "/path/of/some/uri?mapped=1", request.fullpath + assert_equal "/path/of/some/uri", request.path_info request = stub_request 'SCRIPT_NAME' => '', 'PATH_INFO' => '/path/of/some/uri' - assert_equal "/path/of/some/uri", request.request_uri - assert_equal "/path/of/some/uri", request.path + assert_equal "/path/of/some/uri", request.fullpath + assert_equal "/path/of/some/uri", request.path_info request = stub_request 'SCRIPT_NAME' => '', 'PATH_INFO' => '/' - assert_equal "/", request.request_uri - assert_equal "/", request.path + assert_equal "/", request.fullpath + assert_equal "/", request.path_info request = stub_request 'SCRIPT_NAME' => '', 'PATH_INFO' => '/', 'QUERY_STRING' => 'm=b' - assert_equal "/?m=b", request.request_uri - assert_equal "/", request.path + assert_equal "/?m=b", request.fullpath + assert_equal "/", request.path_info request = stub_request 'SCRIPT_NAME' => '/hieraki', 'PATH_INFO' => '/' - assert_equal "/hieraki/", request.request_uri - assert_equal "/", request.path + assert_equal "/hieraki/", request.fullpath + assert_equal "/", request.path_info request = stub_request 'SCRIPT_NAME' => '/collaboration/hieraki', 'PATH_INFO' => '/books/edit/2' - assert_equal "/collaboration/hieraki/books/edit/2", request.request_uri - assert_equal "/books/edit/2", request.path + assert_equal "/collaboration/hieraki/books/edit/2", request.fullpath + assert_equal "/books/edit/2", request.path_info request = stub_request 'SCRIPT_NAME' => '/path', 'PATH_INFO' => '/of/some/uri', 'QUERY_STRING' => 'mapped=1' - assert_equal "/path/of/some/uri?mapped=1", request.request_uri - assert_equal "/of/some/uri", request.path + assert_equal "/path/of/some/uri?mapped=1", request.fullpath + assert_equal "/of/some/uri", request.path_info end -- cgit v1.2.3 From 18bcce596efaa4e77a202431ab5e736001a394c6 Mon Sep 17 00:00:00 2001 From: Carl Lerche Date: Wed, 3 Mar 2010 09:32:27 -0800 Subject: ActionController::Base.use_accept_header is not actually used anymore, so let's deprecate it. --- actionpack/lib/action_controller/metal/compatibility.rb | 10 ++++++++-- actionpack/test/controller/caching_test.rb | 3 --- actionpack/test/controller/content_type_test.rb | 12 ------------ actionpack/test/controller/mime_responds_test.rb | 4 ---- actionpack/test/dispatch/request_test.rb | 7 ------- 5 files changed, 8 insertions(+), 28 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/metal/compatibility.rb b/actionpack/lib/action_controller/metal/compatibility.rb index 93f7b8ca49..d6d8d612a3 100644 --- a/actionpack/lib/action_controller/metal/compatibility.rb +++ b/actionpack/lib/action_controller/metal/compatibility.rb @@ -35,8 +35,14 @@ module ActionController cattr_accessor :resource_action_separator self.resource_action_separator = "/" - cattr_accessor :use_accept_header - self.use_accept_header = true + def self.use_accept_header + ActiveSupport::Deprecation.warn "ActionController::Base.use_accept_header doesn't do anything anymore. " \ + "The accept header is always taken into account." + end + + def self.use_accept_header=(val) + use_accept_header + end self.page_cache_directory = defined?(Rails.public_path) ? Rails.public_path : "" diff --git a/actionpack/test/controller/caching_test.rb b/actionpack/test/controller/caching_test.rb index 37f7483427..e42ef85b98 100644 --- a/actionpack/test/controller/caching_test.rb +++ b/actionpack/test/controller/caching_test.rb @@ -306,12 +306,9 @@ class ActionCacheTest < ActionController::TestCase end def test_action_cache_conditional_options - old_use_accept_header = ActionController::Base.use_accept_header - ActionController::Base.use_accept_header = true @request.env['HTTP_ACCEPT'] = 'application/json' get :index assert !fragment_exist?('hostname.com/action_caching_test') - ActionController::Base.use_accept_header = old_use_accept_header end def test_action_cache_with_store_options diff --git a/actionpack/test/controller/content_type_test.rb b/actionpack/test/controller/content_type_test.rb index e5ffe20ecc..967107853b 100644 --- a/actionpack/test/controller/content_type_test.rb +++ b/actionpack/test/controller/content_type_test.rb @@ -145,18 +145,6 @@ end class AcceptBasedContentTypeTest < ActionController::TestCase tests OldContentTypeController - def setup - super - @_old_accept_header = ActionController::Base.use_accept_header - ActionController::Base.use_accept_header = true - end - - def teardown - super - ActionController::Base.use_accept_header = @_old_accept_header - end - - def test_render_default_content_types_for_respond_to @request.accept = Mime::HTML.to_s get :render_default_content_types_for_respond_to diff --git a/actionpack/test/controller/mime_responds_test.rb b/actionpack/test/controller/mime_responds_test.rb index 5e34773899..5c1eaf453c 100644 --- a/actionpack/test/controller/mime_responds_test.rb +++ b/actionpack/test/controller/mime_responds_test.rb @@ -155,13 +155,11 @@ class RespondToControllerTest < ActionController::TestCase def setup super - ActionController::Base.use_accept_header = true @request.host = "www.example.com" end def teardown super - ActionController::Base.use_accept_header = false end def test_html @@ -544,13 +542,11 @@ class RespondWithControllerTest < ActionController::TestCase def setup super - ActionController::Base.use_accept_header = true @request.host = "www.example.com" end def teardown super - ActionController::Base.use_accept_header = false end def test_using_resource diff --git a/actionpack/test/dispatch/request_test.rb b/actionpack/test/dispatch/request_test.rb index 84c06ca113..78200ca17e 100644 --- a/actionpack/test/dispatch/request_test.rb +++ b/actionpack/test/dispatch/request_test.rb @@ -435,11 +435,4 @@ protected def with_set(*args) args end - - def with_accept_header(value) - ActionController::Base.use_accept_header, old = value, ActionController::Base.use_accept_header - yield - ensure - ActionController::Base.use_accept_header = old - end end -- cgit v1.2.3 From 902d5a4f05c879674a3d010ac8ca76902308e18e Mon Sep 17 00:00:00 2001 From: Carl Lerche Date: Wed, 3 Mar 2010 09:41:23 -0800 Subject: Indicate that ActionController::Base.resource_action_separator is deprecated and only has an effect with the deprecated router DSL. --- actionpack/lib/action_controller/metal/compatibility.rb | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/metal/compatibility.rb b/actionpack/lib/action_controller/metal/compatibility.rb index d6d8d612a3..1a4d0349fe 100644 --- a/actionpack/lib/action_controller/metal/compatibility.rb +++ b/actionpack/lib/action_controller/metal/compatibility.rb @@ -32,8 +32,15 @@ module ActionController @_response) # Controls the resource action separator - cattr_accessor :resource_action_separator - self.resource_action_separator = "/" + def self.resource_action_separator + @resource_action_separator ||= "/" + end + + def self.resource_action_separator=(val) + ActiveSupport::Deprecation.warn "ActionController::Base.resource_action_separator is deprecated and only " \ + "works with the deprecated router DSL." + @resource_action_separator = val + end def self.use_accept_header ActiveSupport::Deprecation.warn "ActionController::Base.use_accept_header doesn't do anything anymore. " \ -- cgit v1.2.3 From 9a9caf646d020e33ccdeac0f9b114acec019b599 Mon Sep 17 00:00:00 2001 From: Carl Lerche Date: Wed, 3 Mar 2010 11:01:49 -0800 Subject: Add a BlockUntrustedIps middleware --- actionpack/lib/action_dispatch.rb | 1 + .../middleware/block_untrusted_ips.rb | 25 ++++++++++++++++++++++ 2 files changed, 26 insertions(+) create mode 100644 actionpack/lib/action_dispatch/middleware/block_untrusted_ips.rb (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch.rb b/actionpack/lib/action_dispatch.rb index 479ea959e6..1abb283b11 100644 --- a/actionpack/lib/action_dispatch.rb +++ b/actionpack/lib/action_dispatch.rb @@ -42,6 +42,7 @@ module ActionDispatch end autoload_under 'middleware' do + autoload :BlockUntrustedIps autoload :Callbacks autoload :Cascade autoload :Cookies diff --git a/actionpack/lib/action_dispatch/middleware/block_untrusted_ips.rb b/actionpack/lib/action_dispatch/middleware/block_untrusted_ips.rb new file mode 100644 index 0000000000..8aed0c45a6 --- /dev/null +++ b/actionpack/lib/action_dispatch/middleware/block_untrusted_ips.rb @@ -0,0 +1,25 @@ +module ActionDispatch + class BlockUntrustedIps + class SpoofAttackError < StandardError ; end + + def initialize(app) + @app = app + end + + def call(env) + if @env['HTTP_X_FORWARDED_FOR'] && @env['HTTP_CLIENT_IP'] + remote_ips = @env['HTTP_X_FORWARDED_FOR'].split(',') + + unless remote_ips.include?(@env['HTTP_CLIENT_IP']) + http_client_ip = @env['HTTP_CLIENT_IP'].inspect + http_forwarded_for = @env['HTTP_X_FORWARDED_FOR'].inspect + + raise SpoofAttackError, "IP spoofing attack?!\n " \ + "HTTP_CLIENT_IP=#{http_client_ip}\n HTTP_X_FORWARDED_FOR=http_forwarded_for" + end + end + + @app.call(env) + end + end +end \ No newline at end of file -- cgit v1.2.3 From 93422af5d5bc0285bd72cfb2fd9b59f6d64ba141 Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Wed, 3 Mar 2010 16:22:30 -0800 Subject: Move remote_ip to a middleware: * ActionController::Base.ip_spoofing_check deprecated => config.action_dispatch.ip_spoofing_check * ActionController::Base.trusted_proxies deprecated => config.action_dispatch.trusted_proxies --- actionpack/lib/action_dispatch.rb | 2 +- actionpack/lib/action_dispatch/http/request.rb | 31 +------------ .../middleware/block_untrusted_ips.rb | 25 ----------- .../lib/action_dispatch/middleware/remote_ip.rb | 51 ++++++++++++++++++++++ actionpack/lib/action_dispatch/railtie.rb | 1 + actionpack/test/dispatch/request_test.rb | 12 ++--- 6 files changed, 61 insertions(+), 61 deletions(-) delete mode 100644 actionpack/lib/action_dispatch/middleware/block_untrusted_ips.rb create mode 100644 actionpack/lib/action_dispatch/middleware/remote_ip.rb (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch.rb b/actionpack/lib/action_dispatch.rb index 1abb283b11..dfb8919561 100644 --- a/actionpack/lib/action_dispatch.rb +++ b/actionpack/lib/action_dispatch.rb @@ -42,13 +42,13 @@ module ActionDispatch end autoload_under 'middleware' do - autoload :BlockUntrustedIps autoload :Callbacks autoload :Cascade autoload :Cookies autoload :Flash autoload :Head autoload :ParamsParser + autoload :RemoteIp autoload :Rescue autoload :ShowExceptions autoload :Static diff --git a/actionpack/lib/action_dispatch/http/request.rb b/actionpack/lib/action_dispatch/http/request.rb index 7a17023ed2..56a2b9bf6a 100755 --- a/actionpack/lib/action_dispatch/http/request.rb +++ b/actionpack/lib/action_dispatch/http/request.rb @@ -119,36 +119,7 @@ module ActionDispatch # delimited list in the case of multiple chained proxies; the last # address which is not trusted is the originating IP. def remote_ip - remote_addr_list = @env['REMOTE_ADDR'] && @env['REMOTE_ADDR'].scan(/[^,\s]+/) - - unless remote_addr_list.blank? - not_trusted_addrs = remote_addr_list.reject {|addr| addr =~ TRUSTED_PROXIES || addr =~ ActionController::Base.trusted_proxies} - return not_trusted_addrs.first unless not_trusted_addrs.empty? - end - remote_ips = @env['HTTP_X_FORWARDED_FOR'] && @env['HTTP_X_FORWARDED_FOR'].split(',') - - if @env.include? 'HTTP_CLIENT_IP' - if ActionController::Base.ip_spoofing_check && remote_ips && !remote_ips.include?(@env['HTTP_CLIENT_IP']) - # We don't know which came from the proxy, and which from the user - raise ActionController::ActionControllerError.new < 1 && (TRUSTED_PROXIES =~ remote_ips.last.strip || ActionController::Base.trusted_proxies =~ remote_ips.last.strip) - remote_ips.pop - end - - return remote_ips.last.strip - end - - @env['REMOTE_ADDR'] + (@env["action_dispatch.remote_ip"] || ip).to_s end # Returns the lowercase name of the HTTP server software. diff --git a/actionpack/lib/action_dispatch/middleware/block_untrusted_ips.rb b/actionpack/lib/action_dispatch/middleware/block_untrusted_ips.rb deleted file mode 100644 index 8aed0c45a6..0000000000 --- a/actionpack/lib/action_dispatch/middleware/block_untrusted_ips.rb +++ /dev/null @@ -1,25 +0,0 @@ -module ActionDispatch - class BlockUntrustedIps - class SpoofAttackError < StandardError ; end - - def initialize(app) - @app = app - end - - def call(env) - if @env['HTTP_X_FORWARDED_FOR'] && @env['HTTP_CLIENT_IP'] - remote_ips = @env['HTTP_X_FORWARDED_FOR'].split(',') - - unless remote_ips.include?(@env['HTTP_CLIENT_IP']) - http_client_ip = @env['HTTP_CLIENT_IP'].inspect - http_forwarded_for = @env['HTTP_X_FORWARDED_FOR'].inspect - - raise SpoofAttackError, "IP spoofing attack?!\n " \ - "HTTP_CLIENT_IP=#{http_client_ip}\n HTTP_X_FORWARDED_FOR=http_forwarded_for" - end - end - - @app.call(env) - end - end -end \ No newline at end of file diff --git a/actionpack/lib/action_dispatch/middleware/remote_ip.rb b/actionpack/lib/action_dispatch/middleware/remote_ip.rb new file mode 100644 index 0000000000..c7d710b98e --- /dev/null +++ b/actionpack/lib/action_dispatch/middleware/remote_ip.rb @@ -0,0 +1,51 @@ +module ActionDispatch + class RemoteIp + class IpSpoofAttackError < StandardError ; end + + class RemoteIpGetter + def initialize(env, check_ip_spoofing, trusted_proxies) + @env = env + @check_ip_spoofing = check_ip_spoofing + @trusted_proxies = trusted_proxies + end + + def remote_addrs + @remote_addrs ||= begin + list = @env['REMOTE_ADDR'] ? @env['REMOTE_ADDR'].split(/[,\s]+/) : [] + list.reject { |addr| addr =~ @trusted_proxies } + end + end + + def to_s + return remote_addrs.first if remote_addrs.any? + + forwarded_ips = @env['HTTP_X_FORWARDED_FOR'] ? @env['HTTP_X_FORWARDED_FOR'].strip.split(/[,\s]+/) : [] + + if client_ip = @env['HTTP_CLIENT_IP'] + if @check_ip_spoofing && !forwarded_ips.include?(client_ip) + # We don't know which came from the proxy, and which from the user + raise IpSpoofAttackError, "IP spoofing attack?!" \ + "HTTP_CLIENT_IP=#{@env['HTTP_CLIENT_IP'].inspect}" \ + "HTTP_X_FORWARDED_FOR=#{@env['HTTP_X_FORWARDED_FOR'].inspect}" + end + return client_ip + end + + return forwarded_ips.reject { |ip| ip =~ @trusted_proxies }.last || @env["REMOTE_ADDR"] + end + end + + def initialize(app, check_ip_spoofing = true, trusted_proxies = nil) + @app = app + @check_ip_spoofing = check_ip_spoofing + regex = '(^127\.0\.0\.1$|^(10|172\.(1[6-9]|2[0-9]|30|31)|192\.168)\.)' + regex << "|(#{trusted_proxies})" if trusted_proxies + @trusted_proxies = Regexp.new(regex, "i") + end + + def call(env) + env["action_dispatch.remote_ip"] = RemoteIpGetter.new(env, @check_ip_spoofing, @trusted_proxies) + @app.call(env) + end + end +end \ No newline at end of file diff --git a/actionpack/lib/action_dispatch/railtie.rb b/actionpack/lib/action_dispatch/railtie.rb index 79e9464337..e486bd4079 100644 --- a/actionpack/lib/action_dispatch/railtie.rb +++ b/actionpack/lib/action_dispatch/railtie.rb @@ -6,6 +6,7 @@ module ActionDispatch railtie_name :action_dispatch config.action_dispatch.x_sendfile_header = "X-Sendfile" + config.action_dispatch.ip_spoofing_check = true # Prepare dispatcher callbacks and run 'prepare' callbacks initializer "action_dispatch.prepare_dispatcher" do |app| diff --git a/actionpack/test/dispatch/request_test.rb b/actionpack/test/dispatch/request_test.rb index 78200ca17e..3a07185586 100644 --- a/actionpack/test/dispatch/request_test.rb +++ b/actionpack/test/dispatch/request_test.rb @@ -42,7 +42,7 @@ class RequestTest < ActiveSupport::TestCase request = stub_request 'HTTP_X_FORWARDED_FOR' => '1.1.1.1', 'HTTP_CLIENT_IP' => '2.2.2.2' - e = assert_raise(ActionController::ActionControllerError) { + e = assert_raise(ActionDispatch::RemoteIp::IpSpoofAttackError) { request.remote_ip } assert_match /IP spoofing attack/, e.message @@ -54,18 +54,17 @@ class RequestTest < ActiveSupport::TestCase # example is WAP. Since the cellular network is not IP based, it's a # leap of faith to assume that their proxies are ever going to set the # HTTP_CLIENT_IP/HTTP_X_FORWARDED_FOR headers properly. - ActionController::Base.ip_spoofing_check = false request = stub_request 'HTTP_X_FORWARDED_FOR' => '1.1.1.1', - 'HTTP_CLIENT_IP' => '2.2.2.2' + 'HTTP_CLIENT_IP' => '2.2.2.2', + :ip_spoofing_check => false assert_equal '2.2.2.2', request.remote_ip - ActionController::Base.ip_spoofing_check = true request = stub_request 'HTTP_X_FORWARDED_FOR' => '8.8.8.8, 9.9.9.9' assert_equal '9.9.9.9', request.remote_ip end test "remote ip with user specified trusted proxies" do - ActionController::Base.trusted_proxies = /^67\.205\.106\.73$/i + @trusted_proxies = /^67\.205\.106\.73$/i request = stub_request 'REMOTE_ADDR' => '67.205.106.73', 'HTTP_X_FORWARDED_FOR' => '3.4.5.6' @@ -429,6 +428,9 @@ class RequestTest < ActiveSupport::TestCase protected def stub_request(env = {}) + ip_spoofing_check = env.key?(:ip_spoofing_check) ? env.delete(:ip_spoofing_check) : true + ip_app = ActionDispatch::RemoteIp.new(Proc.new { }, ip_spoofing_check, @trusted_proxies) + ip_app.call(env) ActionDispatch::Request.new(env) end -- cgit v1.2.3 From 52efbdcdefa678ae2ee9530bcfefd0e2529b188f Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Wed, 3 Mar 2010 16:23:00 -0800 Subject: Add caller to request_uri deprecation notice --- actionpack/lib/action_dispatch/http/url.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/http/url.rb b/actionpack/lib/action_dispatch/http/url.rb index f7afbe7fed..b64a83c62e 100644 --- a/actionpack/lib/action_dispatch/http/url.rb +++ b/actionpack/lib/action_dispatch/http/url.rb @@ -88,7 +88,7 @@ module ActionDispatch # Returns the request URI, accounting for server idiosyncrasies. # WEBrick includes the full URL. IIS leaves REQUEST_URI blank. def request_uri - ActiveSupport::Deprecation.warn "Using #request_uri is deprecated. Use fullpath instead." + ActiveSupport::Deprecation.warn "Using #request_uri is deprecated. Use fullpath instead.", caller fullpath end -- cgit v1.2.3 From 786724107c3dedaeccaae9e187458b48df472f90 Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Wed, 3 Mar 2010 16:32:27 -0800 Subject: Deprecate IP spoofing settings that are directly on the controller in favor of configuring a middleware --- .../lib/action_controller/metal/compatibility.rb | 33 +++++++++++++++++----- actionpack/test/dispatch/request_test.rb | 2 -- 2 files changed, 26 insertions(+), 9 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/metal/compatibility.rb b/actionpack/lib/action_controller/metal/compatibility.rb index 1a4d0349fe..ab59ffc0b4 100644 --- a/actionpack/lib/action_controller/metal/compatibility.rb +++ b/actionpack/lib/action_controller/metal/compatibility.rb @@ -57,11 +57,6 @@ module ActionController # and images to a dedicated asset server away from the main web server. Example: # ActionController::Base.asset_host = "http://assets.example.com" cattr_accessor :asset_host - - cattr_accessor :ip_spoofing_check - self.ip_spoofing_check = true - - cattr_accessor :trusted_proxies end def self.deprecated_config_accessor(option, message = nil) @@ -119,7 +114,7 @@ module ActionController end def consider_all_requests_local=(value) - ActiveSupport::Deprecation.warn "ActionController::Base.consider_all_requests_local= is no longer effective. " << + ActiveSupport::Deprecation.warn "ActionController::Base.consider_all_requests_local= is deprecated. " << "Please configure it on your application with config.consider_all_requests_local=" Rails.application.config.consider_all_requests_local = value end @@ -131,11 +126,35 @@ module ActionController end def allow_concurrency=(value) - ActiveSupport::Deprecation.warn "ActionController::Base.allow_concurrency= is no longer effective. " << + ActiveSupport::Deprecation.warn "ActionController::Base.allow_concurrency= is deprecated. " << "Please configure it on your application with config.allow_concurrency=" Rails.application.config.allow_concurrency = value end + def ip_spoofing_check=(value) + ActiveSupport::Deprecation.warn "ActionController::Base.ip_spoofing_check= is deprecated. " << + "Please configure it on your application with config.action_dispatch.ip_spoofing_check=" + Rails.application.config.action_disaptch.ip_spoofing_check = value + end + + def ip_spoofing_check + ActiveSupport::Deprecation.warn "ActionController::Base.ip_spoofing_check is deprecated. " + "Configuring ip_spoofing_check on the application configures a middleware." + Rails.application.config.action_disaptch.ip_spoofing_check + end + + def trusted_proxies=(value) + ActiveSupport::Deprecation.warn "ActionController::Base.trusted_proxies= is deprecated. " << + "Please configure it on your application with config.action_dispatch.trusted_proxies=" + Rails.application.config.action_dispatch.ip_spoofing_check = value + end + + def trusted_proxies + ActiveSupport::Deprecation.warn "ActionController::Base.trusted_proxies is deprecated. " << + "Configuring trusted_proxies on the application configures a middleware." + Rails.application.config.action_dispatch.ip_spoofing_check = value + end + def rescue_action(env) raise env["action_dispatch.rescue.exception"] end diff --git a/actionpack/test/dispatch/request_test.rb b/actionpack/test/dispatch/request_test.rb index 3a07185586..badef4e92e 100644 --- a/actionpack/test/dispatch/request_test.rb +++ b/actionpack/test/dispatch/request_test.rb @@ -87,8 +87,6 @@ class RequestTest < ActiveSupport::TestCase request = stub_request 'HTTP_X_FORWARDED_FOR' => '9.9.9.9, 3.4.5.6, 10.0.0.1, 67.205.106.73' assert_equal '3.4.5.6', request.remote_ip - - ActionController::Base.trusted_proxies = nil end test "domains" do -- cgit v1.2.3 From 54302ef55bffd1a93f20f5d1ae81217b2e4149c4 Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Wed, 3 Mar 2010 17:08:54 -0800 Subject: Add caller to deprecation notices --- .../lib/action_controller/metal/compatibility.rb | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/metal/compatibility.rb b/actionpack/lib/action_controller/metal/compatibility.rb index ab59ffc0b4..9471f36de3 100644 --- a/actionpack/lib/action_controller/metal/compatibility.rb +++ b/actionpack/lib/action_controller/metal/compatibility.rb @@ -70,7 +70,7 @@ module ActionController ClassMethods.class_eval <<-RUBY, __FILE__, __LINE__ + 1 def #{option} - ActiveSupport::Deprecation.warn #{message.inspect} + ActiveSupport::Deprecation.warn #{message.inspect}, caller config.#{option} end RUBY @@ -82,7 +82,7 @@ module ActionController ClassMethods.class_eval <<-RUBY, __FILE__, __LINE__ + 1 def #{option}=(val) - ActiveSupport::Deprecation.warn #{message.inspect} + ActiveSupport::Deprecation.warn #{message.inspect}, caller config.#{option} = val end RUBY @@ -109,49 +109,49 @@ module ActionController module ClassMethods def consider_all_requests_local ActiveSupport::Deprecation.warn "ActionController::Base.consider_all_requests_local is deprecated, " << - "use Rails.application.config.consider_all_requests_local instead" + "use Rails.application.config.consider_all_requests_local instead", caller Rails.application.config.consider_all_requests_local end def consider_all_requests_local=(value) ActiveSupport::Deprecation.warn "ActionController::Base.consider_all_requests_local= is deprecated. " << - "Please configure it on your application with config.consider_all_requests_local=" + "Please configure it on your application with config.consider_all_requests_local=", caller Rails.application.config.consider_all_requests_local = value end def allow_concurrency ActiveSupport::Deprecation.warn "ActionController::Base.allow_concurrency is deprecated, " << - "use Rails.application.config.allow_concurrency instead" + "use Rails.application.config.allow_concurrency instead", caller Rails.application.config.allow_concurrency end def allow_concurrency=(value) ActiveSupport::Deprecation.warn "ActionController::Base.allow_concurrency= is deprecated. " << - "Please configure it on your application with config.allow_concurrency=" + "Please configure it on your application with config.allow_concurrency=", caller Rails.application.config.allow_concurrency = value end def ip_spoofing_check=(value) ActiveSupport::Deprecation.warn "ActionController::Base.ip_spoofing_check= is deprecated. " << - "Please configure it on your application with config.action_dispatch.ip_spoofing_check=" + "Please configure it on your application with config.action_dispatch.ip_spoofing_check=", caller Rails.application.config.action_disaptch.ip_spoofing_check = value end def ip_spoofing_check - ActiveSupport::Deprecation.warn "ActionController::Base.ip_spoofing_check is deprecated. " - "Configuring ip_spoofing_check on the application configures a middleware." + ActiveSupport::Deprecation.warn "ActionController::Base.ip_spoofing_check is deprecated. " << + "Configuring ip_spoofing_check on the application configures a middleware.", caller Rails.application.config.action_disaptch.ip_spoofing_check end def trusted_proxies=(value) ActiveSupport::Deprecation.warn "ActionController::Base.trusted_proxies= is deprecated. " << - "Please configure it on your application with config.action_dispatch.trusted_proxies=" + "Please configure it on your application with config.action_dispatch.trusted_proxies=", caller Rails.application.config.action_dispatch.ip_spoofing_check = value end def trusted_proxies ActiveSupport::Deprecation.warn "ActionController::Base.trusted_proxies is deprecated. " << - "Configuring trusted_proxies on the application configures a middleware." + "Configuring trusted_proxies on the application configures a middleware.", caller Rails.application.config.action_dispatch.ip_spoofing_check = value end -- cgit v1.2.3 From b160663bd13d08bf845bc8cdf87a2c5e7e46f901 Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Wed, 3 Mar 2010 17:36:08 -0800 Subject: Start refactoring the method of configuring ActionView --- actionpack/lib/action_controller/railtie.rb | 14 ++++++++++++++ actionpack/lib/action_view/base.rb | 12 ++---------- actionpack/lib/action_view/helpers/asset_tag_helper.rb | 7 ------- actionpack/lib/action_view/test_case.rb | 4 ++++ actionpack/test/abstract_unit.rb | 15 +++++++++++++++ actionpack/test/template/asset_tag_helper_test.rb | 14 ++------------ actionpack/test/template/form_tag_helper_test.rb | 9 ++++----- actionpack/test/template/url_helper_test.rb | 9 ++------- 8 files changed, 43 insertions(+), 41 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/railtie.rb b/actionpack/lib/action_controller/railtie.rb index 07c6b8f2b6..f4c51ba760 100644 --- a/actionpack/lib/action_controller/railtie.rb +++ b/actionpack/lib/action_controller/railtie.rb @@ -17,7 +17,21 @@ module ActionController ActionController::Base.logger ||= Rails.logger end + # assets_dir = defined?(Rails.public_path) ? Rails.public_path : "public" + # ActionView::DEFAULT_CONFIG = { + # :assets_dir => assets_dir, + # :javascripts_dir => "#{assets_dir}/javascripts", + # :stylesheets_dir => "#{assets_dir}/stylesheets", + # } + + initializer "action_controller.set_configs" do |app| + paths = app.config.paths + ac = app.config.action_controller + ac.assets_dir = paths.public + ac.javascripts_dir = paths.public.javascripts + ac.stylesheets_dir = paths.public.stylesheets + app.config.action_controller.each do |k,v| ActionController::Base.send "#{k}=", v end diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index 2d2b53a6ce..87a1972fb4 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -175,15 +175,6 @@ module ActionView #:nodoc: include Helpers, Rendering, Partials, ::ERB::Util - def config - self.config = DEFAULT_CONFIG unless @config - @config - end - - def config=(config) - @config = ActiveSupport::OrderedOptions.new.merge(config) - end - extend ActiveSupport::Memoizable attr_accessor :base_path, :assigns, :template_extension @@ -306,12 +297,13 @@ module ActionView #:nodoc: @helpers = self.class.helpers || Module.new @_controller = controller + @_config = controller.config if controller @_content_for = Hash.new {|h,k| h[k] = ActiveSupport::SafeBuffer.new } @_virtual_path = nil self.view_paths = view_paths end - attr_internal :controller, :template + attr_internal :controller, :template, :config attr_reader :view_paths def view_paths=(paths) diff --git a/actionpack/lib/action_view/helpers/asset_tag_helper.rb b/actionpack/lib/action_view/helpers/asset_tag_helper.rb index 5f76ff456e..b52d255d1f 100644 --- a/actionpack/lib/action_view/helpers/asset_tag_helper.rb +++ b/actionpack/lib/action_view/helpers/asset_tag_helper.rb @@ -133,13 +133,6 @@ module ActionView # change. You can use something like Live HTTP Headers for Firefox to verify # that the cache is indeed working. module AssetTagHelper - assets_dir = defined?(Rails.public_path) ? Rails.public_path : "public" - ActionView::DEFAULT_CONFIG = { - :assets_dir => assets_dir, - :javascripts_dir => "#{assets_dir}/javascripts", - :stylesheets_dir => "#{assets_dir}/stylesheets", - } - JAVASCRIPT_DEFAULT_SOURCES = ['prototype', 'effects', 'dragdrop', 'controls', 'rails'].freeze unless const_defined?(:JAVASCRIPT_DEFAULT_SOURCES) # Returns a link tag that browsers and news readers can use to auto-detect diff --git a/actionpack/lib/action_view/test_case.rb b/actionpack/lib/action_view/test_case.rb index 12142a3728..72dbead14b 100644 --- a/actionpack/lib/action_view/test_case.rb +++ b/actionpack/lib/action_view/test_case.rb @@ -62,6 +62,10 @@ module ActionView make_test_case_available_to_view! end + def config + @controller.config + end + def render(options = {}, local_assigns = {}, &block) @rendered << output = _view.render(options, local_assigns, &block) output diff --git a/actionpack/test/abstract_unit.rb b/actionpack/test/abstract_unit.rb index f1e8779cfa..7223a7824e 100644 --- a/actionpack/test/abstract_unit.rb +++ b/actionpack/test/abstract_unit.rb @@ -105,6 +105,21 @@ class RoutedRackApp end end +class BasicController + attr_accessor :request + + def config + @config ||= ActiveSupport::InheritableOptions.new(ActionController::Metal.config).tap do |config| + # VIEW TODO: View tests should not require a controller + public_dir = File.expand_path("../fixtures/public", __FILE__) + config.assets_dir = public_dir + config.javascripts_dir = "#{public_dir}/javascripts" + config.stylesheets_dir = "#{public_dir}/stylesheets" + config + end + end +end + class ActionController::IntegrationTest < ActiveSupport::TestCase def self.build_app(routes = nil) RoutedRackApp.new(routes || ActionDispatch::Routing::RouteSet.new) do |middleware| diff --git a/actionpack/test/template/asset_tag_helper_test.rb b/actionpack/test/template/asset_tag_helper_test.rb index ccc39e9af6..8b24f66a6e 100644 --- a/actionpack/test/template/asset_tag_helper_test.rb +++ b/actionpack/test/template/asset_tag_helper_test.rb @@ -12,13 +12,6 @@ end class AssetTagHelperTest < ActionView::TestCase tests ActionView::Helpers::AssetTagHelper - DEFAULT_CONFIG = ActionView::DEFAULT_CONFIG.merge( - :assets_dir => File.dirname(__FILE__) + "/../fixtures/public", - :javascripts_dir => File.dirname(__FILE__) + "/../fixtures/public/javascripts", - :stylesheets_dir => File.dirname(__FILE__) + "/../fixtures/public/stylesheets") - - include ActiveSupport::Configurable - def setup super silence_warnings do @@ -41,7 +34,7 @@ class AssetTagHelperTest < ActionView::TestCase ) end - @controller = Class.new(FakeController) do + @controller = Class.new(BasicController) do def url_for(*args) "http://www.example.com" end end.new @@ -883,12 +876,9 @@ end class AssetTagHelperNonVhostTest < ActionView::TestCase tests ActionView::Helpers::AssetTagHelper - DEFAULT_CONFIG = ActionView::DEFAULT_CONFIG - include ActiveSupport::Configurable - def setup super - @controller = Class.new(FakeController) do + @controller = Class.new(BasicController) do def url_for(options) "http://www.example.com/collaboration/hieraki" end diff --git a/actionpack/test/template/form_tag_helper_test.rb b/actionpack/test/template/form_tag_helper_test.rb index 0ceec1afbf..c7d4bc986c 100644 --- a/actionpack/test/template/form_tag_helper_test.rb +++ b/actionpack/test/template/form_tag_helper_test.rb @@ -3,17 +3,16 @@ require 'abstract_unit' class FormTagHelperTest < ActionView::TestCase tests ActionView::Helpers::FormTagHelper - include ActiveSupport::Configurable - DEFAULT_CONFIG = ActionView::DEFAULT_CONFIG + # include ActiveSupport::Configurable + # DEFAULT_CONFIG = ActionView::DEFAULT_CONFIG def setup super - @controller = Class.new do + @controller = Class.new(BasicController) do def url_for(options) "http://www.example.com" end - end - @controller = @controller.new + end.new end VALID_HTML_ID = /^[A-Za-z][-_:.A-Za-z0-9]*$/ # see http://www.w3.org/TR/html4/types.html#type-name diff --git a/actionpack/test/template/url_helper_test.rb b/actionpack/test/template/url_helper_test.rb index d8ccb380a6..533a07b6f4 100644 --- a/actionpack/test/template/url_helper_test.rb +++ b/actionpack/test/template/url_helper_test.rb @@ -4,19 +4,14 @@ require 'active_support/ordered_options' require 'controller/fake_controllers' class UrlHelperTest < ActionView::TestCase - include ActiveSupport::Configurable - DEFAULT_CONFIG = ActionView::DEFAULT_CONFIG def setup super - @controller = Class.new do - attr_accessor :url, :request + @controller = Class.new(BasicController) do + attr_accessor :url def url_for(options) url end - def config - ActiveSupport::InheritableOptions.new({}) - end end @controller = @controller.new -- cgit v1.2.3 From 1f0f05b10c924d2f0d0ff4c74cbd979e77deea1d Mon Sep 17 00:00:00 2001 From: Carl Lerche Date: Wed, 3 Mar 2010 19:45:08 -0800 Subject: Move the original config method onto AbstractController --- actionpack/lib/abstract_controller/base.rb | 8 ++++++++ actionpack/lib/action_controller/metal.rb | 8 -------- actionpack/test/abstract_unit.rb | 2 +- actionpack/test/template/asset_tag_helper_test.rb | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/abstract_controller/base.rb b/actionpack/lib/abstract_controller/base.rb index e14818e464..cbd021e246 100644 --- a/actionpack/lib/abstract_controller/base.rb +++ b/actionpack/lib/abstract_controller/base.rb @@ -28,6 +28,10 @@ module AbstractController @descendants ||= [] end + def config + @config ||= ActiveSupport::InheritableOptions.new(superclass < Base ? superclass.config : {}) + end + # A list of all internal methods for a controller. This finds the first # abstract superclass of a controller, and gets a list of all public # instance methods on that abstract class. Public instance methods of @@ -95,6 +99,10 @@ module AbstractController @_formats = nil end + def config + self.class.config + end + # Calls the action going through the entire action dispatch stack. # # The actual method that is called is determined by calling diff --git a/actionpack/lib/action_controller/metal.rb b/actionpack/lib/action_controller/metal.rb index 1f6bbeb7c5..4374ab0a6b 100644 --- a/actionpack/lib/action_controller/metal.rb +++ b/actionpack/lib/action_controller/metal.rb @@ -11,14 +11,6 @@ module ActionController class Metal < AbstractController::Base abstract! - def self.config - @config ||= ActiveSupport::InheritableOptions.new(superclass < Metal ? superclass.config : {}) - end - - def config - self.class.config - end - # :api: public attr_internal :params, :env diff --git a/actionpack/test/abstract_unit.rb b/actionpack/test/abstract_unit.rb index 7223a7824e..29270ed228 100644 --- a/actionpack/test/abstract_unit.rb +++ b/actionpack/test/abstract_unit.rb @@ -109,7 +109,7 @@ class BasicController attr_accessor :request def config - @config ||= ActiveSupport::InheritableOptions.new(ActionController::Metal.config).tap do |config| + @config ||= ActiveSupport::InheritableOptions.new(ActionController::Base.config).tap do |config| # VIEW TODO: View tests should not require a controller public_dir = File.expand_path("../fixtures/public", __FILE__) config.assets_dir = public_dir diff --git a/actionpack/test/template/asset_tag_helper_test.rb b/actionpack/test/template/asset_tag_helper_test.rb index 8b24f66a6e..bbfab05a0f 100644 --- a/actionpack/test/template/asset_tag_helper_test.rb +++ b/actionpack/test/template/asset_tag_helper_test.rb @@ -5,7 +5,7 @@ class FakeController attr_accessor :request def config - @config ||= ActiveSupport::InheritableOptions.new(ActionController::Metal.config) + @config ||= ActiveSupport::InheritableOptions.new(ActionController::Base.config) end end -- cgit v1.2.3 From 15b3b74624eb4c5ae383956950cab12ca9899131 Mon Sep 17 00:00:00 2001 From: Carl Lerche Date: Wed, 3 Mar 2010 21:16:35 -0800 Subject: Fix all the broken tests due to the AC configuration refactor --- .../lib/action_controller/metal/compatibility.rb | 3 +++ .../action_controller/metal/session_management.rb | 22 +++++++++++++--------- actionpack/lib/action_controller/railtie.rb | 3 +++ 3 files changed, 19 insertions(+), 9 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/metal/compatibility.rb b/actionpack/lib/action_controller/metal/compatibility.rb index 9471f36de3..4c2136de8a 100644 --- a/actionpack/lib/action_controller/metal/compatibility.rb +++ b/actionpack/lib/action_controller/metal/compatibility.rb @@ -91,6 +91,9 @@ module ActionController deprecated_config_writer :session_store deprecated_config_writer :session_options deprecated_config_accessor :relative_url_root, "relative_url_root is ineffective. Please stop using it" + deprecated_config_accessor :assets_dir + deprecated_config_accessor :javascripts_dir + deprecated_config_accessor :stylesheets_dir # For old tests def initialize_template_class(*) end diff --git a/actionpack/lib/action_controller/metal/session_management.rb b/actionpack/lib/action_controller/metal/session_management.rb index 09ef9261a4..ce8b20964b 100644 --- a/actionpack/lib/action_controller/metal/session_management.rb +++ b/actionpack/lib/action_controller/metal/session_management.rb @@ -3,24 +3,28 @@ module ActionController #:nodoc: extend ActiveSupport::Concern included do - self.config.session_store ||= :cookie_store + # This is still needed for the session secret for some reason. self.config.session_options ||= {} end + def self.session_store_for(store) + case store + when :active_record_store + ActiveRecord::SessionStore + when Symbol + ActionDispatch::Session.const_get(store.to_s.camelize) + else + store + end + end + module ClassMethods def session_options config.session_options end def session_store - case store = config.session_store - when :active_record_store - ActiveRecord::SessionStore - when Symbol - ActionDispatch::Session.const_get(store.to_s.camelize) - else - store - end + SessionManagement.session_store_for(config.session_store) end def session=(options = {}) diff --git a/actionpack/lib/action_controller/railtie.rb b/actionpack/lib/action_controller/railtie.rb index f4c51ba760..3a084cdf67 100644 --- a/actionpack/lib/action_controller/railtie.rb +++ b/actionpack/lib/action_controller/railtie.rb @@ -13,6 +13,9 @@ module ActionController log_subscriber ActionController::Railties::LogSubscriber.new + config.action_controller.session_store = :cookie_store + config.action_controller.session_options = {} + initializer "action_controller.logger" do ActionController::Base.logger ||= Rails.logger end -- cgit v1.2.3 From 7dbf5c820b3454da8194e2c823cdfd3982657f03 Mon Sep 17 00:00:00 2001 From: Carl Lerche Date: Wed, 3 Mar 2010 21:29:26 -0800 Subject: Tweak how ActionPack handles InheritableOptions --- actionpack/lib/abstract_controller/base.rb | 2 ++ actionpack/lib/action_controller/metal.rb | 1 - actionpack/lib/action_view/base.rb | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/abstract_controller/base.rb b/actionpack/lib/abstract_controller/base.rb index cbd021e246..8e24d55ad0 100644 --- a/actionpack/lib/abstract_controller/base.rb +++ b/actionpack/lib/abstract_controller/base.rb @@ -1,3 +1,5 @@ +require 'active_support/ordered_options' + module AbstractController class Error < StandardError; end class ActionNotFound < StandardError; end diff --git a/actionpack/lib/action_controller/metal.rb b/actionpack/lib/action_controller/metal.rb index 4374ab0a6b..5e0ed201cb 100644 --- a/actionpack/lib/action_controller/metal.rb +++ b/actionpack/lib/action_controller/metal.rb @@ -1,5 +1,4 @@ require 'active_support/core_ext/class/attribute' -require 'active_support/ordered_options' module ActionController # ActionController::Metal provides a way to get a valid Rack application from a controller. diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index 87a1972fb4..76f9eb2b0d 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -297,7 +297,7 @@ module ActionView #:nodoc: @helpers = self.class.helpers || Module.new @_controller = controller - @_config = controller.config if controller + @_config = ActiveSupport::InheritableOptions.new(controller.config) if controller @_content_for = Hash.new {|h,k| h[k] = ActiveSupport::SafeBuffer.new } @_virtual_path = nil self.view_paths = view_paths -- cgit v1.2.3 From 13a932cddcd3165792d3454009b6d07471031a2c Mon Sep 17 00:00:00 2001 From: Carl Lerche Date: Wed, 3 Mar 2010 21:32:05 -0800 Subject: Modifying configurations on the instance of a controller should not affect the class --- actionpack/lib/abstract_controller/base.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/abstract_controller/base.rb b/actionpack/lib/abstract_controller/base.rb index 8e24d55ad0..24f3b552ba 100644 --- a/actionpack/lib/abstract_controller/base.rb +++ b/actionpack/lib/abstract_controller/base.rb @@ -102,7 +102,7 @@ module AbstractController end def config - self.class.config + @config ||= ActiveSupport::InheritableOptions.new(self.class.config) end # Calls the action going through the entire action dispatch stack. -- cgit v1.2.3 From 9eddc8544417323dcd8460026027c3359b2ad717 Mon Sep 17 00:00:00 2001 From: Carl Lerche Date: Thu, 4 Mar 2010 00:52:10 -0800 Subject: Add a method for configuring abstract controllers --- actionpack/lib/abstract_controller/base.rb | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'actionpack') diff --git a/actionpack/lib/abstract_controller/base.rb b/actionpack/lib/abstract_controller/base.rb index 24f3b552ba..ea88a2d24d 100644 --- a/actionpack/lib/abstract_controller/base.rb +++ b/actionpack/lib/abstract_controller/base.rb @@ -34,6 +34,10 @@ module AbstractController @config ||= ActiveSupport::InheritableOptions.new(superclass < Base ? superclass.config : {}) end + def configure + yield config + end + # A list of all internal methods for a controller. This finds the first # abstract superclass of a controller, and gets a list of all public # instance methods on that abstract class. Public instance methods of -- cgit v1.2.3 From ad2e6ee4ec5cc6c6bc5f11bfb875e582dbe55468 Mon Sep 17 00:00:00 2001 From: Carl Lerche Date: Thu, 4 Mar 2010 01:01:21 -0800 Subject: Fix a bunch of failing AP / AM specs created from the previous AbstractController configuration refactor. --- .../lib/action_view/helpers/asset_tag_helper.rb | 2 +- actionpack/test/template/asset_tag_helper_test.rb | 42 ++++++++-------------- 2 files changed, 16 insertions(+), 28 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/asset_tag_helper.rb b/actionpack/lib/action_view/helpers/asset_tag_helper.rb index b52d255d1f..de3d61ebbe 100644 --- a/actionpack/lib/action_view/helpers/asset_tag_helper.rb +++ b/actionpack/lib/action_view/helpers/asset_tag_helper.rb @@ -670,7 +670,7 @@ module ActionView # or the value returned from invoking the proc if it's a proc or the value from # invoking call if it's an object responding to call. def compute_asset_host(source) - if host = ActionController::Base.asset_host + if host = config.asset_host if host.is_a?(Proc) || host.respond_to?(:call) case host.is_a?(Proc) ? host.arity : host.method(:call).arity when 2 diff --git a/actionpack/test/template/asset_tag_helper_test.rb b/actionpack/test/template/asset_tag_helper_test.rb index bbfab05a0f..6089048088 100644 --- a/actionpack/test/template/asset_tag_helper_test.rb +++ b/actionpack/test/template/asset_tag_helper_test.rb @@ -401,7 +401,7 @@ class AssetTagHelperTest < ActionView::TestCase def test_caching_image_path_with_caching_and_proc_asset_host_using_request ENV['RAILS_ASSET_ID'] = '' - ActionController::Base.asset_host = Proc.new do |source, request| + @controller.config.asset_host = Proc.new do |source, request| if request.ssl? "#{request.protocol}#{request.host_with_port}" else @@ -409,8 +409,6 @@ class AssetTagHelperTest < ActionView::TestCase end end - ActionController::Base.perform_caching = true - @controller.request.stubs(:ssl?).returns(false) assert_equal "http://assets15.example.com/images/xml.png", image_path("xml.png") @@ -421,7 +419,7 @@ class AssetTagHelperTest < ActionView::TestCase def test_caching_javascript_include_tag_when_caching_on ENV["RAILS_ASSET_ID"] = "" - ActionController::Base.asset_host = 'http://a0.example.com' + @controller.config.asset_host = 'http://a0.example.com' ActionController::Base.perform_caching = true assert_dom_equal( @@ -453,7 +451,7 @@ class AssetTagHelperTest < ActionView::TestCase def test_caching_javascript_include_tag_when_caching_on_with_proc_asset_host ENV['RAILS_ASSET_ID'] = '' - ActionController::Base.asset_host = Proc.new { |source| "http://a#{source.length}.example.com" } + @controller.config.asset_host = Proc.new { |source| "http://a#{source.length}.example.com" } ActionController::Base.perform_caching = true assert_equal '/javascripts/scripts.js'.length, 23 @@ -470,7 +468,7 @@ class AssetTagHelperTest < ActionView::TestCase def test_caching_javascript_include_tag_when_caching_on_with_2_argument_proc_asset_host ENV['RAILS_ASSET_ID'] = '' - ActionController::Base.asset_host = Proc.new { |source, request| + @controller.config.asset_host = Proc.new { |source, request| if request.ssl? "#{request.protocol}#{request.host_with_port}" else @@ -507,7 +505,7 @@ class AssetTagHelperTest < ActionView::TestCase def test_caching_javascript_include_tag_when_caching_on_with_2_argument_object_asset_host ENV['RAILS_ASSET_ID'] = '' - ActionController::Base.asset_host = Class.new do + @controller.config.asset_host = Class.new do def call(source, request) if request.ssl? "#{request.protocol}#{request.host_with_port}" @@ -547,7 +545,7 @@ class AssetTagHelperTest < ActionView::TestCase def test_caching_javascript_include_tag_when_caching_on_and_using_subdirectory ENV["RAILS_ASSET_ID"] = "" - ActionController::Base.asset_host = 'http://a%d.example.com' + @controller.config.asset_host = 'http://a%d.example.com' ActionController::Base.perform_caching = true hash = '/javascripts/cache/money.js'.hash % 4 @@ -563,7 +561,7 @@ class AssetTagHelperTest < ActionView::TestCase def test_caching_javascript_include_tag_with_all_and_recursive_puts_defaults_at_the_start_of_the_file ENV["RAILS_ASSET_ID"] = "" - ActionController::Base.asset_host = 'http://a0.example.com' + @controller.config.asset_host = 'http://a0.example.com' ActionController::Base.perform_caching = true assert_dom_equal( @@ -584,7 +582,7 @@ class AssetTagHelperTest < ActionView::TestCase def test_caching_javascript_include_tag_with_all_puts_defaults_at_the_start_of_the_file ENV["RAILS_ASSET_ID"] = "" - ActionController::Base.asset_host = 'http://a0.example.com' + @controller.config.asset_host = 'http://a0.example.com' ActionController::Base.perform_caching = true assert_dom_equal( @@ -692,7 +690,7 @@ class AssetTagHelperTest < ActionView::TestCase def test_caching_stylesheet_link_tag_when_caching_on ENV["RAILS_ASSET_ID"] = "" - ActionController::Base.asset_host = 'http://a0.example.com' + @controller.config.asset_host = 'http://a0.example.com' ActionController::Base.perform_caching = true assert_dom_equal( @@ -802,7 +800,7 @@ class AssetTagHelperTest < ActionView::TestCase def test_caching_stylesheet_link_tag_when_caching_on_with_proc_asset_host ENV["RAILS_ASSET_ID"] = "" - ActionController::Base.asset_host = Proc.new { |source| "http://a#{source.length}.example.com" } + @controller.config.asset_host = Proc.new { |source| "http://a#{source.length}.example.com" } ActionController::Base.perform_caching = true assert_equal '/stylesheets/styles.css'.length, 23 @@ -911,43 +909,33 @@ class AssetTagHelperNonVhostTest < ActionView::TestCase end def test_should_compute_proper_path_with_asset_host - ActionController::Base.asset_host = "http://assets.example.com" + @controller.config.asset_host = "http://assets.example.com" assert_dom_equal(%(), auto_discovery_link_tag) assert_dom_equal(%(http://assets.example.com/collaboration/hieraki/javascripts/xmlhr.js), javascript_path("xmlhr")) assert_dom_equal(%(http://assets.example.com/collaboration/hieraki/stylesheets/style.css), stylesheet_path("style")) assert_dom_equal(%(http://assets.example.com/collaboration/hieraki/images/xml.png), image_path("xml.png")) assert_dom_equal(%(Mouse), image_tag("mouse.png", :mouseover => "/images/mouse_over.png")) assert_dom_equal(%(Mouse2), image_tag("mouse2.png", :mouseover => image_path("mouse_over2.png"))) - ensure - ActionController::Base.asset_host = "" end def test_should_ignore_asset_host_on_complete_url - ActionController::Base.asset_host = "http://assets.example.com" + @controller.config.asset_host = "http://assets.example.com" assert_dom_equal(%(), stylesheet_link_tag("http://bar.example.com/stylesheets/style.css")) - ensure - ActionController::Base.asset_host = "" end def test_should_wildcard_asset_host_between_zero_and_four - ActionController::Base.asset_host = 'http://a%d.example.com' + @controller.config.asset_host = 'http://a%d.example.com' assert_match %r(http://a[0123].example.com/collaboration/hieraki/images/xml.png), image_path('xml.png') - ensure - ActionController::Base.asset_host = nil end def test_asset_host_without_protocol_should_use_request_protocol - ActionController::Base.asset_host = 'a.example.com' + @controller.config.asset_host = 'a.example.com' assert_equal 'gopher://a.example.com/collaboration/hieraki/images/xml.png', image_path('xml.png') - ensure - ActionController::Base.asset_host = nil end def test_asset_host_without_protocol_should_use_request_protocol_even_if_path_present - ActionController::Base.asset_host = 'a.example.com/files/go/here' + @controller.config.asset_host = 'a.example.com/files/go/here' assert_equal 'gopher://a.example.com/files/go/here/collaboration/hieraki/images/xml.png', image_path('xml.png') - ensure - ActionController::Base.asset_host = nil end def test_assert_css_and_js_of_the_same_name_return_correct_extension -- cgit v1.2.3 From 17769696279810c6c24a10b0d47f9b712205f0ce Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Thu, 4 Mar 2010 11:58:30 -0800 Subject: Move session and session_store onto ActionDispatch and add deprecation warnings --- .../lib/action_controller/metal/compatibility.rb | 6 +++ .../action_controller/metal/session_management.rb | 5 --- actionpack/lib/action_controller/railtie.rb | 50 ++++++++++++++-------- actionpack/lib/action_dispatch/railtie.rb | 2 + 4 files changed, 41 insertions(+), 22 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/metal/compatibility.rb b/actionpack/lib/action_controller/metal/compatibility.rb index 4c2136de8a..024c58ffc4 100644 --- a/actionpack/lib/action_controller/metal/compatibility.rb +++ b/actionpack/lib/action_controller/metal/compatibility.rb @@ -158,6 +158,12 @@ module ActionController Rails.application.config.action_dispatch.ip_spoofing_check = value end + def session=(value) + ActiveSupport::Deprecation.warn "ActionController::Base.session= is deprecated. " << + "Please configure it on your application with config.action_dispatch.session=", caller + Rails.application.config.action_dispatch.session = value.delete(:disabled) ? nil : value + end + def rescue_action(env) raise env["action_dispatch.rescue.exception"] end diff --git a/actionpack/lib/action_controller/metal/session_management.rb b/actionpack/lib/action_controller/metal/session_management.rb index ce8b20964b..1ea22b7b28 100644 --- a/actionpack/lib/action_controller/metal/session_management.rb +++ b/actionpack/lib/action_controller/metal/session_management.rb @@ -27,11 +27,6 @@ module ActionController #:nodoc: SessionManagement.session_store_for(config.session_store) end - def session=(options = {}) - self.session_store = nil if options.delete(:disabled) - session_options.merge!(options) - end - def session(*args) ActiveSupport::Deprecation.warn( "Disabling sessions for a single controller has been deprecated. " + diff --git a/actionpack/lib/action_controller/railtie.rb b/actionpack/lib/action_controller/railtie.rb index 3a084cdf67..031df9423f 100644 --- a/actionpack/lib/action_controller/railtie.rb +++ b/actionpack/lib/action_controller/railtie.rb @@ -3,6 +3,7 @@ require "action_controller" require "action_view/railtie" require "active_support/core_ext/class/subclasses" require "active_support/deprecation/proxy_wrappers" +require "active_support/deprecation" module ActionController class Railtie < Rails::Railtie @@ -11,33 +12,48 @@ module ActionController require "action_controller/railties/log_subscriber" require "action_controller/railties/url_helpers" - log_subscriber ActionController::Railties::LogSubscriber.new + ad = config.action_dispatch + config.action_controller.singleton_class.send(:define_method, :session) do + ActiveSupport::Deprecation.warn "config.action_controller.session has been " \ + "renamed to config.action_dispatch.session.", caller + ad.session + end - config.action_controller.session_store = :cookie_store - config.action_controller.session_options = {} + config.action_controller.singleton_class.send(:define_method, :session=) do |val| + ActiveSupport::Deprecation.warn "config.action_controller.session has been " \ + "renamed to config.action_dispatch.session.", caller + ad.session = val + end - initializer "action_controller.logger" do - ActionController::Base.logger ||= Rails.logger + config.action_controller.singleton_class.send(:define_method, :session_store) do + ActiveSupport::Deprecation.warn "config.action_controller.session_store has been " \ + "renamed to config.action_dispatch.session_store.", caller + ad.session_store end - # assets_dir = defined?(Rails.public_path) ? Rails.public_path : "public" - # ActionView::DEFAULT_CONFIG = { - # :assets_dir => assets_dir, - # :javascripts_dir => "#{assets_dir}/javascripts", - # :stylesheets_dir => "#{assets_dir}/stylesheets", - # } + config.action_controller.singleton_class.send(:define_method, :session_store=) do |val| + ActiveSupport::Deprecation.warn "config.action_controller.session_store has been " \ + "renamed to config.action_dispatch.session_store.", caller + ad.session_store = val + end + log_subscriber ActionController::Railties::LogSubscriber.new + + initializer "action_controller.logger" do + ActionController::Base.logger ||= Rails.logger + end initializer "action_controller.set_configs" do |app| paths = app.config.paths ac = app.config.action_controller - ac.assets_dir = paths.public - ac.javascripts_dir = paths.public.javascripts - ac.stylesheets_dir = paths.public.stylesheets + ac.assets_dir = paths.public.to_a.first + ac.javascripts_dir = paths.public.javascripts.to_a.first + ac.stylesheets_dir = paths.public.stylesheets.to_a.first - app.config.action_controller.each do |k,v| - ActionController::Base.send "#{k}=", v - end + ActionController::Base.config.replace(ac) + # app.config.action_controller.each do |k,v| + # ActionController::Base.send "#{k}=", v + # end end initializer "action_controller.initialize_framework_caches" do diff --git a/actionpack/lib/action_dispatch/railtie.rb b/actionpack/lib/action_dispatch/railtie.rb index e486bd4079..30b3535e17 100644 --- a/actionpack/lib/action_dispatch/railtie.rb +++ b/actionpack/lib/action_dispatch/railtie.rb @@ -7,6 +7,8 @@ module ActionDispatch config.action_dispatch.x_sendfile_header = "X-Sendfile" config.action_dispatch.ip_spoofing_check = true + config.action_dispatch.session = {} + config.action_dispatch.session_store = :cookie_store # Prepare dispatcher callbacks and run 'prepare' callbacks initializer "action_dispatch.prepare_dispatcher" do |app| -- cgit v1.2.3 From 70916f6a9ce190cae5c545da552bb96f05ee4914 Mon Sep 17 00:00:00 2001 From: wycats Date: Thu, 4 Mar 2010 12:21:12 -0800 Subject: Fixes test ordering bug (ht: evan) --- actionpack/test/controller/view_paths_test.rb | 3 +++ 1 file changed, 3 insertions(+) (limited to 'actionpack') diff --git a/actionpack/test/controller/view_paths_test.rb b/actionpack/test/controller/view_paths_test.rb index 56821332c5..b8972b04b6 100644 --- a/actionpack/test/controller/view_paths_test.rb +++ b/actionpack/test/controller/view_paths_test.rb @@ -36,9 +36,12 @@ class ViewLoadPathsTest < ActionController::TestCase @old_behavior = ActiveSupport::Deprecation.behavior @last_message = nil ActiveSupport::Deprecation.behavior = Proc.new { |message, callback| @last_message = message } + + @paths = TestController.view_paths end def teardown + TestController.view_paths = @paths ActiveSupport::Deprecation.behavior = @old_behavior end -- cgit v1.2.3 From 7c785592ec9a9d7a73978d133dfa03b5b9b78fdc Mon Sep 17 00:00:00 2001 From: wycats Date: Thu, 4 Mar 2010 15:07:26 -0800 Subject: Safely cleans up a test to avoid relying on a particular test order --- actionpack/test/template/test_case_test.rb | 33 +++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 10 deletions(-) (limited to 'actionpack') diff --git a/actionpack/test/template/test_case_test.rb b/actionpack/test/template/test_case_test.rb index 12807baaa7..87408d8475 100644 --- a/actionpack/test/template/test_case_test.rb +++ b/actionpack/test/template/test_case_test.rb @@ -89,16 +89,23 @@ module ActionView end test "helper class that is being tested is always included in view instance" do - self.class.helper_class.module_eval do - def render_from_helper - render :partial => 'customer', :collection => @customers + # This ensure is a hidious hack to deal with these tests bleeding + # methods between eachother + begin + self.class.helper_class.module_eval do + def render_from_helper + render :partial => 'customer', :collection => @customers + end end - end - TestController.stubs(:controller_path).returns('test') + TestController.stubs(:controller_path).returns('test') - @customers = [stub(:name => 'Eloy'), stub(:name => 'Manfred')] - assert_match /Hello: EloyHello: Manfred/, render(:partial => 'test/from_helper') + @customers = [stub(:name => 'Eloy'), stub(:name => 'Manfred')] + assert_match /Hello: EloyHello: Manfred/, render(:partial => 'test/from_helper') + + ensure + self.class.helper_class.remove_method :render_from_helper + end end test "no additional helpers should shared across test cases" do @@ -147,10 +154,16 @@ module ActionView end test "is able to make methods available to the view" do - _helpers.module_eval do - def render_from_helper; from_test_case end + # This ensure is a hidious hack to deal with these tests bleeding + # methods between eachother + begin + _helpers.module_eval do + def render_from_helper; from_test_case end + end + assert_equal 'Word!', render(:partial => 'test/from_helper') + ensure + _helpers.remove_method :render_from_helper end - assert_equal 'Word!', render(:partial => 'test/from_helper') end def from_test_case; 'Word!'; end -- cgit v1.2.3 From 5e3e5ac12baf8432b4c2a324a81fc81901479ef5 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Thu, 4 Mar 2010 15:31:22 -0800 Subject: Clarify cookie jar test --- actionpack/test/controller/integration_test.rb | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) (limited to 'actionpack') diff --git a/actionpack/test/controller/integration_test.rb b/actionpack/test/controller/integration_test.rb index 5cb6aa6997..2180466ca7 100644 --- a/actionpack/test/controller/integration_test.rb +++ b/actionpack/test/controller/integration_test.rb @@ -284,18 +284,13 @@ class IntegrationProcessTest < ActionController::IntegrationTest end end - def test_cookie_monster + test 'response cookies are added to the cookie jar for the next request' do with_test_route_set do self.cookies['cookie_1'] = "sugar" self.cookies['cookie_2'] = "oatmeal" get '/cookie_monster' - assert_equal 410, status - assert_equal "Gone", status_message - assert_response 410 - assert_response :gone assert_equal "cookie_1=; path=/\ncookie_3=chocolate; path=/", headers["Set-Cookie"] assert_equal({"cookie_1"=>"", "cookie_2"=>"oatmeal", "cookie_3"=>"chocolate"}, cookies.to_hash) - assert_equal "Gone", response.body end end -- cgit v1.2.3 From 48bb3b3904806abaea7c62961559c03e689dd12f Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Thu, 4 Mar 2010 12:21:49 -0800 Subject: Move stuff from compatibility.rb to deprecated.rb --- actionpack/lib/action_controller/base.rb | 2 + .../lib/action_controller/deprecated/base.rb | 118 +++++++++++++++++++ .../lib/action_controller/metal/compatibility.rb | 131 +-------------------- actionpack/test/template/asset_tag_helper_test.rb | 1 - 4 files changed, 125 insertions(+), 127 deletions(-) create mode 100644 actionpack/lib/action_controller/deprecated/base.rb (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb index ace0276a31..78871154c3 100644 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -60,3 +60,5 @@ module ActionController end end + +require "action_controller/deprecated/base" diff --git a/actionpack/lib/action_controller/deprecated/base.rb b/actionpack/lib/action_controller/deprecated/base.rb new file mode 100644 index 0000000000..7aa2a34d37 --- /dev/null +++ b/actionpack/lib/action_controller/deprecated/base.rb @@ -0,0 +1,118 @@ +module ActionController + class Base + class << self + def deprecated_config_accessor(option, message = nil) + deprecated_config_reader(option, message) + deprecated_config_writer(option, message) + end + + def deprecated_config_reader(option, message = nil) + message ||= "Reading #{option} directly from ActionController::Base is deprecated. " \ + "Please read it from config.#{option}" + + self.class_eval <<-RUBY, __FILE__, __LINE__ + 1 + def #{option} + ActiveSupport::Deprecation.warn #{message.inspect}, caller + config.#{option} + end + RUBY + end + + def deprecated_config_writer(option, message = nil) + message ||= "Setting #{option} directly on ActionController::Base is deprecated. " \ + "Please set it on config.action_controller.#{option}" + + self.class_eval <<-RUBY, __FILE__, __LINE__ + 1 + def #{option}=(val) + ActiveSupport::Deprecation.warn #{message.inspect}, caller + config.#{option} = val + end + RUBY + end + + def consider_all_requests_local + ActiveSupport::Deprecation.warn "ActionController::Base.consider_all_requests_local is deprecated, " << + "use Rails.application.config.consider_all_requests_local instead", caller + Rails.application.config.consider_all_requests_local + end + + def consider_all_requests_local=(value) + ActiveSupport::Deprecation.warn "ActionController::Base.consider_all_requests_local= is deprecated. " << + "Please configure it on your application with config.consider_all_requests_local=", caller + Rails.application.config.consider_all_requests_local = value + end + + def allow_concurrency + ActiveSupport::Deprecation.warn "ActionController::Base.allow_concurrency is deprecated, " << + "use Rails.application.config.allow_concurrency instead", caller + Rails.application.config.allow_concurrency + end + + def allow_concurrency=(value) + ActiveSupport::Deprecation.warn "ActionController::Base.allow_concurrency= is deprecated. " << + "Please configure it on your application with config.allow_concurrency=", caller + Rails.application.config.allow_concurrency = value + end + + def ip_spoofing_check=(value) + ActiveSupport::Deprecation.warn "ActionController::Base.ip_spoofing_check= is deprecated. " << + "Please configure it on your application with config.action_dispatch.ip_spoofing_check=", caller + Rails.application.config.action_disaptch.ip_spoofing_check = value + end + + def ip_spoofing_check + ActiveSupport::Deprecation.warn "ActionController::Base.ip_spoofing_check is deprecated. " << + "Configuring ip_spoofing_check on the application configures a middleware.", caller + Rails.application.config.action_disaptch.ip_spoofing_check + end + + def trusted_proxies=(value) + ActiveSupport::Deprecation.warn "ActionController::Base.trusted_proxies= is deprecated. " << + "Please configure it on your application with config.action_dispatch.trusted_proxies=", caller + Rails.application.config.action_dispatch.ip_spoofing_check = value + end + + def trusted_proxies + ActiveSupport::Deprecation.warn "ActionController::Base.trusted_proxies is deprecated. " << + "Configuring trusted_proxies on the application configures a middleware.", caller + Rails.application.config.action_dispatch.ip_spoofing_check = value + end + + def session=(value) + ActiveSupport::Deprecation.warn "ActionController::Base.session= is deprecated. " << + "Please configure it on your application with config.action_dispatch.session=", caller + Rails.application.config.action_dispatch.session = value.delete(:disabled) ? nil : value + end + + # Controls the resource action separator + def resource_action_separator + @resource_action_separator ||= "/" + end + + def resource_action_separator=(val) + ActiveSupport::Deprecation.warn "ActionController::Base.resource_action_separator is deprecated and only " \ + "works with the deprecated router DSL." + @resource_action_separator = val + end + + def use_accept_header + ActiveSupport::Deprecation.warn "ActionController::Base.use_accept_header doesn't do anything anymore. " \ + "The accept header is always taken into account." + end + + def use_accept_header=(val) + use_accept_header + end + end + + deprecated_config_writer :session_store + deprecated_config_writer :session_options + deprecated_config_accessor :relative_url_root, "relative_url_root is ineffective. Please stop using it" + deprecated_config_accessor :assets_dir + deprecated_config_accessor :javascripts_dir + deprecated_config_accessor :stylesheets_dir + + delegate :consider_all_requests_local, :consider_all_requests_local=, + :allow_concurrency, :allow_concurrency=, :to => :"self.class" + end +end \ No newline at end of file diff --git a/actionpack/lib/action_controller/metal/compatibility.rb b/actionpack/lib/action_controller/metal/compatibility.rb index 024c58ffc4..44ace925e9 100644 --- a/actionpack/lib/action_controller/metal/compatibility.rb +++ b/actionpack/lib/action_controller/metal/compatibility.rb @@ -31,75 +31,22 @@ module ActionController @before_filter_chain_aborted @_headers @_params @_response) - # Controls the resource action separator - def self.resource_action_separator - @resource_action_separator ||= "/" - end - - def self.resource_action_separator=(val) - ActiveSupport::Deprecation.warn "ActionController::Base.resource_action_separator is deprecated and only " \ - "works with the deprecated router DSL." - @resource_action_separator = val - end - - def self.use_accept_header - ActiveSupport::Deprecation.warn "ActionController::Base.use_accept_header doesn't do anything anymore. " \ - "The accept header is always taken into account." + def rescue_action(env) + raise env["action_dispatch.rescue.exception"] end - def self.use_accept_header=(val) - use_accept_header + # Defines the storage option for cached fragments + def cache_store=(store_option) + @@cache_store = ActiveSupport::Cache.lookup_store(store_option) end self.page_cache_directory = defined?(Rails.public_path) ? Rails.public_path : "" - - # Prepends all the URL-generating helpers from AssetHelper. This makes it possible to easily move javascripts, stylesheets, - # and images to a dedicated asset server away from the main web server. Example: - # ActionController::Base.asset_host = "http://assets.example.com" - cattr_accessor :asset_host end - def self.deprecated_config_accessor(option, message = nil) - deprecated_config_reader(option, message) - deprecated_config_writer(option, message) - end - - def self.deprecated_config_reader(option, message = nil) - message ||= "Reading #{option} directly from ActionController::Base is deprecated. " \ - "Please read it from config.#{option}" - - ClassMethods.class_eval <<-RUBY, __FILE__, __LINE__ + 1 - def #{option} - ActiveSupport::Deprecation.warn #{message.inspect}, caller - config.#{option} - end - RUBY - end - - def self.deprecated_config_writer(option, message = nil) - message ||= "Setting #{option} directly on ActionController::Base is deprecated. " \ - "Please set it on config.action_controller.#{option}" - - ClassMethods.class_eval <<-RUBY, __FILE__, __LINE__ + 1 - def #{option}=(val) - ActiveSupport::Deprecation.warn #{message.inspect}, caller - config.#{option} = val - end - RUBY - end - - deprecated_config_writer :session_store - deprecated_config_writer :session_options - deprecated_config_accessor :relative_url_root, "relative_url_root is ineffective. Please stop using it" - deprecated_config_accessor :assets_dir - deprecated_config_accessor :javascripts_dir - deprecated_config_accessor :stylesheets_dir - # For old tests def initialize_template_class(*) end def assign_shortcuts(*) end - # TODO: Remove this after we flip def template @template ||= view_context end @@ -109,74 +56,6 @@ module ActionController super end - module ClassMethods - def consider_all_requests_local - ActiveSupport::Deprecation.warn "ActionController::Base.consider_all_requests_local is deprecated, " << - "use Rails.application.config.consider_all_requests_local instead", caller - Rails.application.config.consider_all_requests_local - end - - def consider_all_requests_local=(value) - ActiveSupport::Deprecation.warn "ActionController::Base.consider_all_requests_local= is deprecated. " << - "Please configure it on your application with config.consider_all_requests_local=", caller - Rails.application.config.consider_all_requests_local = value - end - - def allow_concurrency - ActiveSupport::Deprecation.warn "ActionController::Base.allow_concurrency is deprecated, " << - "use Rails.application.config.allow_concurrency instead", caller - Rails.application.config.allow_concurrency - end - - def allow_concurrency=(value) - ActiveSupport::Deprecation.warn "ActionController::Base.allow_concurrency= is deprecated. " << - "Please configure it on your application with config.allow_concurrency=", caller - Rails.application.config.allow_concurrency = value - end - - def ip_spoofing_check=(value) - ActiveSupport::Deprecation.warn "ActionController::Base.ip_spoofing_check= is deprecated. " << - "Please configure it on your application with config.action_dispatch.ip_spoofing_check=", caller - Rails.application.config.action_disaptch.ip_spoofing_check = value - end - - def ip_spoofing_check - ActiveSupport::Deprecation.warn "ActionController::Base.ip_spoofing_check is deprecated. " << - "Configuring ip_spoofing_check on the application configures a middleware.", caller - Rails.application.config.action_disaptch.ip_spoofing_check - end - - def trusted_proxies=(value) - ActiveSupport::Deprecation.warn "ActionController::Base.trusted_proxies= is deprecated. " << - "Please configure it on your application with config.action_dispatch.trusted_proxies=", caller - Rails.application.config.action_dispatch.ip_spoofing_check = value - end - - def trusted_proxies - ActiveSupport::Deprecation.warn "ActionController::Base.trusted_proxies is deprecated. " << - "Configuring trusted_proxies on the application configures a middleware.", caller - Rails.application.config.action_dispatch.ip_spoofing_check = value - end - - def session=(value) - ActiveSupport::Deprecation.warn "ActionController::Base.session= is deprecated. " << - "Please configure it on your application with config.action_dispatch.session=", caller - Rails.application.config.action_dispatch.session = value.delete(:disabled) ? nil : value - end - - def rescue_action(env) - raise env["action_dispatch.rescue.exception"] - end - - # Defines the storage option for cached fragments - def cache_store=(store_option) - @@cache_store = ActiveSupport::Cache.lookup_store(store_option) - end - end - - delegate :consider_all_requests_local, :consider_all_requests_local=, - :allow_concurrency, :allow_concurrency=, :to => :"self.class" - def render_to_body(options) if options.is_a?(Hash) && options.key?(:template) options[:template].sub!(/^\//, '') diff --git a/actionpack/test/template/asset_tag_helper_test.rb b/actionpack/test/template/asset_tag_helper_test.rb index 6089048088..50c3ab0b60 100644 --- a/actionpack/test/template/asset_tag_helper_test.rb +++ b/actionpack/test/template/asset_tag_helper_test.rb @@ -51,7 +51,6 @@ class AssetTagHelperTest < ActionView::TestCase def teardown ActionController::Base.perform_caching = false - ActionController::Base.asset_host = nil ENV.delete('RAILS_ASSET_ID') end -- cgit v1.2.3 From e311622e7b20b3fdeab6a93418c8a45c6e7137b6 Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Thu, 4 Mar 2010 15:06:25 -0800 Subject: Deprecated ActionController::Base.session_options= and ActionController::Base.session_store= in favor of a config.session_store method (which takes params) and a config.cookie_secret variable, which is used in various secret scenarios. The old AC::Base options will continue to work with deprecation warnings. --- .../lib/action_controller/deprecated/base.rb | 17 ++++++++++-- .../action_controller/metal/http_authentication.rb | 4 +-- .../action_controller/metal/session_management.rb | 30 ---------------------- actionpack/lib/action_controller/railtie.rb | 4 +-- .../middleware/session/cookie_store.rb | 12 ++++----- actionpack/lib/action_dispatch/railtie.rb | 2 -- actionpack/test/abstract_unit.rb | 3 +-- .../controller/http_digest_authentication_test.rb | 5 ++-- 8 files changed, 27 insertions(+), 50 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/deprecated/base.rb b/actionpack/lib/action_controller/deprecated/base.rb index 7aa2a34d37..34f8f4a822 100644 --- a/actionpack/lib/action_controller/deprecated/base.rb +++ b/actionpack/lib/action_controller/deprecated/base.rb @@ -78,10 +78,23 @@ module ActionController Rails.application.config.action_dispatch.ip_spoofing_check = value end + def session(*args) + ActiveSupport::Deprecation.warn( + "Disabling sessions for a single controller has been deprecated. " + + "Sessions are now lazy loaded. So if you don't access them, " + + "consider them off. You can still modify the session cookie " + + "options with request.session_options.", caller) + end + def session=(value) ActiveSupport::Deprecation.warn "ActionController::Base.session= is deprecated. " << - "Please configure it on your application with config.action_dispatch.session=", caller - Rails.application.config.action_dispatch.session = value.delete(:disabled) ? nil : value + "Please configure it on your application with config.session_store :cookie_store, :key => '....'", caller + if value.delete(:disabled) + Rails.application.config.session_store :disabled + else + store = Rails.application.config.session_store + Rails.application.config.session_store store, value + end end # Controls the resource action separator diff --git a/actionpack/lib/action_controller/metal/http_authentication.rb b/actionpack/lib/action_controller/metal/http_authentication.rb index afa7674e40..f1355a83a3 100644 --- a/actionpack/lib/action_controller/metal/http_authentication.rb +++ b/actionpack/lib/action_controller/metal/http_authentication.rb @@ -165,7 +165,7 @@ module ActionController # Authenticate with HTTP Digest, returns true or false def authenticate_with_http_digest(realm = "Application", &password_procedure) - HttpAuthentication::Digest.authenticate(config.session_options[:secret], request, realm, &password_procedure) + HttpAuthentication::Digest.authenticate(config.secret, request, realm, &password_procedure) end # Render output including the HTTP Digest authentication header @@ -238,7 +238,7 @@ module ActionController end def authentication_header(controller, realm) - secret_key = controller.config.session_options[:secret] + secret_key = controller.config.secret nonce = self.nonce(secret_key) opaque = opaque(secret_key) controller.headers["WWW-Authenticate"] = %(Digest realm="#{realm}", qop="auth", algorithm=MD5, nonce="#{nonce}", opaque="#{opaque}") diff --git a/actionpack/lib/action_controller/metal/session_management.rb b/actionpack/lib/action_controller/metal/session_management.rb index 1ea22b7b28..91d89ff9a4 100644 --- a/actionpack/lib/action_controller/metal/session_management.rb +++ b/actionpack/lib/action_controller/metal/session_management.rb @@ -2,38 +2,8 @@ module ActionController #:nodoc: module SessionManagement #:nodoc: extend ActiveSupport::Concern - included do - # This is still needed for the session secret for some reason. - self.config.session_options ||= {} - end - - def self.session_store_for(store) - case store - when :active_record_store - ActiveRecord::SessionStore - when Symbol - ActionDispatch::Session.const_get(store.to_s.camelize) - else - store - end - end - module ClassMethods - def session_options - config.session_options - end - - def session_store - SessionManagement.session_store_for(config.session_store) - end - def session(*args) - ActiveSupport::Deprecation.warn( - "Disabling sessions for a single controller has been deprecated. " + - "Sessions are now lazy loaded. So if you don't access them, " + - "consider them off. You can still modify the session cookie " + - "options with request.session_options.", caller) - end end end end diff --git a/actionpack/lib/action_controller/railtie.rb b/actionpack/lib/action_controller/railtie.rb index 031df9423f..e9edf80451 100644 --- a/actionpack/lib/action_controller/railtie.rb +++ b/actionpack/lib/action_controller/railtie.rb @@ -49,11 +49,9 @@ module ActionController ac.assets_dir = paths.public.to_a.first ac.javascripts_dir = paths.public.javascripts.to_a.first ac.stylesheets_dir = paths.public.stylesheets.to_a.first + ac.secret = app.config.cookie_secret ActionController::Base.config.replace(ac) - # app.config.action_controller.each do |k,v| - # ActionController::Base.send "#{k}=", v - # end end initializer "action_controller.initialize_framework_caches" do diff --git a/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb b/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb index 04a101dbb2..db64711052 100644 --- a/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb +++ b/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb @@ -177,9 +177,8 @@ module ActionDispatch if key.blank? raise ArgumentError, 'A key is required to write a ' + 'cookie containing the session data. Use ' + - 'config.action_controller.session = { :key => ' + - '"_myapp_session", :secret => "some secret phrase" } in ' + - 'config/application.rb' + 'config.action_controller.session_store :cookie_store, { :key => ' + + '"_myapp_session" } in config/application.rb' end end @@ -193,10 +192,9 @@ module ActionDispatch if secret.blank? raise ArgumentError, "A secret is required to generate an " + "integrity hash for cookie session data. Use " + - "config.action_controller.session = { :key => " + - "\"_myapp_session\", :secret => \"some secret phrase of at " + - "least #{SECRET_MIN_LENGTH} characters\" } " + - "in config/environment.rb" + "config.cookie_secret = \"some secret phrase of at " + + "least #{SECRET_MIN_LENGTH} characters\"" + + "in config/application.rb" end if secret.length < SECRET_MIN_LENGTH diff --git a/actionpack/lib/action_dispatch/railtie.rb b/actionpack/lib/action_dispatch/railtie.rb index 30b3535e17..e486bd4079 100644 --- a/actionpack/lib/action_dispatch/railtie.rb +++ b/actionpack/lib/action_dispatch/railtie.rb @@ -7,8 +7,6 @@ module ActionDispatch config.action_dispatch.x_sendfile_header = "X-Sendfile" config.action_dispatch.ip_spoofing_check = true - config.action_dispatch.session = {} - config.action_dispatch.session_store = :cookie_store # Prepare dispatcher callbacks and run 'prepare' callbacks initializer "action_dispatch.prepare_dispatcher" do |app| diff --git a/actionpack/test/abstract_unit.rb b/actionpack/test/abstract_unit.rb index 29270ed228..d103c4e485 100644 --- a/actionpack/test/abstract_unit.rb +++ b/actionpack/test/abstract_unit.rb @@ -170,8 +170,7 @@ end # Temporary base class class Rack::TestCase < ActionController::IntegrationTest setup do - ActionController::Base.session_options[:key] = "abc" - ActionController::Base.session_options[:secret] = ("*" * 30) + ActionController::Base.config.secret = "abc" * 30 end def self.testing(klass = nil) diff --git a/actionpack/test/controller/http_digest_authentication_test.rb b/actionpack/test/controller/http_digest_authentication_test.rb index 6f167fe627..eb2af523a2 100644 --- a/actionpack/test/controller/http_digest_authentication_test.rb +++ b/actionpack/test/controller/http_digest_authentication_test.rb @@ -41,11 +41,12 @@ class HttpDigestAuthenticationTest < ActionController::TestCase setup do # Used as secret in generating nonce to prevent tampering of timestamp @secret = "session_options_secret" - @old_secret, ActionController::Base.session_options[:secret] = ActionController::Base.session_options[:secret], @secret + @controller.config.secret = @secret + # @old_secret, ActionController::Base.config.secret[:secret] = ActionController::Base.session_options[:secret], @secret end teardown do - ActionController::Base.session_options[:secret] = @old_secret + # ActionController::Base.session_options[:secret] = @old_secret end AUTH_HEADERS.each do |header| -- cgit v1.2.3 From c8e1cc8657c19a852f3c84cdc61df538486f5adf Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Thu, 4 Mar 2010 16:35:05 -0800 Subject: remove_method is private --- actionpack/test/template/test_case_test.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'actionpack') diff --git a/actionpack/test/template/test_case_test.rb b/actionpack/test/template/test_case_test.rb index 87408d8475..195a6ea3ae 100644 --- a/actionpack/test/template/test_case_test.rb +++ b/actionpack/test/template/test_case_test.rb @@ -104,7 +104,7 @@ module ActionView assert_match /Hello: EloyHello: Manfred/, render(:partial => 'test/from_helper') ensure - self.class.helper_class.remove_method :render_from_helper + self.class.helper_class.send(:remove_method, :render_from_helper) end end @@ -162,7 +162,7 @@ module ActionView end assert_equal 'Word!', render(:partial => 'test/from_helper') ensure - _helpers.remove_method :render_from_helper + _helpers.send(:remove_method, :render_from_helper) end end -- cgit v1.2.3 From ff29606c061099f82668ab62e50660cda8645512 Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Thu, 4 Mar 2010 16:50:57 -0800 Subject: Refactor cache_store to use ActionController config --- actionpack/lib/action_controller/caching.rb | 34 ++++++++++++---------- .../lib/action_controller/metal/compatibility.rb | 5 ---- actionpack/test/controller/caching_test.rb | 21 ++++++++----- actionpack/test/controller/log_subscriber_test.rb | 3 +- 4 files changed, 33 insertions(+), 30 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/caching.rb b/actionpack/lib/action_controller/caching.rb index d784138ebe..7fae4e924d 100644 --- a/actionpack/lib/action_controller/caching.rb +++ b/actionpack/lib/action_controller/caching.rb @@ -40,15 +40,27 @@ module ActionController #:nodoc: autoload :Sweeping, 'action_controller/caching/sweeping' end - included do - @@cache_store = nil - cattr_reader :cache_store + module ConfigMethods + def cache_store + config.cache_store + end - # Defines the storage option for cached fragments - def self.cache_store=(store_option) - @@cache_store = ActiveSupport::Cache.lookup_store(store_option) + def cache_store=(store) + config.cache_store = ActiveSupport::Cache.lookup_store(store) end + private + + def cache_configured? + perform_caching && cache_store + end + end + + include ConfigMethods + + included do + extend ConfigMethods + include Pages, Actions, Fragments include Sweeping if defined?(ActiveRecord) @@ -56,11 +68,6 @@ module ActionController #:nodoc: cattr_accessor :perform_caching end - module ClassMethods - def cache_configured? - perform_caching && cache_store - end - end def caching_allowed? request.get? && response.status == 200 @@ -75,10 +82,5 @@ module ActionController #:nodoc: yield end end - - private - def cache_configured? - self.class.cache_configured? - end end end diff --git a/actionpack/lib/action_controller/metal/compatibility.rb b/actionpack/lib/action_controller/metal/compatibility.rb index 44ace925e9..317a9fd951 100644 --- a/actionpack/lib/action_controller/metal/compatibility.rb +++ b/actionpack/lib/action_controller/metal/compatibility.rb @@ -35,11 +35,6 @@ module ActionController raise env["action_dispatch.rescue.exception"] end - # Defines the storage option for cached fragments - def cache_store=(store_option) - @@cache_store = ActiveSupport::Cache.lookup_store(store_option) - end - self.page_cache_directory = defined?(Rails.public_path) ? Rails.public_path : "" end diff --git a/actionpack/test/controller/caching_test.rb b/actionpack/test/controller/caching_test.rb index e42ef85b98..11ef3cdd92 100644 --- a/actionpack/test/controller/caching_test.rb +++ b/actionpack/test/controller/caching_test.rb @@ -6,12 +6,18 @@ CACHE_DIR = 'test_cache' # Don't change '/../temp/' cavalierly or you might hose something you don't want hosed FILE_STORE_PATH = File.join(File.dirname(__FILE__), '/../temp/', CACHE_DIR) ActionController::Base.page_cache_directory = FILE_STORE_PATH -ActionController::Base.cache_store = :file_store, FILE_STORE_PATH -class PageCachingTestController < ActionController::Base +class CachingController < ActionController::Base + abstract! + + self.cache_store = :file_store, FILE_STORE_PATH +end + +class PageCachingTestController < CachingController caches_page :ok, :no_content, :if => Proc.new { |c| !c.request.format.json? } caches_page :found, :not_found + def ok head :ok end @@ -55,6 +61,7 @@ class PageCachingTest < ActionController::TestCase @response = ActionController::TestResponse.new @controller = PageCachingTestController.new + @controller.cache_store = :file_store, FILE_STORE_PATH @params = {:controller => 'posts', :action => 'index', :only_path => true, :skip_relative_url_root => true} @rewriter = ActionController::UrlRewriter.new(@request, @params) @@ -148,7 +155,7 @@ class PageCachingTest < ActionController::TestCase end end -class ActionCachingTestController < ActionController::Base +class ActionCachingTestController < CachingController rescue_from(Exception) { head 500 } if defined? ActiveRecord rescue_from(ActiveRecord::RecordNotFound) { head :not_found } @@ -522,7 +529,7 @@ class ActionCacheTest < ActionController::TestCase end end -class FragmentCachingTestController < ActionController::Base +class FragmentCachingTestController < CachingController def some_action; end; end @@ -531,8 +538,8 @@ class FragmentCachingTest < ActionController::TestCase super ActionController::Base.perform_caching = true @store = ActiveSupport::Cache::MemoryStore.new - ActionController::Base.cache_store = @store @controller = FragmentCachingTestController.new + @controller.cache_store = @store @params = {:controller => 'posts', :action => 'index'} @request = ActionController::TestRequest.new @response = ActionController::TestResponse.new @@ -630,7 +637,7 @@ class FragmentCachingTest < ActionController::TestCase end -class FunctionalCachingController < ActionController::Base +class FunctionalCachingController < CachingController def fragment_cached end @@ -664,8 +671,8 @@ class FunctionalFragmentCachingTest < ActionController::TestCase super ActionController::Base.perform_caching = true @store = ActiveSupport::Cache::MemoryStore.new - ActionController::Base.cache_store = @store @controller = FunctionalCachingController.new + @controller.cache_store = @store @request = ActionController::TestRequest.new @response = ActionController::TestResponse.new end diff --git a/actionpack/test/controller/log_subscriber_test.rb b/actionpack/test/controller/log_subscriber_test.rb index 1f8134822c..20d3e77b6e 100644 --- a/actionpack/test/controller/log_subscriber_test.rb +++ b/actionpack/test/controller/log_subscriber_test.rb @@ -46,8 +46,7 @@ class ACLogSubscriberTest < ActionController::TestCase @cache_path = File.expand_path('../temp/test_cache', File.dirname(__FILE__)) ActionController::Base.page_cache_directory = @cache_path - ActionController::Base.cache_store = :file_store, @cache_path - + @controller.cache_store = :file_store, @cache_path Rails::LogSubscriber.add(:action_controller, ActionController::Railties::LogSubscriber.new) end -- cgit v1.2.3 From 3438373f038cefda664b879f49eec8aec6a15a76 Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Thu, 4 Mar 2010 16:59:54 -0800 Subject: Use AS::Concern for caching modules --- actionpack/lib/action_controller/caching.rb | 5 ++- actionpack/lib/action_controller/caching/pages.rb | 42 +++++++++++----------- .../lib/action_controller/caching/sweeping.rb | 4 +-- 3 files changed, 24 insertions(+), 27 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/caching.rb b/actionpack/lib/action_controller/caching.rb index 7fae4e924d..b3fa129929 100644 --- a/actionpack/lib/action_controller/caching.rb +++ b/actionpack/lib/action_controller/caching.rb @@ -57,13 +57,12 @@ module ActionController #:nodoc: end include ConfigMethods + include Pages, Actions, Fragments + include Sweeping if defined?(ActiveRecord) included do extend ConfigMethods - include Pages, Actions, Fragments - include Sweeping if defined?(ActiveRecord) - @@perform_caching = true cattr_accessor :perform_caching end diff --git a/actionpack/lib/action_controller/caching/pages.rb b/actionpack/lib/action_controller/caching/pages.rb index 5797eeebd6..36a97d390c 100644 --- a/actionpack/lib/action_controller/caching/pages.rb +++ b/actionpack/lib/action_controller/caching/pages.rb @@ -1,5 +1,6 @@ require 'fileutils' require 'uri' +require 'active_support/core_ext/class/attribute_accessors' module ActionController #:nodoc: module Caching @@ -34,27 +35,26 @@ module ActionController #:nodoc: # Additionally, you can expire caches using Sweepers that act on changes in the model to determine when a cache is supposed to be # expired. module Pages - def self.included(base) #:nodoc: - base.extend(ClassMethods) - base.class_eval do - @@page_cache_directory = defined?(Rails.public_path) ? Rails.public_path : "" - ## - # :singleton-method: - # The cache directory should be the document root for the web server and is set using Base.page_cache_directory = "/document/root". - # For Rails, this directory has already been set to Rails.public_path (which is usually set to RAILS_ROOT + "/public"). Changing - # this setting can be useful to avoid naming conflicts with files in public/, but doing so will likely require configuring your - # web server to look in the new location for cached files. - cattr_accessor :page_cache_directory - - @@page_cache_extension = '.html' - ## - # :singleton-method: - # Most Rails requests do not have an extension, such as /weblog/new. In these cases, the page caching mechanism will add one in - # order to make it easy for the cached files to be picked up properly by the web server. By default, this cache extension is .html. - # If you want something else, like .php or .shtml, just set Base.page_cache_extension. In cases where a request already has an - # extension, such as .xml or .rss, page caching will not add an extension. This allows it to work well with RESTful apps. - cattr_accessor :page_cache_extension - end + extend ActiveSupport::Concern + + included do + @@page_cache_directory = defined?(Rails.public_path) ? Rails.public_path : "" + ## + # :singleton-method: + # The cache directory should be the document root for the web server and is set using Base.page_cache_directory = "/document/root". + # For Rails, this directory has already been set to Rails.public_path (which is usually set to RAILS_ROOT + "/public"). Changing + # this setting can be useful to avoid naming conflicts with files in public/, but doing so will likely require configuring your + # web server to look in the new location for cached files. + cattr_accessor :page_cache_directory + + @@page_cache_extension = '.html' + ## + # :singleton-method: + # Most Rails requests do not have an extension, such as /weblog/new. In these cases, the page caching mechanism will add one in + # order to make it easy for the cached files to be picked up properly by the web server. By default, this cache extension is .html. + # If you want something else, like .php or .shtml, just set Base.page_cache_extension. In cases where a request already has an + # extension, such as .xml or .rss, page caching will not add an extension. This allows it to work well with RESTful apps. + cattr_accessor :page_cache_extension end module ClassMethods diff --git a/actionpack/lib/action_controller/caching/sweeping.rb b/actionpack/lib/action_controller/caching/sweeping.rb index 871f41bfdd..cf16417e84 100644 --- a/actionpack/lib/action_controller/caching/sweeping.rb +++ b/actionpack/lib/action_controller/caching/sweeping.rb @@ -30,9 +30,7 @@ module ActionController #:nodoc: # cache_sweeper OpenBar::Sweeper, :only => [ :edit, :destroy, :share ] # end module Sweeping - def self.included(base) #:nodoc: - base.extend(ClassMethods) - end + extend ActiveSupport::Concern module ClassMethods #:nodoc: def cache_sweeper(*sweepers) -- cgit v1.2.3 From 900a2d304a83bad7a3958464b8dfa6fb49670686 Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Thu, 4 Mar 2010 17:43:46 -0800 Subject: Get rid of relative_url_path in favor of respecting SCRIPT_NAME. Also added a way to specify a default SCRIPT_NAME when generating URLs out of the context of a request. --- actionpack/lib/action_controller/metal/url_for.rb | 2 +- actionpack/lib/action_controller/railtie.rb | 6 ++++++ actionpack/lib/action_controller/url_rewriter.rb | 2 +- actionpack/lib/action_dispatch/routing/route_set.rb | 5 ++++- actionpack/lib/action_dispatch/routing/url_for.rb | 6 +++++- actionpack/test/controller/url_for_test.rb | 4 ++-- 6 files changed, 19 insertions(+), 6 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/metal/url_for.rb b/actionpack/lib/action_controller/metal/url_for.rb index c890dc51d4..89ab0b4753 100644 --- a/actionpack/lib/action_controller/metal/url_for.rb +++ b/actionpack/lib/action_controller/metal/url_for.rb @@ -12,7 +12,7 @@ module ActionController # ROUTES TODO: relative_url_root should be middleware # and the generator should take SCRIPT_NAME into # consideration - :relative_url_root => config.relative_url_root, + :script_name => request.env["SCRIPT_NAME"], :_path_segments => request.symbolized_path_parameters ) end diff --git a/actionpack/lib/action_controller/railtie.rb b/actionpack/lib/action_controller/railtie.rb index e9edf80451..e638be5251 100644 --- a/actionpack/lib/action_controller/railtie.rb +++ b/actionpack/lib/action_controller/railtie.rb @@ -51,6 +51,12 @@ module ActionController ac.stylesheets_dir = paths.public.stylesheets.to_a.first ac.secret = app.config.cookie_secret + if ac.relative_url_root + ActiveSupport::Deprecation.warn "config.action_controller.relative_url_root " \ + "is no longer effective. Please set it in the router as " \ + "routes.draw(:script_name => #{ac.relative_url_root.inspect})" + end + ActionController::Base.config.replace(ac) end diff --git a/actionpack/lib/action_controller/url_rewriter.rb b/actionpack/lib/action_controller/url_rewriter.rb index 973a6facd7..8821892b3a 100644 --- a/actionpack/lib/action_controller/url_rewriter.rb +++ b/actionpack/lib/action_controller/url_rewriter.rb @@ -32,7 +32,7 @@ module ActionController # ROUTES TODO: Fix the tests segments = options.delete(:_path_segments) - relative_url_root = options.delete(:relative_url_root).to_s + relative_url_root = options.delete(:script_name).to_s path_segments = path_segments ? path_segments.merge(segments || {}) : segments unless options[:only_path] diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 99436e3cb0..9ca1857966 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -211,6 +211,7 @@ module ActionDispatch attr_accessor :routes, :named_routes attr_accessor :disable_clear_and_finalize, :resources_path_names + attr_accessor :script_name def self.default_resources_path_names { :new => 'new', :edit => 'edit' } @@ -225,9 +226,11 @@ module ActionDispatch @disable_clear_and_finalize = false end - def draw(&block) + def draw(options = {}, &block) clear! unless @disable_clear_and_finalize + @script_name = options[:script_name] + mapper = Mapper.new(self) if block.arity == 1 mapper.instance_exec(DeprecatedMapper.new(self), &block) diff --git a/actionpack/lib/action_dispatch/routing/url_for.rb b/actionpack/lib/action_dispatch/routing/url_for.rb index 7f2c9a5c12..afbb2ecf16 100644 --- a/actionpack/lib/action_dispatch/routing/url_for.rb +++ b/actionpack/lib/action_dispatch/routing/url_for.rb @@ -101,7 +101,11 @@ module ActionDispatch # end def url_options - self.class.default_url_options.merge(@url_options || {}) + @url_options ||= begin + opts = self.class.default_url_options + opts.merge(:script_name => _router.script_name) if respond_to?(:_router) + opts + end end def url_options=(options) diff --git a/actionpack/test/controller/url_for_test.rb b/actionpack/test/controller/url_for_test.rb index 07809aa480..fc7773dffe 100644 --- a/actionpack/test/controller/url_for_test.rb +++ b/actionpack/test/controller/url_for_test.rb @@ -118,7 +118,7 @@ module AbstractController add_host! assert_equal('https://www.basecamphq.com/subdir/c/a/i', - W.new.url_for(:controller => 'c', :action => 'a', :id => 'i', :protocol => 'https', :relative_url_root => '/subdir') + W.new.url_for(:controller => 'c', :action => 'a', :id => 'i', :protocol => 'https', :script_name => '/subdir') ) end @@ -153,7 +153,7 @@ module AbstractController controller = kls.new assert_equal 'http://www.basecamphq.com/subdir/home/sweet/home/again', - controller.send(:home_url, :host => 'www.basecamphq.com', :user => 'again', :relative_url_root => "/subdir") + controller.send(:home_url, :host => 'www.basecamphq.com', :user => 'again', :script_name => "/subdir") end end -- cgit v1.2.3 From deb00bcb8cf88eb6420282c9af0af64fb69aeed4 Mon Sep 17 00:00:00 2001 From: Bryan Helmkamp Date: Thu, 4 Mar 2010 22:41:39 -0500 Subject: Read Rails version from a file instead of modifying the load path and doing requires Signed-off-by: Jeremy Kemper --- actionpack/actionpack.gemspec | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) (limited to 'actionpack') diff --git a/actionpack/actionpack.gemspec b/actionpack/actionpack.gemspec index a281df8642..a50c55ed9a 100644 --- a/actionpack/actionpack.gemspec +++ b/actionpack/actionpack.gemspec @@ -1,10 +1,9 @@ -$:.unshift "lib" -require "action_pack/version" +version = File.read("../RAILS_VERSION").strip Gem::Specification.new do |s| s.platform = Gem::Platform::RUBY s.name = 'actionpack' - s.version = ActionPack::VERSION::STRING + s.version = version s.summary = 'Web-flow and rendering framework putting the VC in MVC (part of Rails).' s.description = 'Web apps on Rails. Simple, battle-tested conventions for building and testing MVC web applications. Works with any Rack-compatible server.' s.required_ruby_version = '>= 1.8.7' @@ -20,8 +19,8 @@ Gem::Specification.new do |s| s.has_rdoc = true - s.add_dependency('activesupport', "= #{ActionPack::VERSION::STRING}") - s.add_dependency('activemodel', "= #{ActionPack::VERSION::STRING}") + s.add_dependency('activesupport', version) + s.add_dependency('activemodel', version) s.add_dependency('rack', '~> 1.1.0') s.add_dependency('rack-test', '~> 0.5.0') s.add_dependency('rack-mount', '~> 0.5.1') -- cgit v1.2.3 From 48672cd1997618f21f50e1204e60dc681e647ddb Mon Sep 17 00:00:00 2001 From: Carl Lerche Date: Thu, 4 Mar 2010 19:01:48 -0800 Subject: Have ActionDispatch::Routing::RouteSet.new ready to receive routes as is. --- actionpack/lib/action_dispatch/routing/route_set.rb | 1 + 1 file changed, 1 insertion(+) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 9ca1857966..26189329c2 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -224,6 +224,7 @@ module ActionDispatch self.controller_namespaces = Set.new @disable_clear_and_finalize = false + clear! end def draw(options = {}, &block) -- cgit v1.2.3 From 9a17416d8bda0df0a6961e547c3cf1d677e66b5e Mon Sep 17 00:00:00 2001 From: Carl Lerche Date: Thu, 4 Mar 2010 21:59:42 -0800 Subject: Tweak out url_for uses :script_name and add some tests --- actionpack/lib/action_controller/metal/url_for.rb | 6 +-- actionpack/lib/action_controller/railtie.rb | 6 --- actionpack/lib/action_controller/url_rewriter.rb | 4 +- .../lib/action_dispatch/routing/route_set.rb | 12 ++--- actionpack/lib/action_dispatch/routing/url_for.rb | 9 ++-- actionpack/test/dispatch/url_generation_test.rb | 58 ++++++++++++++++++++++ 6 files changed, 71 insertions(+), 24 deletions(-) create mode 100644 actionpack/test/dispatch/url_generation_test.rb (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/metal/url_for.rb b/actionpack/lib/action_controller/metal/url_for.rb index 89ab0b4753..f6b6cb2ff4 100644 --- a/actionpack/lib/action_controller/metal/url_for.rb +++ b/actionpack/lib/action_controller/metal/url_for.rb @@ -9,12 +9,8 @@ module ActionController super.reverse_merge( :host => request.host_with_port, :protocol => request.protocol, - # ROUTES TODO: relative_url_root should be middleware - # and the generator should take SCRIPT_NAME into - # consideration - :script_name => request.env["SCRIPT_NAME"], :_path_segments => request.symbolized_path_parameters - ) + ).merge(:script_name => request.script_name) end def _router diff --git a/actionpack/lib/action_controller/railtie.rb b/actionpack/lib/action_controller/railtie.rb index e638be5251..e9edf80451 100644 --- a/actionpack/lib/action_controller/railtie.rb +++ b/actionpack/lib/action_controller/railtie.rb @@ -51,12 +51,6 @@ module ActionController ac.stylesheets_dir = paths.public.stylesheets.to_a.first ac.secret = app.config.cookie_secret - if ac.relative_url_root - ActiveSupport::Deprecation.warn "config.action_controller.relative_url_root " \ - "is no longer effective. Please set it in the router as " \ - "routes.draw(:script_name => #{ac.relative_url_root.inspect})" - end - ActionController::Base.config.replace(ac) end diff --git a/actionpack/lib/action_controller/url_rewriter.rb b/actionpack/lib/action_controller/url_rewriter.rb index 8821892b3a..981865517f 100644 --- a/actionpack/lib/action_controller/url_rewriter.rb +++ b/actionpack/lib/action_controller/url_rewriter.rb @@ -32,7 +32,6 @@ module ActionController # ROUTES TODO: Fix the tests segments = options.delete(:_path_segments) - relative_url_root = options.delete(:script_name).to_s path_segments = path_segments ? path_segments.merge(segments || {}) : segments unless options[:only_path] @@ -50,8 +49,7 @@ module ActionController path_options = yield(path_options) if block_given? path = router.generate(path_options, path_segments || {}) - # ROUTES TODO: This can be called directly, so relative_url_root should probably be set in the router - rewritten_url << relative_url_root + # ROUTES TODO: This can be called directly, so script_name should probably be set in the router rewritten_url << (options[:trailing_slash] ? path.sub(/\?|\z/) { "/" + $& } : path) rewritten_url << "##{Rack::Utils.escape(options[:anchor].to_param.to_s)}" if options[:anchor] diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 26189329c2..a53d8067dd 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -209,29 +209,27 @@ module ActionDispatch end end - attr_accessor :routes, :named_routes + attr_accessor :routes, :named_routes, :mount_point attr_accessor :disable_clear_and_finalize, :resources_path_names - attr_accessor :script_name def self.default_resources_path_names { :new => 'new', :edit => 'edit' } end - def initialize + def initialize(options = {}) self.routes = [] self.named_routes = NamedRouteCollection.new self.resources_path_names = self.class.default_resources_path_names.dup self.controller_namespaces = Set.new + self.mount_point = options[:mount_point] @disable_clear_and_finalize = false clear! end - def draw(options = {}, &block) + def draw(&block) clear! unless @disable_clear_and_finalize - @script_name = options[:script_name] - mapper = Mapper.new(self) if block.arity == 1 mapper.instance_exec(DeprecatedMapper.new(self), &block) @@ -341,6 +339,7 @@ module ActionDispatch def generate(options, recall = {}, method = :generate) options, recall = options.dup, recall.dup + script_name = options.delete(:script_name) || mount_point named_route = options.delete(:use_route) options = options_as_params(options) @@ -406,6 +405,7 @@ module ActionDispatch [path, params.keys] elsif path path << "?#{params.to_query}" if params.any? + path = "#{script_name}#{path}" path else raise ActionController::RoutingError, "No route matches #{options.inspect}" diff --git a/actionpack/lib/action_dispatch/routing/url_for.rb b/actionpack/lib/action_dispatch/routing/url_for.rb index afbb2ecf16..be5edcc120 100644 --- a/actionpack/lib/action_dispatch/routing/url_for.rb +++ b/actionpack/lib/action_dispatch/routing/url_for.rb @@ -102,14 +102,15 @@ module ActionDispatch def url_options @url_options ||= begin - opts = self.class.default_url_options - opts.merge(:script_name => _router.script_name) if respond_to?(:_router) - opts + # self.class does not respond to default_url_options when the helpers are extended + # onto a singleton + self.class.respond_to?(:default_url_options) ? self.class.default_url_options : {} end end def url_options=(options) - @url_options = options + defaults = self.class.respond_to?(:default_url_options) ? self.class.default_url_options : {} + @url_options = defaults.merge(options) end # def merge_options(options) #:nodoc: diff --git a/actionpack/test/dispatch/url_generation_test.rb b/actionpack/test/dispatch/url_generation_test.rb new file mode 100644 index 0000000000..b55e001fa7 --- /dev/null +++ b/actionpack/test/dispatch/url_generation_test.rb @@ -0,0 +1,58 @@ +require 'abstract_unit' + +module TestUrlGeneration + class WithoutMountpoint < ActiveSupport::TestCase + setup do + app = lambda { |env| [200, {}, "Hello"] } + @router = ActionDispatch::Routing::RouteSet.new + @router.draw do + match "/foo", :to => app, :as => :foo + end + + singleton_class.send(:include, @router.url_helpers) + end + + test "generating URLS normally" do + assert_equal "/foo", foo_path + end + + test "accepting a :script_name option" do + assert_equal "/bar/foo", foo_path(:script_name => "/bar") + end + end + + class WithMountPoint < ActionDispatch::IntegrationTest + Router = ActionDispatch::Routing::RouteSet.new(:mount_point => "/baz") + Router.draw { match "/foo", :to => "my_route_generating#index", :as => :foo } + + class ::MyRouteGeneratingController < ActionController::Base + include Router.url_helpers + def index + render :text => foo_path + end + end + + include Router.url_helpers + + def _router + Router + end + + def app + Router + end + + test "using the default :script_name option" do + assert_equal "/baz/foo", foo_path + end + + test "overriding the default :script_name option" do + assert_equal "/bar/foo", foo_path(:script_name => "/bar") + end + + test "the request's SCRIPT_NAME takes precedence over the router's" do + get "/foo", {}, 'SCRIPT_NAME' => "/new" + assert_equal "/new/foo", response.body + end + end +end \ No newline at end of file -- cgit v1.2.3 From 57cf1c578a5a3823ae280cf786c1d2ec71001ba8 Mon Sep 17 00:00:00 2001 From: Carl Lerche Date: Thu, 4 Mar 2010 22:17:25 -0800 Subject: Remove the ability to set the mountpoint when initializing a route set. --- .../lib/action_dispatch/routing/route_set.rb | 7 +++--- actionpack/test/dispatch/url_generation_test.rb | 28 ++++------------------ 2 files changed, 7 insertions(+), 28 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index a53d8067dd..5c246d8781 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -209,19 +209,18 @@ module ActionDispatch end end - attr_accessor :routes, :named_routes, :mount_point + attr_accessor :routes, :named_routes attr_accessor :disable_clear_and_finalize, :resources_path_names def self.default_resources_path_names { :new => 'new', :edit => 'edit' } end - def initialize(options = {}) + def initialize self.routes = [] self.named_routes = NamedRouteCollection.new self.resources_path_names = self.class.default_resources_path_names.dup self.controller_namespaces = Set.new - self.mount_point = options[:mount_point] @disable_clear_and_finalize = false clear! @@ -339,7 +338,7 @@ module ActionDispatch def generate(options, recall = {}, method = :generate) options, recall = options.dup, recall.dup - script_name = options.delete(:script_name) || mount_point + script_name = options.delete(:script_name) named_route = options.delete(:use_route) options = options_as_params(options) diff --git a/actionpack/test/dispatch/url_generation_test.rb b/actionpack/test/dispatch/url_generation_test.rb index b55e001fa7..18b5b7ee00 100644 --- a/actionpack/test/dispatch/url_generation_test.rb +++ b/actionpack/test/dispatch/url_generation_test.rb @@ -1,28 +1,8 @@ require 'abstract_unit' module TestUrlGeneration - class WithoutMountpoint < ActiveSupport::TestCase - setup do - app = lambda { |env| [200, {}, "Hello"] } - @router = ActionDispatch::Routing::RouteSet.new - @router.draw do - match "/foo", :to => app, :as => :foo - end - - singleton_class.send(:include, @router.url_helpers) - end - - test "generating URLS normally" do - assert_equal "/foo", foo_path - end - - test "accepting a :script_name option" do - assert_equal "/bar/foo", foo_path(:script_name => "/bar") - end - end - class WithMountPoint < ActionDispatch::IntegrationTest - Router = ActionDispatch::Routing::RouteSet.new(:mount_point => "/baz") + Router = ActionDispatch::Routing::RouteSet.new Router.draw { match "/foo", :to => "my_route_generating#index", :as => :foo } class ::MyRouteGeneratingController < ActionController::Base @@ -42,11 +22,11 @@ module TestUrlGeneration Router end - test "using the default :script_name option" do - assert_equal "/baz/foo", foo_path + test "generating URLS normally" do + assert_equal "/foo", foo_path end - test "overriding the default :script_name option" do + test "accepting a :script_name option" do assert_equal "/bar/foo", foo_path(:script_name => "/bar") end -- cgit v1.2.3 From 80715cee73856d0ccade7b912b1e6a0aa5ca135b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Fri, 5 Mar 2010 15:40:06 +0100 Subject: Define to_s method in ActionView::Resolver, so I'm not required to write it in inherited classes. --- actionpack/lib/action_view/template/resolver.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/template/resolver.rb b/actionpack/lib/action_view/template/resolver.rb index 20402f9d6d..962fa0e260 100644 --- a/actionpack/lib/action_view/template/resolver.rb +++ b/actionpack/lib/action_view/template/resolver.rb @@ -29,11 +29,11 @@ module ActionView @cached = {} end - # Normalizes the arguments and passes it on to find_template def find(*args) find_all(*args).first end + # Normalizes the arguments and passes it on to find_template def find_all(name, details = {}, prefix = nil, partial = nil) details = normalize_details(details) name, prefix = normalize_name(name, prefix) @@ -43,6 +43,10 @@ module ActionView end end + def to_s + self.class.name + end + private # This is what child classes implement. No defaults are needed -- cgit v1.2.3 From 7d4d97e22ad3cb1ff280265cbbc880feff47e694 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Fri, 5 Mar 2010 15:49:36 +0100 Subject: Actually, revert previous commit. Having a lot of information is better than having no information at all. --- actionpack/lib/action_view/template/resolver.rb | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/template/resolver.rb b/actionpack/lib/action_view/template/resolver.rb index 962fa0e260..8c81914aac 100644 --- a/actionpack/lib/action_view/template/resolver.rb +++ b/actionpack/lib/action_view/template/resolver.rb @@ -18,11 +18,9 @@ module ActionView end end - register_detail(:locale) { [I18n.locale] } - register_detail(:formats) { Mime::SET.symbols } - register_detail(:handlers) do - Template::Handlers.extensions - end + register_detail(:locale) { [I18n.locale] } + register_detail(:formats) { Mime::SET.symbols } + register_detail(:handlers) { Template::Handlers.extensions } def initialize(options = {}) @cache = options[:cache] @@ -43,10 +41,6 @@ module ActionView end end - def to_s - self.class.name - end - private # This is what child classes implement. No defaults are needed -- cgit v1.2.3 From 8da026cb797519deac807721096fab5182ca61af Mon Sep 17 00:00:00 2001 From: Xavier Shay Date: Wed, 17 Feb 2010 15:07:01 +1100 Subject: Remove some of the blank rescues from number helper. This makes the code easier to understand, as you're not left wondering what the rescue is actually doing. This does not change documented/tested behaviour. Signed-off-by: wycats --- .../lib/action_view/helpers/number_helper.rb | 86 +++++++++++----------- 1 file changed, 42 insertions(+), 44 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/number_helper.rb b/actionpack/lib/action_view/helpers/number_helper.rb index 3d3502a08b..46e41bc406 100644 --- a/actionpack/lib/action_view/helpers/number_helper.rb +++ b/actionpack/lib/action_view/helpers/number_helper.rb @@ -28,27 +28,25 @@ module ActionView # number_to_phone(1235551234, :country_code => 1, :extension => 1343, :delimiter => ".") # => +1.123.555.1234 x 1343 def number_to_phone(number, options = {}) - number = number.to_s.strip unless number.nil? + return nil if number.nil? + + number = number.to_s.strip options = options.symbolize_keys area_code = options[:area_code] || nil delimiter = options[:delimiter] || "-" extension = options[:extension].to_s.strip || nil country_code = options[:country_code] || nil - begin - str = "" - str << "+#{country_code}#{delimiter}" unless country_code.blank? - str << if area_code - number.gsub!(/([0-9]{1,3})([0-9]{3})([0-9]{4}$)/,"(\\1) \\2#{delimiter}\\3") - else - number.gsub!(/([0-9]{0,3})([0-9]{3})([0-9]{4})$/,"\\1#{delimiter}\\2#{delimiter}\\3") - number.starts_with?('-') ? number.slice!(1..-1) : number - end - str << " x #{extension}" unless extension.blank? - str - rescue - number + str = "" + str << "+#{country_code}#{delimiter}" unless country_code.blank? + str << if area_code + number.gsub!(/([0-9]{1,3})([0-9]{3})([0-9]{4}$)/,"(\\1) \\2#{delimiter}\\3") + else + number.gsub!(/([0-9]{0,3})([0-9]{3})([0-9]{4})$/,"\\1#{delimiter}\\2#{delimiter}\\3") + number.starts_with?('-') ? number.slice!(1..-1) : number end + str << " x #{extension}" unless extension.blank? + str end # Formats a +number+ into a currency string (e.g., $13.65). You can customize the format @@ -87,13 +85,14 @@ module ActionView format = options[:format] || defaults[:format] separator = '' if precision == 0 - begin - format.gsub(/%n/, number_with_precision(number, - :precision => precision, - :delimiter => delimiter, - :separator => separator) - ).gsub(/%u/, unit).html_safe - rescue + value = number_with_precision(number, + :precision => precision, + :delimiter => delimiter, + :separator => separator) + + if value + format.gsub(/%n/, value).gsub(/%u/, unit).html_safe + else number end end @@ -122,14 +121,11 @@ module ActionView separator = options[:separator] || defaults[:separator] delimiter = options[:delimiter] || defaults[:delimiter] - begin - number_with_precision(number, - :precision => precision, - :separator => separator, - :delimiter => delimiter) + "%" - rescue - number - end + value = number_with_precision(number, + :precision => precision, + :separator => separator, + :delimiter => delimiter) + value ? value + "%" : number end # Formats a +number+ with grouped thousands using +delimiter+ (e.g., 12,324). You can @@ -168,11 +164,11 @@ module ActionView delimiter ||= (options[:delimiter] || defaults[:delimiter]) separator ||= (options[:separator] || defaults[:separator]) - begin - parts = number.to_s.split('.') + parts = number.to_s.split('.') + if parts[0] parts[0].gsub!(/(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{delimiter}") parts.join(separator) - rescue + else number end end @@ -216,11 +212,17 @@ module ActionView delimiter ||= (options[:delimiter] || defaults[:delimiter]) begin + value = Float(number) + rescue ArgumentError, TypeError + value = nil + end + + if value rounded_number = BigDecimal.new((Float(number) * (10 ** precision)).to_s).round.to_f / 10 ** precision number_with_delimiter("%01.#{precision}f" % rounded_number, :separator => separator, :delimiter => delimiter) - rescue + else number end end @@ -293,17 +295,13 @@ module ActionView unit_key = STORAGE_UNITS[exponent] unit = I18n.translate(:"number.human.storage_units.units.#{unit_key}", :locale => options[:locale], :count => number, :raise => true) - begin - escaped_separator = Regexp.escape(separator) - formatted_number = number_with_precision(number, - :precision => precision, - :separator => separator, - :delimiter => delimiter - ).sub(/(#{escaped_separator})(\d*[1-9])?0+\z/, '\1\2').sub(/#{escaped_separator}\z/, '') - storage_units_format.gsub(/%n/, formatted_number).gsub(/%u/, unit) - rescue - number - end + escaped_separator = Regexp.escape(separator) + formatted_number = number_with_precision(number, + :precision => precision, + :separator => separator, + :delimiter => delimiter + ).sub(/(#{escaped_separator})(\d*[1-9])?0+\z/, '\1\2').sub(/#{escaped_separator}\z/, '') + storage_units_format.gsub(/%n/, formatted_number).gsub(/%u/, unit) end end end -- cgit v1.2.3 From a04b44910e57387bd1bcfbd95c3a6754a08e77af Mon Sep 17 00:00:00 2001 From: Jose Fernandez Date: Tue, 23 Feb 2010 18:50:05 +0100 Subject: Solved a problem that prevented render :file => work in layouts Signed-off-by: wycats --- actionpack/lib/action_view/render/rendering.rb | 2 +- actionpack/test/fixtures/test/layout_render_file.erb | 2 ++ actionpack/test/template/render_test.rb | 5 +++++ 3 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 actionpack/test/fixtures/test/layout_render_file.erb (limited to 'actionpack') diff --git a/actionpack/lib/action_view/render/rendering.rb b/actionpack/lib/action_view/render/rendering.rb index 64cc0caf11..28b79bfcb7 100644 --- a/actionpack/lib/action_view/render/rendering.rb +++ b/actionpack/lib/action_view/render/rendering.rb @@ -102,7 +102,7 @@ module ActionView ActiveSupport::Notifications.instrument("action_view.render_template", :identifier => template.identifier, :layout => layout.try(:identifier)) do - content = template.render(self, locals) + content = template.render(self, locals) {|*name| _layout_for(*name) } @_content_for[:layout] = content if layout diff --git a/actionpack/test/fixtures/test/layout_render_file.erb b/actionpack/test/fixtures/test/layout_render_file.erb new file mode 100644 index 0000000000..2f8e921c5f --- /dev/null +++ b/actionpack/test/fixtures/test/layout_render_file.erb @@ -0,0 +1,2 @@ +<% content_for :title do %>title<% end -%> +<%= render :file => 'layouts/yield' -%> \ No newline at end of file diff --git a/actionpack/test/template/render_test.rb b/actionpack/test/template/render_test.rb index 338ada8b0e..6dbadc9304 100644 --- a/actionpack/test/template/render_test.rb +++ b/actionpack/test/template/render_test.rb @@ -233,6 +233,11 @@ module RenderTestCases @view.render(:file => "test/nested_layout.erb", :layout => "layouts/yield") end + def test_render_with_file_in_layout + assert_equal %(\ntitle\n\n), + @view.render(:file => "test/layout_render_file.erb") + end + if '1.9'.respond_to?(:force_encoding) def test_render_utf8_template_with_magic_comment with_external_encoding Encoding::ASCII_8BIT do -- cgit v1.2.3 From a82cf0a9327d85f5787427e1d06d0ae374b11103 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Fri, 5 Mar 2010 12:15:45 -0800 Subject: Tweak default_url_options deprecation warning --- actionpack/lib/action_dispatch/routing/url_for.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/routing/url_for.rb b/actionpack/lib/action_dispatch/routing/url_for.rb index be5edcc120..0ab20dcb39 100644 --- a/actionpack/lib/action_dispatch/routing/url_for.rb +++ b/actionpack/lib/action_dispatch/routing/url_for.rb @@ -152,7 +152,7 @@ module ActionDispatch when Hash # Handle the deprecated instance level default_url_options if respond_to?(:default_url_options, true) - ActiveSupport::Deprecation.warn "Overwriting #default_url_options is deprecated. Please set url options with self.url_options = { ... }" + ActiveSupport::Deprecation.warn "Overriding the #default_url_options method is deprecated. Instead, set self.url_options = { ... } in a before_filter." if defaults = default_url_options(options) options = defaults.merge(options) end @@ -165,4 +165,4 @@ module ActionDispatch end end end -end \ No newline at end of file +end -- cgit v1.2.3 From e472f76e4c86cfc1350f3b769d9ac3d96f062e3f Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Fri, 5 Mar 2010 19:40:41 -0200 Subject: =?UTF-8?q?Adds=20disable=20option=20to=20date=5Fhelpers=20generat?= =?UTF-8?q?ed=20hidden=20fields=20when=20html=5Foptions=20specifies=20it.?= =?UTF-8?q?=20ht=20by=20Marc=20Sch=C3=BCtz?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit [#3807 state:committed] Signed-off-by: Jeremy Kemper --- actionpack/lib/action_view/helpers/date_helper.rb | 3 +- actionpack/test/template/date_helper_test.rb | 55 +++++++++++++++++++++++ 2 files changed, 57 insertions(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/date_helper.rb b/actionpack/lib/action_view/helpers/date_helper.rb index 89ac682c18..42018ee261 100644 --- a/actionpack/lib/action_view/helpers/date_helper.rb +++ b/actionpack/lib/action_view/helpers/date_helper.rb @@ -1,5 +1,6 @@ require "date" require 'action_view/helpers/tag_helper' +require 'active_support/core_ext/hash/slice' module ActionView module Helpers @@ -865,7 +866,7 @@ module ActionView :id => input_id_from_type(type), :name => input_name_from_type(type), :value => value - }) + "\n").html_safe + }.merge(@html_options.slice(:disabled))) + "\n").html_safe end # Returns the name attribute for the input tag diff --git a/actionpack/test/template/date_helper_test.rb b/actionpack/test/template/date_helper_test.rb index 7d3075d232..9a2d490854 100644 --- a/actionpack/test/template/date_helper_test.rb +++ b/actionpack/test/template/date_helper_test.rb @@ -1229,6 +1229,23 @@ class DateHelperTest < ActionView::TestCase assert_dom_equal expected, date_select("post", "written_on", :order => [ :month, :year ]) end + def test_date_select_without_day_and_with_disabled_html_option + @post = Post.new + @post.written_on = Date.new(2004, 6, 15) + + expected = "\n" + + expected << %{\n" + + expected << %{\n" + + assert_dom_equal expected, date_select("post", "written_on", { :order => [ :month, :year ] }, :disabled => true) + end + def test_date_select_within_fields_for @post = Post.new @post.written_on = Date.new(2004, 6, 15) @@ -1713,6 +1730,25 @@ class DateHelperTest < ActionView::TestCase assert_dom_equal expected, time_select("post", "written_on", :prompt => {:hour => 'Choose hour', :minute => 'Choose minute'}) end + def test_time_select_with_disabled_html_option + @post = Post.new + @post.written_on = Time.local(2004, 6, 15, 15, 16, 35) + + expected = %{\n} + expected << %{\n} + expected << %{\n} + + expected << %(\n" + expected << " : " + expected << %(\n" + + assert_dom_equal expected, time_select("post", "written_on", {}, :disabled => true) + end + def test_datetime_select @post = Post.new @post.updated_at = Time.local(2004, 6, 15, 16, 35) @@ -2173,6 +2209,25 @@ class DateHelperTest < ActionView::TestCase assert_dom_equal expected, datetime_select("post", "updated_at", :discard_year => true, :discard_month => true) end + def test_datetime_select_discard_year_and_month_with_disabled_html_option + @post = Post.new + @post.updated_at = Time.local(2004, 6, 15, 15, 16, 35) + + expected = %{\n} + expected << %{\n} + expected << %{\n} + + expected << %{\n" + expected << " : " + expected << %{\n" + + assert_dom_equal expected, datetime_select("post", "updated_at", { :discard_year => true, :discard_month => true }, :disabled => true) + end + def test_datetime_select_discard_hour @post = Post.new @post.updated_at = Time.local(2004, 6, 15, 15, 16, 35) -- cgit v1.2.3 From 4bc2cbc3cfa231b3dea0dce38a6fa2723c7ed94d Mon Sep 17 00:00:00 2001 From: Stefan Penner Date: Sat, 6 Mar 2010 13:30:25 -0600 Subject: Load RAILS_VERSION relative to the gemspec file. --- actionpack/actionpack.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/actionpack.gemspec b/actionpack/actionpack.gemspec index a50c55ed9a..790efc4ec5 100644 --- a/actionpack/actionpack.gemspec +++ b/actionpack/actionpack.gemspec @@ -1,4 +1,4 @@ -version = File.read("../RAILS_VERSION").strip +version = File.read(File.expand_path("../../RAILS_VERSION", __FILE__)).strip Gem::Specification.new do |s| s.platform = Gem::Platform::RUBY -- cgit v1.2.3 From 6e0443fd433393dc1967fab4f4fa06dc2b3c02fd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Sun, 7 Mar 2010 12:49:27 +0100 Subject: First take on ViewPaths clean up. --- actionpack/lib/action_view/paths.rb | 78 ++++++------------------- actionpack/lib/action_view/template/resolver.rb | 19 +++--- actionpack/test/lib/fixture_template.rb | 4 +- 3 files changed, 32 insertions(+), 69 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/paths.rb b/actionpack/lib/action_view/paths.rb index 6e55d69d00..459b6bba54 100644 --- a/actionpack/lib/action_view/paths.rb +++ b/actionpack/lib/action_view/paths.rb @@ -1,46 +1,17 @@ module ActionView #:nodoc: class PathSet < Array #:nodoc: - def self.type_cast(obj, cache = nil) - # TODO: Clean this up - if obj.is_a?(String) - if cache.nil? - cache = !defined?(Rails.application) || Rails.application.config.cache_classes + %w(initialize << concat insert push unshift).each do |method| + class_eval <<-METHOD, __FILE__, __LINE__ + 1 + def #{method}(*args) + super + typecast! end - FileSystemResolverWithFallback.new(obj, :cache => cache) - else - obj - end - end - - def initialize(*args) - super(*args).map! { |obj| self.class.type_cast(obj) } - end - - def <<(obj) - super(self.class.type_cast(obj)) - end - - def concat(array) - super(array.map! { |obj| self.class.type_cast(obj) }) - end - - def insert(index, obj) - super(index, self.class.type_cast(obj)) - end - - def push(*objs) - super(*objs.map { |obj| self.class.type_cast(obj) }) - end - - def unshift(*objs) - super(*objs.map { |obj| self.class.type_cast(obj) }) + METHOD end def find(path, details = {}, prefix = nil, partial = false) - template_path = path - - each do |load_path| - if template = load_path.find(template_path, details, prefix, partial) + each do |resolver| + if template = resolver.find(path, details, prefix, partial) return template end end @@ -48,33 +19,22 @@ module ActionView #:nodoc: raise ActionView::MissingTemplate.new(self, "#{prefix}/#{path}", details, partial) end - def exists?(path, extension = nil, prefix = nil, partial = false) - template_path = path.sub(/^\//, '') - - each do |load_path| - return true if template = load_path.find(template_path, extension, prefix, partial) - end + def exists?(path, details = {}, prefix = nil, partial = false) + each do |resolver| + if resolver.find(path, details, prefix, partial) + return true + end + end false end - def find_template(original_template_path, format = nil, html_fallback = true) - return original_template_path if original_template_path.respond_to?(:render) - template_path = original_template_path.sub(/^\//, '') + protected - each do |load_path| - if template = load_path.find(template_path, format) - return template - # Try to find html version if the format is javascript - elsif format == :js && html_fallback && template = load_path["#{template_path}.#{I18n.locale}.html"] - return template - elsif format == :js && html_fallback && template = load_path["#{template_path}.html"] - return template - end + def typecast! + each_with_index do |path, i| + next unless path.is_a?(String) + self[i] = FileSystemResolverWithFallback.new(path) end - - return Template.new(original_template_path, original_template_path.to_s =~ /\A\// ? "" : ".") if File.file?(original_template_path) - - raise MissingTemplate.new(self, original_template_path, format) end end end diff --git a/actionpack/lib/action_view/template/resolver.rb b/actionpack/lib/action_view/template/resolver.rb index 8c81914aac..40326f9193 100644 --- a/actionpack/lib/action_view/template/resolver.rb +++ b/actionpack/lib/action_view/template/resolver.rb @@ -22,8 +22,7 @@ module ActionView register_detail(:formats) { Mime::SET.symbols } register_detail(:handlers) { Template::Handlers.extensions } - def initialize(options = {}) - @cache = options[:cache] + def initialize @cached = {} end @@ -43,6 +42,10 @@ module ActionView private + def caching? + @caching ||= !defined?(Rails.application) || Rails.application.config.cache_classes + end + # This is what child classes implement. No defaults are needed # because Resolver guarantees that the arguments are present and # normalized. @@ -72,7 +75,7 @@ module ActionView end def cached(key) - return yield unless @cache + return yield unless caching? return @cached[key] if @cached.key?(key) @cached[key] = yield end @@ -133,18 +136,18 @@ module ActionView end class FileSystemResolver < PathResolver - def initialize(path, options = {}) + def initialize(path) raise ArgumentError, "path already is a Resolver class" if path.is_a?(Resolver) - super(options) + super() @path = Pathname.new(path).expand_path end end # TODO: remove hack class FileSystemResolverWithFallback < Resolver - def initialize(path, options = {}) - super(options) - @paths = [FileSystemResolver.new(path, options), FileSystemResolver.new("", options), FileSystemResolver.new("/", options)] + def initialize(path) + super() + @paths = [FileSystemResolver.new(path), FileSystemResolver.new(""), FileSystemResolver.new("/")] end def find_templates(*args) diff --git a/actionpack/test/lib/fixture_template.rb b/actionpack/test/lib/fixture_template.rb index 6b9e7c5270..a7f0490984 100644 --- a/actionpack/test/lib/fixture_template.rb +++ b/actionpack/test/lib/fixture_template.rb @@ -1,7 +1,7 @@ module ActionView #:nodoc: class FixtureResolver < PathResolver - def initialize(hash = {}, options = {}) - super(options) + def initialize(hash = {}) + super() @hash = hash end -- cgit v1.2.3 From 39d6f9e112f2320d8c2006ee3bcc160cfa761d0a Mon Sep 17 00:00:00 2001 From: wycats Date: Sun, 7 Mar 2010 06:24:30 -0800 Subject: Make many parts of Rails lazy. In order to facilitate this, add lazy_load_hooks.rb, which allows us to declare code that should be run at some later time. For instance, this allows us to defer requiring ActiveRecord::Base at boot time purely to apply configuration. Instead, we register a hook that should apply configuration once ActiveRecord::Base is loaded. With these changes, brings down total boot time of a new app to 300ms in production and 400ms in dev. TODO: rename base_hook --- actionpack/lib/action_controller/base.rb | 2 ++ actionpack/lib/action_controller/railtie.rb | 14 +++++++++----- actionpack/lib/action_dispatch/middleware/params_parser.rb | 1 - .../lib/action_dispatch/middleware/session/cookie_store.rb | 1 - actionpack/lib/action_dispatch/middleware/stack.rb | 2 +- actionpack/lib/action_dispatch/routing/mapper.rb | 4 +++- actionpack/lib/action_view.rb | 2 +- actionpack/lib/action_view/base.rb | 2 ++ actionpack/lib/action_view/helpers/active_model_helper.rb | 8 +++++--- actionpack/lib/action_view/helpers/form_helper.rb | 8 +++++--- actionpack/lib/action_view/railtie.rb | 4 +++- actionpack/lib/action_view/test_case.rb | 1 + actionpack/test/abstract_unit.rb | 1 - 13 files changed, 32 insertions(+), 18 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb index 78871154c3..d00afa6d4e 100644 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -58,6 +58,8 @@ module ActionController filter end + ActionController.run_base_hooks(self) + end end diff --git a/actionpack/lib/action_controller/railtie.rb b/actionpack/lib/action_controller/railtie.rb index e9edf80451..ca03fc62da 100644 --- a/actionpack/lib/action_controller/railtie.rb +++ b/actionpack/lib/action_controller/railtie.rb @@ -40,7 +40,7 @@ module ActionController log_subscriber ActionController::Railties::LogSubscriber.new initializer "action_controller.logger" do - ActionController::Base.logger ||= Rails.logger + ActionController.base_hook { self.logger ||= Rails.logger } end initializer "action_controller.set_configs" do |app| @@ -51,19 +51,23 @@ module ActionController ac.stylesheets_dir = paths.public.stylesheets.to_a.first ac.secret = app.config.cookie_secret - ActionController::Base.config.replace(ac) + ActionController.base_hook { self.config.replace(ac) } end initializer "action_controller.initialize_framework_caches" do - ActionController::Base.cache_store ||= RAILS_CACHE + ActionController.base_hook { self.cache_store ||= RAILS_CACHE } end initializer "action_controller.set_helpers_path" do |app| - ActionController::Base.helpers_path = app.config.paths.app.helpers.to_a + ActionController.base_hook do + self.helpers_path = app.config.paths.app.helpers.to_a + end end initializer "action_controller.url_helpers" do |app| - ActionController::Base.extend ::ActionController::Railtie::UrlHelpers.with(app.routes) + ActionController.base_hook do + extend ::ActionController::Railtie::UrlHelpers.with(app.routes) + end message = "ActionController::Routing::Routes is deprecated. " \ "Instead, use Rails.application.routes" diff --git a/actionpack/lib/action_dispatch/middleware/params_parser.rb b/actionpack/lib/action_dispatch/middleware/params_parser.rb index 522982e202..f4c4324fb0 100644 --- a/actionpack/lib/action_dispatch/middleware/params_parser.rb +++ b/actionpack/lib/action_dispatch/middleware/params_parser.rb @@ -1,4 +1,3 @@ -require 'active_support/json' require 'action_dispatch/http/request' module ActionDispatch diff --git a/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb b/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb index db64711052..22da82479e 100644 --- a/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb +++ b/actionpack/lib/action_dispatch/middleware/session/cookie_store.rb @@ -1,5 +1,4 @@ require 'active_support/core_ext/hash/keys' -require 'rack/request' module ActionDispatch module Session diff --git a/actionpack/lib/action_dispatch/middleware/stack.rb b/actionpack/lib/action_dispatch/middleware/stack.rb index 18a2922fa7..c52c8c0e6a 100644 --- a/actionpack/lib/action_dispatch/middleware/stack.rb +++ b/actionpack/lib/action_dispatch/middleware/stack.rb @@ -58,7 +58,7 @@ module ActionDispatch if lazy_compare?(@klass) && lazy_compare?(middleware) normalize(@klass) == normalize(middleware) else - klass == ActiveSupport::Inflector.constantize(middleware.to_s) + klass.name == middleware.to_s end end end diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index 52e7b0e77d..52a8df4273 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -1,3 +1,5 @@ +require "active_support/core_ext/hash/except" + module ActionDispatch module Routing class Mapper @@ -85,7 +87,7 @@ module ActionDispatch end def requirements - @requirements ||= returning(@options[:constraints] || {}) do |requirements| + @requirements ||= (@options[:constraints] || {}).tap do |requirements| requirements.reverse_merge!(@scope[:constraints]) if @scope[:constraints] @options.each { |k, v| requirements[k] = v if v.is_a?(Regexp) } end diff --git a/actionpack/lib/action_view.rb b/actionpack/lib/action_view.rb index f5035fe45a..33bf0b8deb 100644 --- a/actionpack/lib/action_view.rb +++ b/actionpack/lib/action_view.rb @@ -41,6 +41,7 @@ module ActionView autoload :Rendering end + autoload :Base autoload :MissingTemplate, 'action_view/base' autoload :Resolver, 'action_view/template/resolver' autoload :PathResolver, 'action_view/template/resolver' @@ -56,6 +57,5 @@ module ActionView end require 'active_support/core_ext/string/output_safety' -require 'action_view/base' 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 76f9eb2b0d..e88ccc645e 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -177,6 +177,8 @@ module ActionView #:nodoc: extend ActiveSupport::Memoizable + ActionView.run_base_hooks(self) + attr_accessor :base_path, :assigns, :template_extension attr_internal :captures diff --git a/actionpack/lib/action_view/helpers/active_model_helper.rb b/actionpack/lib/action_view/helpers/active_model_helper.rb index ed83b8a8b2..4e12cdab54 100644 --- a/actionpack/lib/action_view/helpers/active_model_helper.rb +++ b/actionpack/lib/action_view/helpers/active_model_helper.rb @@ -5,9 +5,11 @@ require 'active_support/core_ext/enumerable' require 'active_support/core_ext/kernel/reporting' module ActionView - class Base - @@field_error_proc = Proc.new{ |html_tag, instance| "
#{html_tag}
".html_safe } - cattr_accessor :field_error_proc + ActionView.base_hook do + class ActionView::Base + @@field_error_proc = Proc.new{ |html_tag, instance| "
#{html_tag}
".html_safe } + cattr_accessor :field_error_proc + end end module Helpers diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index ace3bcfde3..742e873a49 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -1211,8 +1211,10 @@ module ActionView end end - class Base - cattr_accessor :default_form_builder - @@default_form_builder = ::ActionView::Helpers::FormBuilder + ActionView.base_hook do + class ActionView::Base + cattr_accessor :default_form_builder + @@default_form_builder = ::ActionView::Helpers::FormBuilder + end end end diff --git a/actionpack/lib/action_view/railtie.rb b/actionpack/lib/action_view/railtie.rb index 03f18ac172..2e5d115630 100644 --- a/actionpack/lib/action_view/railtie.rb +++ b/actionpack/lib/action_view/railtie.rb @@ -10,7 +10,9 @@ module ActionView initializer "action_view.cache_asset_timestamps" do |app| unless app.config.cache_classes - ActionView::Helpers::AssetTagHelper.cache_asset_timestamps = false + ActionView.base_hook do + ActionView::Helpers::AssetTagHelper.cache_asset_timestamps = false + end end end end diff --git a/actionpack/lib/action_view/test_case.rb b/actionpack/lib/action_view/test_case.rb index 72dbead14b..1578ac9479 100644 --- a/actionpack/lib/action_view/test_case.rb +++ b/actionpack/lib/action_view/test_case.rb @@ -1,4 +1,5 @@ require 'action_controller/test_case' +require 'action_view' module ActionView class Base diff --git a/actionpack/test/abstract_unit.rb b/actionpack/test/abstract_unit.rb index d103c4e485..67aa412d3d 100644 --- a/actionpack/test/abstract_unit.rb +++ b/actionpack/test/abstract_unit.rb @@ -16,7 +16,6 @@ require 'test/unit' require 'abstract_controller' require 'action_controller' require 'action_view' -require 'action_view/base' require 'action_dispatch' require 'fixture_template' require 'active_support/dependencies' -- cgit v1.2.3 From e00bc711d8780d9c7018dec8a794cb0772cd3ad5 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Sun, 7 Mar 2010 11:09:50 -0600 Subject: Bump rack-mount requirement to 0.6 --- actionpack/actionpack.gemspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/actionpack.gemspec b/actionpack/actionpack.gemspec index 790efc4ec5..ed5b7e1e93 100644 --- a/actionpack/actionpack.gemspec +++ b/actionpack/actionpack.gemspec @@ -23,6 +23,6 @@ Gem::Specification.new do |s| s.add_dependency('activemodel', version) s.add_dependency('rack', '~> 1.1.0') s.add_dependency('rack-test', '~> 0.5.0') - s.add_dependency('rack-mount', '~> 0.5.1') + s.add_dependency('rack-mount', '~> 0.6.0') s.add_dependency('erubis', '~> 2.6.5') end -- cgit v1.2.3 From c7564d74e8a9b451f9fc78566ab0c734671f9612 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Sun, 7 Mar 2010 19:41:58 +0100 Subject: Added template lookup responsible to hold all information used in template lookup. --- .../lib/abstract_controller/compatibility.rb | 2 +- .../lib/abstract_controller/details_cache.rb | 48 ------------- actionpack/lib/abstract_controller/layouts.rb | 37 +++------- actionpack/lib/abstract_controller/rendering.rb | 42 ++++++------ .../lib/action_controller/metal/compatibility.rb | 13 ---- .../lib/action_controller/metal/implicit_render.rb | 1 + .../lib/action_controller/metal/rendering.rb | 1 - actionpack/lib/action_view/base.rb | 78 +++++++--------------- .../lib/action_view/helpers/prototype_helper.rb | 4 +- actionpack/lib/action_view/paths.rb | 4 +- actionpack/lib/action_view/render/partials.rb | 4 +- actionpack/lib/action_view/render/rendering.rb | 8 +-- actionpack/lib/action_view/template.rb | 1 + actionpack/lib/action_view/template/lookup.rb | 48 +++++++++++++ actionpack/test/abstract/details_cache_test.rb | 57 ---------------- actionpack/test/template/javascript_helper_test.rb | 4 +- actionpack/test/template/prototype_helper_test.rb | 4 +- 17 files changed, 118 insertions(+), 238 deletions(-) delete mode 100644 actionpack/lib/abstract_controller/details_cache.rb create mode 100644 actionpack/lib/action_view/template/lookup.rb delete mode 100644 actionpack/test/abstract/details_cache_test.rb (limited to 'actionpack') diff --git a/actionpack/lib/abstract_controller/compatibility.rb b/actionpack/lib/abstract_controller/compatibility.rb index 7fb93a0eb5..85fb1364b7 100644 --- a/actionpack/lib/abstract_controller/compatibility.rb +++ b/actionpack/lib/abstract_controller/compatibility.rb @@ -11,7 +11,7 @@ module AbstractController def _default_layout(details, require_layout = false) super rescue ActionView::MissingTemplate - _find_layout(_layout({}), {}) + _layout_for_name(_layout({}), {}) nil end end diff --git a/actionpack/lib/abstract_controller/details_cache.rb b/actionpack/lib/abstract_controller/details_cache.rb deleted file mode 100644 index be1a1c0f34..0000000000 --- a/actionpack/lib/abstract_controller/details_cache.rb +++ /dev/null @@ -1,48 +0,0 @@ -module AbstractController - class HashKey - @hash_keys = Hash.new {|h,k| h[k] = {} } - - def self.get(klass, details) - @hash_keys[klass][details] ||= new(klass, details) - end - - attr_reader :hash - alias_method :eql?, :equal? - - def initialize(klass, details) - @details, @hash = details, details.hash - end - - def inspect - "#" - end - end - - module DetailsCache - extend ActiveSupport::Concern - - module ClassMethods - def clear_template_caches! - ActionView::Partials::PartialRenderer::TEMPLATES.clear - template_cache.clear - super - end - - def template_cache - @template_cache ||= Hash.new {|h,k| h[k] = {} } - end - end - - def render_to_body(*args) - Thread.current[:format_locale_key] = HashKey.get(self.class, details_for_render) - super - end - - private - - def with_template_cache(name, details) - self.class.template_cache[HashKey.get(self.class, details)][name] ||= super - end - - end -end diff --git a/actionpack/lib/abstract_controller/layouts.rb b/actionpack/lib/abstract_controller/layouts.rb index beda4e633e..c26593dd19 100644 --- a/actionpack/lib/abstract_controller/layouts.rb +++ b/actionpack/lib/abstract_controller/layouts.rb @@ -170,27 +170,7 @@ module AbstractController module ClassMethods def inherited(klass) super - klass.class_eval do - _write_layout_method - @found_layouts = {} - end - end - - def clear_template_caches! - @found_layouts.clear if defined? @found_layouts - super - end - - def cache_layout(details) - layout = @found_layouts - key = Thread.current[:format_locale_key] - - # Cache nil - if layout.key?(key) - return layout[key] - else - layout[key] = yield - end + klass._write_layout_method end # This module is mixed in if layout conditions are provided. This means @@ -282,12 +262,10 @@ module AbstractController if name self.class_eval <<-RUBY, __FILE__, __LINE__ + 1 def _layout(details) - self.class.cache_layout(details) do - if template_exists?("#{_implied_layout_name}", details, :_prefix => "layouts") - "#{_implied_layout_name}" - else - super - end + if template_exists?("#{_implied_layout_name}", :_prefix => "layouts") + "#{_implied_layout_name}" + else + super end end RUBY @@ -372,9 +350,10 @@ module AbstractController # ==== Returns # Template:: A template object matching the name and details def _find_layout(name, details) - # TODO: Make prefix actually part of details in ViewPath#find_by_parts prefix = details.key?(:prefix) ? details.delete(:prefix) : "layouts" - find_template(name, details, :_prefix => prefix) + # TODO This should happen automatically + template_lookup.details = template_lookup.details.merge(:formats => details[:formats]) + find_template(name, :_prefix => prefix) end # Returns the default layout for this controller and a given set of details. diff --git a/actionpack/lib/abstract_controller/rendering.rb b/actionpack/lib/abstract_controller/rendering.rb index 2ea4f02871..df33e8b480 100644 --- a/actionpack/lib/abstract_controller/rendering.rb +++ b/actionpack/lib/abstract_controller/rendering.rb @@ -90,10 +90,22 @@ module AbstractController view_context.render_partial(options) end + def template_lookup + @template_lookup ||= ActionView::Template::Lookup.new(_view_paths, details_for_render) + end + # The list of view paths for this controller. See ActionView::ViewPathSet for # more details about writing custom view paths. def view_paths - _view_paths + template_lookup.view_paths + end + + def append_view_path(path) + template_lookup.view_paths.push(*path) + end + + def prepend_view_path(path) + template_lookup.view_paths.unshift(*path) end # The prefix used in render "foo" shortcuts. @@ -162,10 +174,9 @@ module AbstractController options[:_prefix] ||= _prefix if (options.keys & [:partial, :file, :template]).empty? details = _normalize_details(options) + template_lookup.details = details - options[:_template] ||= with_template_cache(name, details) do - find_template(name, details, options) - end + options[:_template] ||= find_template(name, options) end def details_for_render @@ -179,16 +190,12 @@ module AbstractController details end - def find_template(name, details, options) - view_paths.find(name, details, options[:_prefix], options[:_partial]) - end - - def template_exists?(name, details, options) - view_paths.exists?(name, details, options[:_prefix], options[:_partial]) + def find_template(name, options) + template_lookup.find(name, options[:_prefix], options[:_partial]) end - def with_template_cache(name, details) - yield + def template_exists?(name, options) + template_lookup.exists?(name, options[:_prefix], options[:_partial]) end def format_for_text @@ -196,9 +203,6 @@ module AbstractController end module ClassMethods - def clear_template_caches! - end - # Append a path to the list of view paths for this controller. # # ==== Parameters @@ -206,7 +210,7 @@ module AbstractController # the default view path. You may also provide a custom view path # (see ActionView::ViewPathSet for more information) def append_view_path(path) - self.view_paths = view_paths.dup + Array.wrap(path) + self.view_paths = view_paths.dup + Array(path) end # Prepend a path to the list of view paths for this controller. @@ -216,8 +220,7 @@ module AbstractController # the default view path. You may also provide a custom view path # (see ActionView::ViewPathSet for more information) def prepend_view_path(path) - clear_template_caches! - self.view_paths = Array.wrap(path) + view_paths.dup + self.view_paths = Array(path) + view_paths.dup end # A list of all of the default view paths for this controller. @@ -231,9 +234,8 @@ module AbstractController # paths:: If a ViewPathSet is provided, use that; # otherwise, process the parameter into a ViewPathSet. def view_paths=(paths) - clear_template_caches! self._view_paths = paths.is_a?(ActionView::PathSet) ? paths : ActionView::Base.process_view_paths(paths) - _view_paths.freeze + self._view_paths.freeze end end end diff --git a/actionpack/lib/action_controller/metal/compatibility.rb b/actionpack/lib/action_controller/metal/compatibility.rb index 317a9fd951..518272b4cf 100644 --- a/actionpack/lib/action_controller/metal/compatibility.rb +++ b/actionpack/lib/action_controller/metal/compatibility.rb @@ -73,18 +73,5 @@ module ActionController def performed? response_body end - - # ==== Request only view path switching ==== - def append_view_path(path) - view_paths.push(*path) - end - - def prepend_view_path(path) - view_paths.unshift(*path) - end - - def view_paths - view_context.view_paths - end end end diff --git a/actionpack/lib/action_controller/metal/implicit_render.rb b/actionpack/lib/action_controller/metal/implicit_render.rb index ba2d9b686e..da717fcce2 100644 --- a/actionpack/lib/action_controller/metal/implicit_render.rb +++ b/actionpack/lib/action_controller/metal/implicit_render.rb @@ -12,6 +12,7 @@ module ActionController def method_for_action(action_name) super || begin + # TODO This should use template lookup if view_paths.exists?(action_name.to_s, details_for_render, controller_path) "default_render" end diff --git a/actionpack/lib/action_controller/metal/rendering.rb b/actionpack/lib/action_controller/metal/rendering.rb index 00a09309bf..0a4215028b 100644 --- a/actionpack/lib/action_controller/metal/rendering.rb +++ b/actionpack/lib/action_controller/metal/rendering.rb @@ -4,7 +4,6 @@ module ActionController include ActionController::RackDelegation include AbstractController::Rendering - include AbstractController::DetailsCache def process_action(*) self.formats = request.formats.map {|x| x.to_sym } diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index 76f9eb2b0d..22bc390dc5 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -180,64 +180,21 @@ module ActionView #:nodoc: attr_accessor :base_path, :assigns, :template_extension attr_internal :captures - def reset_formats(formats) - old_formats, self.formats = self.formats, formats - reset_hash_key - yield if block_given? - ensure - if block_given? - self.formats = old_formats - reset_hash_key - end - end - - def reset_hash_key - if defined?(AbstractController::HashKey) - # This is expensive, but we need to reset this when the format is updated, - # which currently only happens - Thread.current[:format_locale_key] = - AbstractController::HashKey.get(self.class, :formats => formats, :locale => [I18n.locale]) - end - end - - def formats - controller ? controller.formats : @formats - end - - def formats=(val) - if controller - controller.formats = val - else - @formats = val - end - end - class << self delegate :erb_trim_mode=, :to => 'ActionView::Template::Handlers::ERB' delegate :logger, :to => 'ActionController::Base', :allow_nil => true end - @@debug_rjs = false - ## - # :singleton-method: # Specify whether RJS responses should be wrapped in a try/catch block # that alert()s the caught exception (and then re-raises it). cattr_accessor :debug_rjs - - # Specify whether templates should be cached. Otherwise the file we be read everytime it is accessed. - # Automatically reloading templates are not thread safe and should only be used in development mode. - @@cache_template_loading = nil - cattr_accessor :cache_template_loading + @@debug_rjs = false # :nodoc: def self.xss_safe? true end - def self.cache_template_loading? - ActionController::Base.allow_concurrency || (cache_template_loading.nil? ? !ActiveSupport::Dependencies.load? : cache_template_loading) - end - attr_internal :request, :layout def controller_path @@ -249,8 +206,6 @@ module ActionView #:nodoc: delegate :logger, :to => :controller, :allow_nil => true - delegate :find, :to => :view_paths - include Context def self.process_view_paths(value) @@ -287,10 +242,10 @@ module ActionView #:nodoc: klass = self end - klass.new(controller.class.view_paths, {}, controller) + klass.new(controller.template_lookup, {}, controller) end - def initialize(view_paths = [], assigns_for_first_render = {}, controller = nil, formats = nil)#:nodoc: + def initialize(template_lookup = nil, assigns_for_first_render = {}, controller = nil, formats = nil) #:nodoc: @config = nil @formats = formats @assigns = assigns_for_first_render.each { |key, value| instance_variable_set("@#{key}", value) } @@ -298,16 +253,33 @@ module ActionView #:nodoc: @_controller = controller @_config = ActiveSupport::InheritableOptions.new(controller.config) if controller - @_content_for = Hash.new {|h,k| h[k] = ActiveSupport::SafeBuffer.new } + @_content_for = Hash.new { |h,k| h[k] = ActiveSupport::SafeBuffer.new } @_virtual_path = nil - self.view_paths = view_paths + + @template_lookup = template_lookup.is_a?(ActionView::Template::Lookup) ? + template_lookup : ActionView::Template::Lookup.new(template_lookup) end attr_internal :controller, :template, :config - attr_reader :view_paths - def view_paths=(paths) - @view_paths = self.class.process_view_paths(paths) + attr_reader :template_lookup + delegate :find, :view_paths, :view_paths=, :to => :template_lookup + + def formats=(formats) + update_details(:formats => Array(formats)) + end + + def update_details(details) + old_details = template_lookup.details + template_lookup.details = old_details.merge(details) + + if block_given? + begin + yield + ensure + template_lookup.details = old_details + end + end end def punctuate_body!(part) diff --git a/actionpack/lib/action_view/helpers/prototype_helper.rb b/actionpack/lib/action_view/helpers/prototype_helper.rb index 67a7586699..be49b5cc28 100644 --- a/actionpack/lib/action_view/helpers/prototype_helper.rb +++ b/actionpack/lib/action_view/helpers/prototype_helper.rb @@ -182,7 +182,7 @@ module ActionView def initialize(context, &block) #:nodoc: context._evaluate_assigns_and_ivars @context, @lines = context, [] - @context.reset_formats([:js, :html]) do + @context.update_details(:formats => [:js, :html]) do include_helpers_from_context @context.with_output_buffer(@lines) do @context.instance_exec(self, &block) @@ -583,7 +583,7 @@ module ActionView end def with_formats(*args) - @context ? @context.reset_formats(args) { yield } : yield + @context ? @context.update_details(:formats => args) { yield } : yield end def javascript_object_for(object) diff --git a/actionpack/lib/action_view/paths.rb b/actionpack/lib/action_view/paths.rb index 459b6bba54..154a79a8f1 100644 --- a/actionpack/lib/action_view/paths.rb +++ b/actionpack/lib/action_view/paths.rb @@ -9,7 +9,7 @@ module ActionView #:nodoc: METHOD end - def find(path, details = {}, prefix = nil, partial = false) + def find(path, details = {}, prefix = nil, partial = false, key=nil) each do |resolver| if template = resolver.find(path, details, prefix, partial) return template @@ -19,7 +19,7 @@ module ActionView #:nodoc: raise ActionView::MissingTemplate.new(self, "#{prefix}/#{path}", details, partial) end - def exists?(path, details = {}, prefix = nil, partial = false) + def exists?(path, details = {}, prefix = nil, partial = false, key=nil) each do |resolver| if resolver.find(path, details, prefix, partial) return true diff --git a/actionpack/lib/action_view/render/partials.rb b/actionpack/lib/action_view/render/partials.rb index 8b6dce0c1c..74513935a7 100644 --- a/actionpack/lib/action_view/render/partials.rb +++ b/actionpack/lib/action_view/render/partials.rb @@ -309,7 +309,7 @@ module ActionView prefix = controller.controller_path unless path.include?(?/) end - @view.find(path, {:formats => @view.formats}, prefix, true) + @view.find(path, prefix, true) end def partial_path(object = @object) @@ -329,7 +329,7 @@ module ActionView details = options[:_details] - # Is this needed + # TODO This should happen automatically as well self.formats = details[:formats] if details renderer = PartialRenderer.new(self, options, nil) text = renderer.render diff --git a/actionpack/lib/action_view/render/rendering.rb b/actionpack/lib/action_view/render/rendering.rb index 28b79bfcb7..1be5675e37 100644 --- a/actionpack/lib/action_view/render/rendering.rb +++ b/actionpack/lib/action_view/render/rendering.rb @@ -25,7 +25,7 @@ module ActionView end template = if options[:file] - find(options[:file], details_for_render) + find(options[:file]) elsif options[:inline] handler = Template.handler_class_for_extension(options[:type] || "erb") Template.new(options[:inline], "inline template", handler, {}) @@ -34,7 +34,7 @@ module ActionView end if template - layout = find(layout, details_for_render) if layout + layout = find(layout) if layout _render_template(template, layout, :locals => options[:locals]) end when :update @@ -44,10 +44,6 @@ module ActionView end end - def details_for_render - controller.try(:details_for_render) || {:formats => formats} - end - # You can think of a layout as a method that is called with a block. _layout_for # returns the contents that are yielded to the layout. If the user calls yield # :some_name, the block, by default, returns content_for(:some_name). If the user diff --git a/actionpack/lib/action_view/template.rb b/actionpack/lib/action_view/template.rb index cd6b1930a1..c176359253 100644 --- a/actionpack/lib/action_view/template.rb +++ b/actionpack/lib/action_view/template.rb @@ -13,6 +13,7 @@ module ActionView autoload :Handler autoload :Handlers autoload :Text + autoload :Lookup end extend Template::Handlers diff --git a/actionpack/lib/action_view/template/lookup.rb b/actionpack/lib/action_view/template/lookup.rb new file mode 100644 index 0000000000..ea3a12615b --- /dev/null +++ b/actionpack/lib/action_view/template/lookup.rb @@ -0,0 +1,48 @@ +module ActionView + class Template + class Lookup + attr_reader :details, :view_paths + + class DetailsKey + attr_reader :details + alias :eql? :equal? + + @details_keys = Hash.new + + def self.get(details) + @details_keys[details] ||= new(details) + end + + def initialize(details) + @details, @hash = details, details.hash + end + end + + def initialize(view_paths, details = {}) + @details = details + self.view_paths = view_paths + end + + def view_paths=(paths) + @view_paths = ActionView::Base.process_view_paths(paths) + end + + def details=(details) + @details = details + @details_key = nil if @details_key && @details_key.details != details + end + + def details_key + @details_key ||= DetailsKey.get(details) unless details.empty? + end + + def find(name, prefix = nil, partial = false) + @view_paths.find(name, details, prefix, partial || false, details_key) + end + + def exists?(name, prefix = nil, partial = false) + @view_paths.exists?(name, details, prefix, partial || false, details_key) + end + end + end +end \ No newline at end of file diff --git a/actionpack/test/abstract/details_cache_test.rb b/actionpack/test/abstract/details_cache_test.rb deleted file mode 100644 index ee746c1bb0..0000000000 --- a/actionpack/test/abstract/details_cache_test.rb +++ /dev/null @@ -1,57 +0,0 @@ -require 'abstract_unit' - -module AbstractController - module Testing - - class CachedController < AbstractController::Base - include AbstractController::Rendering - include AbstractController::DetailsCache - - self.view_paths = [ActionView::FixtureResolver.new( - "default.erb" => "With Default", - "template.erb" => "With Template", - "some/file.erb" => "With File", - "template_name.erb" => "With Template Name" - )] - end - - class TestLocalizedCache < ActiveSupport::TestCase - - def setup - @controller = CachedController.new - CachedController.clear_template_caches! - end - - def test_templates_are_cached - @controller.render :template => "default.erb" - assert_equal "With Default", @controller.response_body - - cached = @controller.class.template_cache - assert_equal 1, cached.size - assert_kind_of ActionView::Template, cached.values.first["default.erb"] - end - - def test_cache_is_used - CachedController.new.render :template => "default.erb" - - @controller.expects(:find_template).never - @controller.render :template => "default.erb" - - assert_equal 1, @controller.class.template_cache.size - end - - def test_cache_changes_with_locale - CachedController.new.render :template => "default.erb" - - I18n.locale = :es - @controller.render :template => "default.erb" - - assert_equal 2, @controller.class.template_cache.size - ensure - I18n.locale = :en - end - - end - - end -end diff --git a/actionpack/test/template/javascript_helper_test.rb b/actionpack/test/template/javascript_helper_test.rb index 368a9c2514..6604f1c095 100644 --- a/actionpack/test/template/javascript_helper_test.rb +++ b/actionpack/test/template/javascript_helper_test.rb @@ -7,8 +7,8 @@ class JavaScriptHelperTest < ActionView::TestCase attr_accessor :formats, :output_buffer - def reset_formats(format) - @format = format + def update_details(details) + @details = details yield if block_given? end diff --git a/actionpack/test/template/prototype_helper_test.rb b/actionpack/test/template/prototype_helper_test.rb index 6811d3aaf3..619293dc43 100644 --- a/actionpack/test/template/prototype_helper_test.rb +++ b/actionpack/test/template/prototype_helper_test.rb @@ -39,8 +39,8 @@ class Author::Nested < Author; end class PrototypeHelperBaseTest < ActionView::TestCase attr_accessor :formats, :output_buffer - def reset_formats(format) - @format = format + def update_details(details) + @details = details yield if block_given? end -- cgit v1.2.3 From dfc7ff64298e1a0656639a630cc0ddbf93c1eeb9 Mon Sep 17 00:00:00 2001 From: Jan De Poorter Date: Fri, 12 Feb 2010 11:39:19 +0100 Subject: Make sure nested singular resources get the correct name [#3911 state:committed] Signed-off-by: Jeremy Kemper --- actionpack/lib/action_dispatch/routing/mapper.rb | 5 ++++- actionpack/test/dispatch/routing_test.rb | 10 ++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index 52a8df4273..7a33259054 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -452,7 +452,10 @@ module ActionDispatch scope(:path => resource.name.to_s, :controller => resource.controller) do with_scope_level(:resource, resource) do - yield if block_given? + + scope(:name_prefix => resource.name.to_s) do + yield if block_given? + end get :show if resource.actions.include?(:show) post :create if resource.actions.include?(:create) diff --git a/actionpack/test/dispatch/routing_test.rb b/actionpack/test/dispatch/routing_test.rb index 37c2f1421b..b46276c453 100644 --- a/actionpack/test/dispatch/routing_test.rb +++ b/actionpack/test/dispatch/routing_test.rb @@ -24,6 +24,8 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest resource :session do get :create + + resource :info end match 'account/logout' => redirect("/logout"), :as => :logout_redirect @@ -234,6 +236,14 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest end end + def test_session_info_nested_singleton_resource + with_test_routes do + get '/session/info' + assert_equal 'infos#show', @response.body + assert_equal '/session/info', session_info_path + end + end + def test_redirect_modulo with_test_routes do get '/account/modulo/name' -- cgit v1.2.3 From ffd8d753f171a33cb0f8dadaff7fc5ba12b8f6b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Mon, 8 Mar 2010 02:04:18 +0100 Subject: Move layout lookup to views. --- actionpack/lib/abstract_controller/base.rb | 6 ------ .../lib/abstract_controller/compatibility.rb | 18 ---------------- actionpack/lib/abstract_controller/layouts.rb | 25 ++++++---------------- actionpack/lib/abstract_controller/rendering.rb | 8 ++++--- .../lib/action_controller/metal/implicit_render.rb | 3 +-- .../lib/action_controller/metal/rendering.rb | 2 +- actionpack/lib/action_view/base.rb | 6 +----- actionpack/lib/action_view/render/partials.rb | 2 +- actionpack/lib/action_view/render/rendering.rb | 16 +++++++++++++- actionpack/lib/action_view/template/lookup.rb | 8 +++++++ actionpack/test/abstract/layouts_test.rb | 2 +- 11 files changed, 39 insertions(+), 57 deletions(-) delete mode 100644 actionpack/lib/abstract_controller/compatibility.rb (limited to 'actionpack') diff --git a/actionpack/lib/abstract_controller/base.rb b/actionpack/lib/abstract_controller/base.rb index ea88a2d24d..c12b584144 100644 --- a/actionpack/lib/abstract_controller/base.rb +++ b/actionpack/lib/abstract_controller/base.rb @@ -7,7 +7,6 @@ module AbstractController class Base attr_internal :response_body attr_internal :action_name - attr_internal :formats class << self attr_reader :abstract @@ -100,11 +99,6 @@ module AbstractController abstract! - # Initialize controller with nil formats. - def initialize #:nodoc: - @_formats = nil - end - def config @config ||= ActiveSupport::InheritableOptions.new(self.class.config) end diff --git a/actionpack/lib/abstract_controller/compatibility.rb b/actionpack/lib/abstract_controller/compatibility.rb deleted file mode 100644 index 85fb1364b7..0000000000 --- a/actionpack/lib/abstract_controller/compatibility.rb +++ /dev/null @@ -1,18 +0,0 @@ -module AbstractController - module Compatibility - extend ActiveSupport::Concern - - def _find_layout(name, details) - details[:prefix] = nil if name =~ /\blayouts/ - super - end - - # Move this into a "don't run in production" module - def _default_layout(details, require_layout = false) - super - rescue ActionView::MissingTemplate - _layout_for_name(_layout({}), {}) - nil - end - end -end diff --git a/actionpack/lib/abstract_controller/layouts.rb b/actionpack/lib/abstract_controller/layouts.rb index c26593dd19..ac0f646e19 100644 --- a/actionpack/lib/abstract_controller/layouts.rb +++ b/actionpack/lib/abstract_controller/layouts.rb @@ -260,9 +260,11 @@ module AbstractController raise ArgumentError, "Layouts must be specified as a String, Symbol, false, or nil" when nil if name + _prefix = "layouts" unless _implied_layout_name =~ /\blayouts/ + self.class_eval <<-RUBY, __FILE__, __LINE__ + 1 def _layout(details) - if template_exists?("#{_implied_layout_name}", :_prefix => "layouts") + if template_exists?("#{_implied_layout_name}", :_prefix => #{_prefix.inspect}) "#{_implied_layout_name}" else super @@ -290,6 +292,7 @@ module AbstractController # render_template if layout layout = _layout_for_option(layout, options[:_template].details) + layout = find_template(layout, {}) response = layout.render(view_context, options[:locals] || {}) { response } end @@ -309,7 +312,7 @@ module AbstractController # the lookup to. By default, layout lookup is limited to the # formats specified for the current request. def _layout_for_name(name, details) - name && _find_layout(name, details) + name end # Determine the layout for a given name and details, taking into account @@ -337,23 +340,7 @@ module AbstractController return unless (options.keys & [:text, :inline, :partial]).empty? || options.key?(:layout) layout = options.key?(:layout) ? options[:layout] : :default - options[:_layout] = _layout_for_option(layout, options[:_template].details) - end - - # Take in the name and details and find a Template. - # - # ==== Parameters - # name:: The name of the template to retrieve - # details:: A list of details to restrict the search by. This - # might include details like the format or locale of the template. - # - # ==== Returns - # Template:: A template object matching the name and details - def _find_layout(name, details) - prefix = details.key?(:prefix) ? details.delete(:prefix) : "layouts" - # TODO This should happen automatically - template_lookup.details = template_lookup.details.merge(:formats => details[:formats]) - find_template(name, :_prefix => prefix) + options[:layout] = _layout_for_option(layout, options[:_template].details) end # Returns the default layout for this controller and a given set of details. diff --git a/actionpack/lib/abstract_controller/rendering.rb b/actionpack/lib/abstract_controller/rendering.rb index df33e8b480..8125badc75 100644 --- a/actionpack/lib/abstract_controller/rendering.rb +++ b/actionpack/lib/abstract_controller/rendering.rb @@ -15,10 +15,12 @@ module AbstractController included do class_attribute :_view_paths - delegate :_view_paths, :to => :'self.class' self._view_paths = ActionView::PathSet.new end + delegate :formats, :formats=, :to => :template_lookup + delegate :_view_paths, :to => :'self.class' + # An instance of a view class. The default view class is ActionView::Base # # The view class must have the following methods: @@ -180,11 +182,11 @@ module AbstractController end def details_for_render - { :formats => formats, :locale => [I18n.locale] } + { } end def _normalize_details(options) - details = details_for_render + details = template_lookup.details details[:formats] = Array(options[:format]) if options[:format] details[:locale] = Array(options[:locale]) if options[:locale] details diff --git a/actionpack/lib/action_controller/metal/implicit_render.rb b/actionpack/lib/action_controller/metal/implicit_render.rb index da717fcce2..c3e3b8fdf5 100644 --- a/actionpack/lib/action_controller/metal/implicit_render.rb +++ b/actionpack/lib/action_controller/metal/implicit_render.rb @@ -12,8 +12,7 @@ module ActionController def method_for_action(action_name) super || begin - # TODO This should use template lookup - if view_paths.exists?(action_name.to_s, details_for_render, controller_path) + if template_exists?(action_name.to_s, :_prefix => controller_path) "default_render" end end diff --git a/actionpack/lib/action_controller/metal/rendering.rb b/actionpack/lib/action_controller/metal/rendering.rb index 0a4215028b..e2d2e2312b 100644 --- a/actionpack/lib/action_controller/metal/rendering.rb +++ b/actionpack/lib/action_controller/metal/rendering.rb @@ -5,7 +5,7 @@ module ActionController include ActionController::RackDelegation include AbstractController::Rendering - def process_action(*) + def process(*) self.formats = request.formats.map {|x| x.to_sym } super end diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index 22bc390dc5..5acd2a8b82 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -263,11 +263,7 @@ module ActionView #:nodoc: attr_internal :controller, :template, :config attr_reader :template_lookup - delegate :find, :view_paths, :view_paths=, :to => :template_lookup - - def formats=(formats) - update_details(:formats => Array(formats)) - end + delegate :find, :formats, :formats=, :view_paths, :view_paths=, :to => :template_lookup def update_details(details) old_details = template_lookup.details diff --git a/actionpack/lib/action_view/render/partials.rb b/actionpack/lib/action_view/render/partials.rb index 74513935a7..52cb188508 100644 --- a/actionpack/lib/action_view/render/partials.rb +++ b/actionpack/lib/action_view/render/partials.rb @@ -330,7 +330,7 @@ module ActionView details = options[:_details] # TODO This should happen automatically as well - self.formats = details[:formats] if details + self.formats = details[:formats] if details[:formats] renderer = PartialRenderer.new(self, options, nil) text = renderer.render options[:_template] = renderer.template diff --git a/actionpack/lib/action_view/render/rendering.rb b/actionpack/lib/action_view/render/rendering.rb index 1be5675e37..b92a03ddbd 100644 --- a/actionpack/lib/action_view/render/rendering.rb +++ b/actionpack/lib/action_view/render/rendering.rb @@ -88,12 +88,26 @@ module ActionView # _layout:: The layout, if any, to wrap the Template in def render_template(options) _evaluate_assigns_and_ivars - template, layout = options.values_at(:_template, :_layout) + template, layout = options.values_at(:_template, :layout) _render_template(template, layout, options) end + def _find_layout(template, layout) + begin + prefix = "layouts" unless layout =~ /\blayouts/ + layout = find(layout, prefix) + rescue ActionView::MissingTemplate => e + update_details(:formats => nil) do + raise unless template_lookup.exists?(layout, prefix) + end + end + end + def _render_template(template, layout = nil, options = {}) + self.formats = template.details[:formats] + locals = options[:locals] || {} + layout = _find_layout(template, layout) if layout.is_a?(String) ActiveSupport::Notifications.instrument("action_view.render_template", :identifier => template.identifier, :layout => layout.try(:identifier)) do diff --git a/actionpack/lib/action_view/template/lookup.rb b/actionpack/lib/action_view/template/lookup.rb index ea3a12615b..30de093934 100644 --- a/actionpack/lib/action_view/template/lookup.rb +++ b/actionpack/lib/action_view/template/lookup.rb @@ -23,6 +23,14 @@ module ActionView self.view_paths = view_paths end + def formats + @details[:formats] + end + + def formats=(value) + self.details = @details.merge(:formats => Array(value)) + end + def view_paths=(paths) @view_paths = ActionView::Base.process_view_paths(paths) end diff --git a/actionpack/test/abstract/layouts_test.rb b/actionpack/test/abstract/layouts_test.rb index b6d89ea489..fcc91d03f1 100644 --- a/actionpack/test/abstract/layouts_test.rb +++ b/actionpack/test/abstract/layouts_test.rb @@ -11,7 +11,7 @@ module AbstractControllerTests self.view_paths = [ActionView::FixtureResolver.new( "layouts/hello.erb" => "With String <%= yield %>", "layouts/hello_override.erb" => "With Override <%= yield %>", - "layouts/abstract_controller_tests/layouts/with_string_implied_child.erb" => + "abstract_controller_tests/layouts/with_string_implied_child.erb" => "With Implied <%= yield %>", "layouts/overwrite.erb" => "Overwrite <%= yield %>", "layouts/with_false_layout.erb" => "False Layout <%= yield %>" -- cgit v1.2.3 From 4bae77a89baf0fee15c6b2cfd3987f7344b56a1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Mon, 8 Mar 2010 02:58:16 +0100 Subject: More cleanup on the layouts side. --- actionpack/lib/abstract_controller.rb | 2 - actionpack/lib/abstract_controller/layouts.rb | 81 ++++++++-------------- .../lib/action_controller/metal/compatibility.rb | 2 - actionpack/lib/action_view/render/partials.rb | 13 +--- actionpack/lib/action_view/render/rendering.rb | 10 ++- 5 files changed, 34 insertions(+), 74 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/abstract_controller.rb b/actionpack/lib/abstract_controller.rb index c1b035306b..05348d8ba0 100644 --- a/actionpack/lib/abstract_controller.rb +++ b/actionpack/lib/abstract_controller.rb @@ -14,8 +14,6 @@ module AbstractController autoload :Base autoload :Callbacks autoload :Collector - autoload :Compatibility - autoload :DetailsCache autoload :Helpers autoload :Layouts autoload :Logger diff --git a/actionpack/lib/abstract_controller/layouts.rb b/actionpack/lib/abstract_controller/layouts.rb index ac0f646e19..c6a94c5220 100644 --- a/actionpack/lib/abstract_controller/layouts.rb +++ b/actionpack/lib/abstract_controller/layouts.rb @@ -239,10 +239,10 @@ module AbstractController def _write_layout_method case defined?(@_layout) ? @_layout : nil when String - self.class_eval %{def _layout(details) #{@_layout.inspect} end} + self.class_eval %{def _layout; #{@_layout.inspect} end} when Symbol self.class_eval <<-ruby_eval, __FILE__, __LINE__ + 1 - def _layout(details) + def _layout #{@_layout}.tap do |layout| unless layout.is_a?(String) || !layout raise ArgumentError, "Your layout method :#{@_layout} returned \#{layout}. It " \ @@ -253,9 +253,9 @@ module AbstractController ruby_eval when Proc define_method :_layout_from_proc, &@_layout - self.class_eval %{def _layout(details) _layout_from_proc(self) end} + self.class_eval %{def _layout; _layout_from_proc(self) end} when false - self.class_eval %{def _layout(details) end} + self.class_eval %{def _layout; end} when true raise ArgumentError, "Layouts must be specified as a String, Symbol, false, or nil" when nil @@ -263,7 +263,7 @@ module AbstractController _prefix = "layouts" unless _implied_layout_name =~ /\blayouts/ self.class_eval <<-RUBY, __FILE__, __LINE__ + 1 - def _layout(details) + def _layout if template_exists?("#{_implied_layout_name}", :_prefix => #{_prefix.inspect}) "#{_implied_layout_name}" else @@ -277,43 +277,24 @@ module AbstractController end end - def render_to_body(options = {}) - # In the case of a partial with a layout, handle the layout - # here, and make sure the view does not try to handle it - layout = options.delete(:layout) if options.key?(:partial) + def render_to_body(options={}) + if (options.keys & [:text, :inline, :partial]).empty? || options.key?(:layout) + layout = options.key?(:layout) ? options[:layout] : :default + value = _layout_for_option(layout) - response = super + # TODO Revisit this. Maybe we should pass a :layout_prefix? + options[:layout] = ((!value || value =~ /\blayouts/) ? value : "layouts/#{value}") - # This is a little bit messy. We need to explicitly handle partial - # layouts here since the core lookup logic is in the view, but - # we need to determine the layout based on the controller - # - # TODO: An easier way to handle this would probably be to override - # render_template - if layout - layout = _layout_for_option(layout, options[:_template].details) - layout = find_template(layout, {}) - response = layout.render(view_context, options[:locals] || {}) { response } + # TODO Revisit this. :layout with :partial from controllers are not the same as in views + options[:layout] = view_context._find_layout(options[:layout]) if options.key?(:partial) end - - response + super end private # This will be overwritten by _write_layout_method - def _layout(details) end - - # Determine the layout for a given name and details. - # - # ==== Parameters - # name:: The name of the template - # details Object}>:: A list of details to restrict - # the lookup to. By default, layout lookup is limited to the - # formats specified for the current request. - def _layout_for_name(name, details) - name - end + def _layout; end # Determine the layout for a given name and details, taking into account # the name type. @@ -323,11 +304,11 @@ module AbstractController # details Object}>:: A list of details to restrict # the lookup to. By default, layout lookup is limited to the # formats specified for the current request. - def _layout_for_option(name, details) + def _layout_for_option(name) case name - when String then _layout_for_name(name, details) - when true then _default_layout(details, true) - when :default then _default_layout(details, false) + when String then name + when true then _default_layout(true) + when :default then _default_layout(false) when false, nil then nil else raise ArgumentError, @@ -335,14 +316,6 @@ module AbstractController end end - def _determine_template(options) - super - - return unless (options.keys & [:text, :inline, :partial]).empty? || options.key?(:layout) - layout = options.key?(:layout) ? options[:layout] : :default - options[:layout] = _layout_for_option(layout, options[:_template].details) - end - # Returns the default layout for this controller and a given set of details. # Optionally raises an exception if the layout could not be found. # @@ -355,18 +328,20 @@ module AbstractController # # ==== Returns # Template:: The template object for the default layout (or nil) - def _default_layout(details, require_layout = false) - if require_layout && _action_has_layout? && !_layout(details) - raise ArgumentError, - "There was no default layout for #{self.class} in #{view_paths.inspect}" - end - + def _default_layout(require_layout = false) begin - _layout_for_name(_layout(details), details) if _action_has_layout? + layout_name = _layout if _action_has_layout? rescue NameError => e raise NoMethodError, "You specified #{@_layout.inspect} as the layout, but no such method was found" end + + if require_layout && _action_has_layout? && !layout_name + raise ArgumentError, + "There was no default layout for #{self.class} in #{view_paths.inspect}" + end + + layout_name end def _action_has_layout? diff --git a/actionpack/lib/action_controller/metal/compatibility.rb b/actionpack/lib/action_controller/metal/compatibility.rb index 518272b4cf..0cb20b2f0f 100644 --- a/actionpack/lib/action_controller/metal/compatibility.rb +++ b/actionpack/lib/action_controller/metal/compatibility.rb @@ -2,8 +2,6 @@ module ActionController module Compatibility extend ActiveSupport::Concern - include AbstractController::Compatibility - class ::ActionController::ActionControllerError < StandardError #:nodoc: end diff --git a/actionpack/lib/action_view/render/partials.rb b/actionpack/lib/action_view/render/partials.rb index 52cb188508..eecc88a1e0 100644 --- a/actionpack/lib/action_view/render/partials.rb +++ b/actionpack/lib/action_view/render/partials.rb @@ -182,9 +182,6 @@ module ActionView @view = view_context @partial_names = PARTIAL_NAMES[@view.controller.class] - key = Thread.current[:format_locale_key] - @templates = TEMPLATES[key] if key - setup(options, block) end @@ -296,15 +293,9 @@ module ActionView end end - def find_template(path = @path) - unless @templates - path && _find_template(path) - else - path && @templates[path] ||= _find_template(path) - end - end + def find_template(path=@path) + return path unless path.is_a?(String) - def _find_template(path) if controller = @view.controller prefix = controller.controller_path unless path.include?(?/) end diff --git a/actionpack/lib/action_view/render/rendering.rb b/actionpack/lib/action_view/render/rendering.rb index b92a03ddbd..17fb110eb4 100644 --- a/actionpack/lib/action_view/render/rendering.rb +++ b/actionpack/lib/action_view/render/rendering.rb @@ -34,7 +34,6 @@ module ActionView end if template - layout = find(layout) if layout _render_template(template, layout, :locals => options[:locals]) end when :update @@ -92,13 +91,12 @@ module ActionView _render_template(template, layout, options) end - def _find_layout(template, layout) + def _find_layout(layout) begin - prefix = "layouts" unless layout =~ /\blayouts/ - layout = find(layout, prefix) + find(layout) rescue ActionView::MissingTemplate => e update_details(:formats => nil) do - raise unless template_lookup.exists?(layout, prefix) + raise unless template_lookup.exists?(layout) end end end @@ -107,7 +105,7 @@ module ActionView self.formats = template.details[:formats] locals = options[:locals] || {} - layout = _find_layout(template, layout) if layout.is_a?(String) + layout = _find_layout(layout) if layout ActiveSupport::Notifications.instrument("action_view.render_template", :identifier => template.identifier, :layout => layout.try(:identifier)) do -- cgit v1.2.3 From 34b2180451f842b180dd925bab10e8f4afa34490 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Mon, 8 Mar 2010 03:23:16 +0100 Subject: More refactoring. Split _normalize_args and _normalize_options concerns. --- actionpack/lib/abstract_controller/layouts.rb | 8 ++++++-- actionpack/lib/abstract_controller/rendering.rb | 12 ++++++++---- actionpack/lib/action_controller/metal/rendering.rb | 19 +++++++++++++------ 3 files changed, 27 insertions(+), 12 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/abstract_controller/layouts.rb b/actionpack/lib/abstract_controller/layouts.rb index c6a94c5220..648a2da795 100644 --- a/actionpack/lib/abstract_controller/layouts.rb +++ b/actionpack/lib/abstract_controller/layouts.rb @@ -277,8 +277,8 @@ module AbstractController end end - def render_to_body(options={}) - if (options.keys & [:text, :inline, :partial]).empty? || options.key?(:layout) + def render_to_body(options) + if _include_layout?(options) layout = options.key?(:layout) ? options[:layout] : :default value = _layout_for_option(layout) @@ -344,6 +344,10 @@ module AbstractController layout_name end + def _include_layout?(options) + (options.keys & [:text, :inline, :partial]).empty? || options.key?(:layout) + end + def _action_has_layout? true end diff --git a/actionpack/lib/abstract_controller/rendering.rb b/actionpack/lib/abstract_controller/rendering.rb index 8125badc75..9093e90c97 100644 --- a/actionpack/lib/abstract_controller/rendering.rb +++ b/actionpack/lib/abstract_controller/rendering.rb @@ -45,7 +45,8 @@ 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) - options = _normalize_options(*args, &block) + options = _normalize_args(*args, &block) + _normalize_options(options) self.response_body = render_to_body(options) end @@ -70,8 +71,8 @@ module AbstractController # render_to_body into a String. # # :api: plugin - def render_to_string(*args) - options = _normalize_options(*args) + def render_to_string(options={}) + _normalize_options(options) AbstractController::Rendering.body_to_s(render_to_body(options)) end @@ -131,7 +132,7 @@ module AbstractController # Normalize options, by converting render "foo" to render :template => "prefix/foo" # and render "/foo" to render :file => "/foo". - def _normalize_options(action=nil, options={}) + def _normalize_args(action=nil, options={}) case action when Hash options, action = action, nil @@ -151,6 +152,9 @@ module AbstractController options end + def _normalize_options(options) + end + # Take in a set of options and determine the template to render # # ==== Options diff --git a/actionpack/lib/action_controller/metal/rendering.rb b/actionpack/lib/action_controller/metal/rendering.rb index e2d2e2312b..60d61999de 100644 --- a/actionpack/lib/action_controller/metal/rendering.rb +++ b/actionpack/lib/action_controller/metal/rendering.rb @@ -18,6 +18,11 @@ module ActionController response_body end + def render_to_body(options) + _process_options(options) + super + end + private def _render_partial(options) @@ -30,7 +35,7 @@ module ActionController formats.first end - def _normalize_options(action=nil, options={}, &blk) + def _normalize_args(action=nil, options={}, &blk) case action when NilClass when Hash @@ -38,9 +43,14 @@ module ActionController when String, Symbol options = super else - options.merge! :partial => action + options.merge!(:partial => action) end + options[:update] = blk if block_given? + options + end + + def _normalize_options(options) if options.key?(:text) && options[:text].respond_to?(:to_text) options[:text] = options[:text].to_text end @@ -49,10 +59,7 @@ module ActionController options[:status] = Rack::Utils.status_code(options[:status]) end - options[:update] = blk if block_given? - - _process_options(options) - options + super end def _process_options(options) -- cgit v1.2.3 From 54a69c31edd240c8ed06d12be7b065153f44529f Mon Sep 17 00:00:00 2001 From: wycats Date: Sun, 7 Mar 2010 21:27:25 -0800 Subject: Typo in config.action_dispatch --- actionpack/lib/action_controller/deprecated/base.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/deprecated/base.rb b/actionpack/lib/action_controller/deprecated/base.rb index 34f8f4a822..1d05b3fbd6 100644 --- a/actionpack/lib/action_controller/deprecated/base.rb +++ b/actionpack/lib/action_controller/deprecated/base.rb @@ -57,7 +57,7 @@ module ActionController def ip_spoofing_check=(value) ActiveSupport::Deprecation.warn "ActionController::Base.ip_spoofing_check= is deprecated. " << "Please configure it on your application with config.action_dispatch.ip_spoofing_check=", caller - Rails.application.config.action_disaptch.ip_spoofing_check = value + Rails.application.config.action_dispatch.ip_spoofing_check = value end def ip_spoofing_check -- cgit v1.2.3 From 0a85380966e47a38292242e6c3b259d77c738ab5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Mon, 8 Mar 2010 11:32:01 +0100 Subject: Finally moved the find template logic to the views. --- actionpack/lib/abstract_controller/layouts.rb | 7 +- actionpack/lib/abstract_controller/rendering.rb | 232 +++++++++------------ .../lib/action_controller/metal/compatibility.rb | 11 +- .../lib/action_controller/metal/implicit_render.rb | 2 +- .../lib/action_controller/metal/rendering.rb | 41 ++-- actionpack/lib/action_view/render/rendering.rb | 40 ++-- actionpack/lib/action_view/template/text.rb | 7 +- .../test/abstract/abstract_controller_test.rb | 4 +- 8 files changed, 152 insertions(+), 192 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/abstract_controller/layouts.rb b/actionpack/lib/abstract_controller/layouts.rb index 648a2da795..6ac3806149 100644 --- a/actionpack/lib/abstract_controller/layouts.rb +++ b/actionpack/lib/abstract_controller/layouts.rb @@ -264,7 +264,7 @@ module AbstractController self.class_eval <<-RUBY, __FILE__, __LINE__ + 1 def _layout - if template_exists?("#{_implied_layout_name}", :_prefix => #{_prefix.inspect}) + if template_exists?("#{_implied_layout_name}", #{_prefix.inspect}) "#{_implied_layout_name}" else super @@ -277,7 +277,9 @@ module AbstractController end end - def render_to_body(options) + def _normalize_options(options) + super + if _include_layout?(options) layout = options.key?(:layout) ? options[:layout] : :default value = _layout_for_option(layout) @@ -288,7 +290,6 @@ module AbstractController # TODO Revisit this. :layout with :partial from controllers are not the same as in views options[:layout] = view_context._find_layout(options[:layout]) if options.key?(:partial) end - super end private diff --git a/actionpack/lib/abstract_controller/rendering.rb b/actionpack/lib/abstract_controller/rendering.rb index 9093e90c97..d9087ce294 100644 --- a/actionpack/lib/abstract_controller/rendering.rb +++ b/actionpack/lib/abstract_controller/rendering.rb @@ -10,7 +10,7 @@ module AbstractController end end - module Rendering + module ViewPaths extend ActiveSupport::Concern included do @@ -21,21 +21,87 @@ module AbstractController delegate :formats, :formats=, :to => :template_lookup delegate :_view_paths, :to => :'self.class' + def template_lookup + @template_lookup ||= ActionView::Template::Lookup.new(_view_paths, details_for_lookup) + end + + def details_for_lookup + { } + end + + # The list of view paths for this controller. See ActionView::ViewPathSet for + # more details about writing custom view paths. + def view_paths + template_lookup.view_paths + end + + def append_view_path(path) + template_lookup.view_paths.push(*path) + end + + def prepend_view_path(path) + template_lookup.view_paths.unshift(*path) + end + + protected + + def template_exists?(*args) + template_lookup.exists?(*args) + end + + def find_template(*args) + template_lookup.find(*args) + end + + module ClassMethods + # Append a path to the list of view paths for this controller. + # + # ==== Parameters + # path:: If a String is provided, it gets converted into + # the default view path. You may also provide a custom view path + # (see ActionView::ViewPathSet for more information) + def append_view_path(path) + self.view_paths = view_paths.dup + Array(path) + end + + # Prepend a path to the list of view paths for this controller. + # + # ==== Parameters + # path:: If a String is provided, it gets converted into + # the default view path. You may also provide a custom view path + # (see ActionView::ViewPathSet for more information) + def prepend_view_path(path) + self.view_paths = Array(path) + view_paths.dup + end + + # A list of all of the default view paths for this controller. + def view_paths + _view_paths + end + + # Set the view paths. + # + # ==== Parameters + # paths:: If a ViewPathSet is provided, use that; + # otherwise, process the parameter into a ViewPathSet. + def view_paths=(paths) + self._view_paths = paths.is_a?(ActionView::PathSet) ? paths : ActionView::Base.process_view_paths(paths) + self._view_paths.freeze + end + end + end + + module Rendering + extend ActiveSupport::Concern + include AbstractController::ViewPaths + # An instance of a view class. The default view class is ActionView::Base # # The view class must have the following methods: - # View.for_controller[controller] Create a new ActionView instance for a - # controller - # View#render_partial[options] - # - responsible for setting options[:_template] - # - Returns String with the rendered partial - # options:: see _render_partial in ActionView::Base - # View#render_template[template, layout, options, partial] - # - Returns String with the rendered template - # template:: The template to render - # layout:: The layout to render around the template - # options:: See _render_template_with_layout in ActionView::Base - # partial:: Whether or not the template to render is a partial + # View.for_controller[controller] + # Create a new ActionView instance for a controller + # View#render_template[options] + # Returns String with the rendered template # # Override this method in a module to change the default behavior. def view_context @@ -51,64 +117,23 @@ module AbstractController end # Raw rendering of a template to a Rack-compatible body. - # - # ==== Options - # _partial_object:: The object that is being rendered. If this - # exists, we are in the special case of rendering an object as a partial. - # # :api: plugin def render_to_body(options = {}) - # TODO: Refactor so we can just use the normal template logic for this - if options.key?(:partial) - _render_partial(options) - else - _determine_template(options) - _render_template(options) - end + _process_options(options) + _render_template(options) end # Raw rendering of a template to a string. Just convert the results of # render_to_body into a String. - # # :api: plugin def render_to_string(options={}) _normalize_options(options) AbstractController::Rendering.body_to_s(render_to_body(options)) end - # Renders the template from an object. - # - # ==== Options - # _template:: The template to render - # _layout:: The layout to wrap the template in (optional) + # Find and renders a template based on the options given. def _render_template(options) - view_context.render_template(options) - end - - # Renders the given partial. - # - # ==== Options - # partial:: The partial name or the object to be rendered - def _render_partial(options) - view_context.render_partial(options) - end - - def template_lookup - @template_lookup ||= ActionView::Template::Lookup.new(_view_paths, details_for_render) - end - - # The list of view paths for this controller. See ActionView::ViewPathSet for - # more details about writing custom view paths. - def view_paths - template_lookup.view_paths - end - - def append_view_path(path) - template_lookup.view_paths.push(*path) - end - - def prepend_view_path(path) - template_lookup.view_paths.unshift(*path) + view_context.render_template(options) { |template| _with_template_hook(template) } end # The prefix used in render "foo" shortcuts. @@ -134,59 +159,40 @@ module AbstractController # and render "/foo" to render :file => "/foo". def _normalize_args(action=nil, options={}) case action + when NilClass when Hash options, action = action, nil when String, Symbol action = action.to_s case action.index("/") when NilClass - options[:_prefix] = _prefix - options[:_template_name] = action + options[:action] = action when 0 options[:file] = action else options[:template] = action end + else + options.merge!(:partial => action) end options end def _normalize_options(options) - end + if options[:partial] == true + options[:partial] = action_name + end - # Take in a set of options and determine the template to render - # - # ==== Options - # _template:: If this is provided, the search is over - # _template_name<#to_s>:: The name of the template to look up. Otherwise, - # use the current action name. - # _prefix:: The prefix to look inside of. In a file system, this corresponds - # to a directory. - # _partial:: Whether or not the file to look up is a partial - def _determine_template(options) - if options.key?(:text) - options[:_template] = ActionView::Template::Text.new(options[:text], format_for_text) - elsif options.key?(:inline) - handler = ActionView::Template.handler_class_for_extension(options[:type] || "erb") - template = ActionView::Template.new(options[:inline], "inline template", handler, {}) - options[:_template] = template - elsif options.key?(:template) - options[:_template_name] = options[:template] - elsif options.key?(:file) - options[:_template_name] = options[:file] + if (options.keys & [:partial, :file, :template]).empty? + options[:_prefix] ||= _prefix end - name = (options[:_template_name] || options[:action] || action_name).to_s - options[:_prefix] ||= _prefix if (options.keys & [:partial, :file, :template]).empty? + + options[:template] ||= (options[:action] || action_name).to_s details = _normalize_details(options) template_lookup.details = details - - options[:_template] ||= find_template(name, options) - end - - def details_for_render - { } + options end def _normalize_details(options) @@ -196,53 +202,11 @@ module AbstractController details end - def find_template(name, options) - template_lookup.find(name, options[:_prefix], options[:_partial]) - end - - def template_exists?(name, options) - template_lookup.exists?(name, options[:_prefix], options[:_partial]) - end - - def format_for_text - Mime[:text] + def _process_options(options) end - module ClassMethods - # Append a path to the list of view paths for this controller. - # - # ==== Parameters - # path:: If a String is provided, it gets converted into - # the default view path. You may also provide a custom view path - # (see ActionView::ViewPathSet for more information) - def append_view_path(path) - self.view_paths = view_paths.dup + Array(path) - end - - # Prepend a path to the list of view paths for this controller. - # - # ==== Parameters - # path:: If a String is provided, it gets converted into - # the default view path. You may also provide a custom view path - # (see ActionView::ViewPathSet for more information) - def prepend_view_path(path) - self.view_paths = Array(path) + view_paths.dup - end - - # A list of all of the default view paths for this controller. - def view_paths - _view_paths - end - - # Set the view paths. - # - # ==== Parameters - # paths:: If a ViewPathSet is provided, use that; - # otherwise, process the parameter into a ViewPathSet. - def view_paths=(paths) - self._view_paths = paths.is_a?(ActionView::PathSet) ? paths : ActionView::Base.process_view_paths(paths) - self._view_paths.freeze - end + def _with_template_hook(template) + self.formats = template.details[:formats] end end end diff --git a/actionpack/lib/action_controller/metal/compatibility.rb b/actionpack/lib/action_controller/metal/compatibility.rb index 0cb20b2f0f..5cad0814ca 100644 --- a/actionpack/lib/action_controller/metal/compatibility.rb +++ b/actionpack/lib/action_controller/metal/compatibility.rb @@ -49,14 +49,19 @@ module ActionController super end - def render_to_body(options) - if options.is_a?(Hash) && options.key?(:template) - options[:template].sub!(/^\//, '') + def _normalize_options(options) + # TODO Deprecate this. Rails 2.x allowed to give a template as action. + if options[:action] && options[:action].to_s.include?(?/) + options[:template] = options.delete(:action) end options[:text] = nil if options.delete(:nothing) == true options[:text] = " " if options.key?(:text) && options[:text].nil? + super + end + def render_to_body(options) + options[:template].sub!(/^\//, '') if options.key?(:template) super || " " end diff --git a/actionpack/lib/action_controller/metal/implicit_render.rb b/actionpack/lib/action_controller/metal/implicit_render.rb index c3e3b8fdf5..282dcf66b3 100644 --- a/actionpack/lib/action_controller/metal/implicit_render.rb +++ b/actionpack/lib/action_controller/metal/implicit_render.rb @@ -12,7 +12,7 @@ module ActionController def method_for_action(action_name) super || begin - if template_exists?(action_name.to_s, :_prefix => controller_path) + if template_exists?(action_name.to_s, _prefix) "default_render" end end diff --git a/actionpack/lib/action_controller/metal/rendering.rb b/actionpack/lib/action_controller/metal/rendering.rb index 60d61999de..f892bd9b91 100644 --- a/actionpack/lib/action_controller/metal/rendering.rb +++ b/actionpack/lib/action_controller/metal/rendering.rb @@ -6,46 +6,20 @@ module ActionController include AbstractController::Rendering def process(*) - self.formats = request.formats.map {|x| x.to_sym } + self.formats = request.formats.map { |x| x.to_sym } super end def render(*args) raise ::AbstractController::DoubleRenderError if response_body - args << {} unless args.last.is_a?(Hash) - super(*args) - self.content_type ||= args.last[:_template].mime_type.to_s - response_body - end - - def render_to_body(options) - _process_options(options) super + response_body end private - def _render_partial(options) - options[:partial] = action_name if options[:partial] == true - options[:_details] = details_for_render - super - end - - def format_for_text - formats.first - end - def _normalize_args(action=nil, options={}, &blk) - case action - when NilClass - when Hash - options = super(action.delete(:action), action) - when String, Symbol - options = super - else - options.merge!(:partial => action) - end - + options = super options[:update] = blk if block_given? options end @@ -64,9 +38,18 @@ module ActionController def _process_options(options) status, content_type, location = options.values_at(:status, :content_type, :location) + self.status = status if status self.content_type = content_type if content_type self.headers["Location"] = url_for(location) if location + + super end + + def _with_template_hook(template) + super + self.content_type ||= template.mime_type.to_s + end + end end diff --git a/actionpack/lib/action_view/render/rendering.rb b/actionpack/lib/action_view/render/rendering.rb index 17fb110eb4..c6d95e88e2 100644 --- a/actionpack/lib/action_view/render/rendering.rb +++ b/actionpack/lib/action_view/render/rendering.rb @@ -24,18 +24,8 @@ module ActionView return _render_partial(options) end - template = if options[:file] - find(options[:file]) - elsif options[:inline] - handler = Template.handler_class_for_extension(options[:type] || "erb") - Template.new(options[:inline], "inline template", handler, {}) - elsif options[:text] - Template::Text.new(options[:text]) - end - - if template - _render_template(template, layout, :locals => options[:locals]) - end + template = _determine_template(options) + _render_template(template, layout, :locals => options[:locals]) if template when :update update_page(&block) else @@ -87,8 +77,28 @@ module ActionView # _layout:: The layout, if any, to wrap the Template in def render_template(options) _evaluate_assigns_and_ivars - template, layout = options.values_at(:_template, :layout) - _render_template(template, layout, options) + if options.key?(:partial) + _render_partial(options) + else + template = _determine_template(options) + yield template if block_given? + _render_template(template, options[:layout], options) + end + end + + def _determine_template(options) + if options.key?(:inline) + handler = Template.handler_class_for_extension(options[:type] || "erb") + Template.new(options[:inline], "inline template", handler, {}) + elsif options.key?(:text) + Template::Text.new(options[:text], self.formats.try(:first)) + elsif options.key?(:_template) + options[:_template] + elsif options.key?(:file) + find(options[:file], options[:_prefix]) + elsif options.key?(:template) + find(options[:template], options[:_prefix]) + end end def _find_layout(layout) @@ -102,8 +112,6 @@ module ActionView end def _render_template(template, layout = nil, options = {}) - self.formats = template.details[:formats] - locals = options[:locals] || {} layout = _find_layout(layout) if layout diff --git a/actionpack/lib/action_view/template/text.rb b/actionpack/lib/action_view/template/text.rb index 2abb352d4e..5978a8a3ac 100644 --- a/actionpack/lib/action_view/template/text.rb +++ b/actionpack/lib/action_view/template/text.rb @@ -1,11 +1,10 @@ module ActionView #:nodoc: class Template class Text < String #:nodoc: - HTML = Mime[:html] - - def initialize(string, content_type = HTML) + def initialize(string, content_type = nil) super(string.to_s) - @content_type = Mime[content_type] || content_type + @content_type = Mime[content_type] || content_type if content_type + @content_type ||= Mime::TEXT end def details diff --git a/actionpack/test/abstract/abstract_controller_test.rb b/actionpack/test/abstract/abstract_controller_test.rb index 4ad87d9762..f70d497481 100644 --- a/actionpack/test/abstract/abstract_controller_test.rb +++ b/actionpack/test/abstract/abstract_controller_test.rb @@ -59,11 +59,11 @@ module AbstractController end def rendering_to_body - self.response_body = render_to_body :_template_name => "naked_render.erb" + self.response_body = render_to_body :template => "naked_render.erb" end def rendering_to_string - self.response_body = render_to_string :_template_name => "naked_render.erb" + self.response_body = render_to_string :template => "naked_render.erb" end end -- cgit v1.2.3 From ea68fe59c670dd5580f3aa34fdfa0eb89eb717d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Mon, 8 Mar 2010 14:46:57 +0100 Subject: More refactoring on the views side of rendering. --- actionpack/lib/abstract_controller/layouts.rb | 9 +- actionpack/lib/action_view.rb | 1 + actionpack/lib/action_view/base.rb | 2 +- actionpack/lib/action_view/render/layouts.rb | 64 ++++++++++++++ actionpack/lib/action_view/render/partials.rb | 33 ++----- actionpack/lib/action_view/render/rendering.rb | 95 ++++++-------------- actionpack/test/abstract/layouts_test.rb | 116 ++++++++++++++++++------- actionpack/test/abstract/render_test.rb | 19 ---- 8 files changed, 185 insertions(+), 154 deletions(-) create mode 100644 actionpack/lib/action_view/render/layouts.rb (limited to 'actionpack') diff --git a/actionpack/lib/abstract_controller/layouts.rb b/actionpack/lib/abstract_controller/layouts.rb index 6ac3806149..2f9616124a 100644 --- a/actionpack/lib/abstract_controller/layouts.rb +++ b/actionpack/lib/abstract_controller/layouts.rb @@ -281,14 +281,9 @@ module AbstractController super if _include_layout?(options) - layout = options.key?(:layout) ? options[:layout] : :default + layout = options.key?(:layout) ? options.delete(:layout) : :default value = _layout_for_option(layout) - - # TODO Revisit this. Maybe we should pass a :layout_prefix? - options[:layout] = ((!value || value =~ /\blayouts/) ? value : "layouts/#{value}") - - # TODO Revisit this. :layout with :partial from controllers are not the same as in views - options[:layout] = view_context._find_layout(options[:layout]) if options.key?(:partial) + options[:layout] = (value =~ /\blayouts/ ? value : "layouts/#{value}") if value end end diff --git a/actionpack/lib/action_view.rb b/actionpack/lib/action_view.rb index f5035fe45a..f111950540 100644 --- a/actionpack/lib/action_view.rb +++ b/actionpack/lib/action_view.rb @@ -37,6 +37,7 @@ module ActionView autoload :Helpers autoload_under "render" do + autoload :Layouts autoload :Partials autoload :Rendering end diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index 5acd2a8b82..656d73e32d 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -173,7 +173,7 @@ module ActionView #:nodoc: module Subclasses end - include Helpers, Rendering, Partials, ::ERB::Util + include Helpers, Rendering, Partials, Layouts, ::ERB::Util extend ActiveSupport::Memoizable diff --git a/actionpack/lib/action_view/render/layouts.rb b/actionpack/lib/action_view/render/layouts.rb new file mode 100644 index 0000000000..e1dbd3c120 --- /dev/null +++ b/actionpack/lib/action_view/render/layouts.rb @@ -0,0 +1,64 @@ +require 'active_support/core_ext/object/try' + +module ActionView + module Layouts + + # You can think of a layout as a method that is called with a block. _layout_for + # returns the contents that are yielded to the layout. If the user calls yield + # :some_name, the block, by default, returns content_for(:some_name). If the user + # calls yield, the default block returns content_for(:layout). + # + # The user can override this default by passing a block to the layout. + # + # ==== Example + # + # # The template + # <% render :layout => "my_layout" do %>Content<% end %> + # + # # The layout + # <% yield %> + # + # In this case, instead of the default block, which would return content_for(:layout), + # this method returns the block that was passed in to render layout, and the response + # would be Content. + # + # Finally, the block can take block arguments, which can be passed in by yield. + # + # ==== Example + # + # # The template + # <% render :layout => "my_layout" do |customer| %>Hello <%= customer.name %><% end %> + # + # # The layout + # <% yield Struct.new(:name).new("David") %> + # + # In this case, the layout would receive the block passed into render :layout, + # and the Struct specified in the layout would be passed into the block. The result + # would be Hello David. + def _layout_for(name = nil, &block) #:nodoc: + if !block || name + @_content_for[name || :layout] + else + capture(&block) + end + end + + # This is the method which actually finds the layout using details in the lookup + # context object. If no layout is found, it checkes if at least a layout with + # the given name exists across all details before raising the error. + def _find_layout(layout) #:nodoc: + begin + find(layout) + rescue ActionView::MissingTemplate => e + update_details(:formats => nil) do + raise unless template_lookup.exists?(layout) + end + end + end + + # Contains the logic that actually renders the layout. + def _render_layout(layout, locals, &block) #:nodoc: + layout.render(self, locals){ |*name| _layout_for(*name, &block) } + end + end +end diff --git a/actionpack/lib/action_view/render/partials.rb b/actionpack/lib/action_view/render/partials.rb index eecc88a1e0..950c9d2cd8 100644 --- a/actionpack/lib/action_view/render/partials.rb +++ b/actionpack/lib/action_view/render/partials.rb @@ -174,9 +174,6 @@ module ActionView class PartialRenderer PARTIAL_NAMES = Hash.new {|h,k| h[k] = {} } - TEMPLATES = Hash.new {|h,k| h[k] = {} } - - attr_reader :template def initialize(view_context, options, block) @view = view_context @@ -225,6 +222,7 @@ module ActionView if !@block && (layout = @options[:layout]) content = @view._render_layout(find_template(layout), @locals){ content } end + content end end @@ -241,9 +239,9 @@ module ActionView end def collection_with_template(template = @template) - segments, locals, as = [], @locals, @options[:as] || template.variable_name + segments, locals, as, template = [], @locals, @options[:as] || @template.variable_name, @template - counter_name = template.counter_name + counter_name = template.counter_name locals[counter_name] = -1 @collection.each do |object| @@ -253,7 +251,6 @@ module ActionView segments << template.render(@view, locals) end - @template = template segments end @@ -274,7 +271,7 @@ module ActionView end def render_partial(object = @object) - locals, view = @locals, @view + locals, view, template = @locals, @view, @template object ||= locals[template.variable_name] locals[@options[:as] || template.variable_name] = object @@ -285,6 +282,7 @@ module ActionView end private + def collection if @object.respond_to?(:to_ary) @object @@ -295,11 +293,7 @@ module ActionView def find_template(path=@path) return path unless path.is_a?(String) - - if controller = @view.controller - prefix = controller.controller_path unless path.include?(?/) - end - + prefix = @view.controller_path unless path.include?(?/) @view.find(path, prefix, true) end @@ -315,21 +309,8 @@ module ActionView end end - def render_partial(options) - _evaluate_assigns_and_ivars - - details = options[:_details] - - # TODO This should happen automatically as well - self.formats = details[:formats] if details[:formats] - renderer = PartialRenderer.new(self, options, nil) - text = renderer.render - options[:_template] = renderer.template - text - end - def _render_partial(options, &block) #:nodoc: - if defined? @renderer + if defined?(@renderer) @renderer.setup(options, block) else @renderer = PartialRenderer.new(self, options, block) diff --git a/actionpack/lib/action_view/render/rendering.rb b/actionpack/lib/action_view/render/rendering.rb index c6d95e88e2..61fea6f49e 100644 --- a/actionpack/lib/action_view/render/rendering.rb +++ b/actionpack/lib/action_view/render/rendering.rb @@ -15,17 +15,12 @@ module ActionView def render(options = {}, locals = {}, &block) #:nodoc: case options when Hash - layout = options[:layout] - options[:locals] ||= {} - if block_given? - return safe_concat(_render_partial(options.merge(:partial => layout), &block)) - elsif options.key?(:partial) - return _render_partial(options) + content = _render_partial(options.merge(:partial => options[:layout]), &block) + safe_concat(content) + else + _render(options) end - - template = _determine_template(options) - _render_template(template, layout, :locals => options[:locals]) if template when :update update_page(&block) else @@ -33,50 +28,24 @@ module ActionView end end - # You can think of a layout as a method that is called with a block. _layout_for - # returns the contents that are yielded to the layout. If the user calls yield - # :some_name, the block, by default, returns content_for(:some_name). If the user - # calls yield, the default block returns content_for(:layout). - # - # The user can override this default by passing a block to the layout. - # - # ==== Example - # - # # The template - # <% render :layout => "my_layout" do %>Content<% end %> - # - # # The layout - # <% yield %> - # - # In this case, instead of the default block, which would return content_for(:layout), - # this method returns the block that was passed in to render layout, and the response - # would be Content. - # - # Finally, the block can take block arguments, which can be passed in by yield. - # - # ==== Example - # - # # The template - # <% render :layout => "my_layout" do |customer| %>Hello <%= customer.name %><% end %> - # - # # The layout - # <% yield Struct.new(:name).new("David") %> - # - # In this case, the layout would receive the block passed into render :layout, - # and the Struct specified in the layout would be passed into the block. The result - # would be Hello David. - def _layout_for(name = nil, &block) - return @_content_for[name || :layout] if !block_given? || name - capture(&block) - end - # This is the API to render a ViewContext's template from a controller. - # - # Internal Options: - # _template:: The Template object to render - # _layout:: The layout, if any, to wrap the Template in - def render_template(options) + # TODO Review this name since it does not render only templates, but also + # partials, files and so forth. + def render_template(options, &block) _evaluate_assigns_and_ivars + + # TODO Layout for partials should be handled here, because inside the + # partial renderer it looks for the layout as a partial. + if options.key?(:partial) && options[:layout] + options[:layout] = _find_layout(options[:layout]) + end + + _render(options, &block) + end + + # This method holds the common render logic for both controllers and + # views rendering stacks. + def _render(options) #:nodoc: if options.key?(:partial) _render_partial(options) else @@ -86,14 +55,13 @@ module ActionView end end - def _determine_template(options) + # Determine the template to be rendered using the given options. + def _determine_template(options) #:nodoc: if options.key?(:inline) handler = Template.handler_class_for_extension(options[:type] || "erb") Template.new(options[:inline], "inline template", handler, {}) elsif options.key?(:text) Template::Text.new(options[:text], self.formats.try(:first)) - elsif options.key?(:_template) - options[:_template] elsif options.key?(:file) find(options[:file], options[:_prefix]) elsif options.key?(:template) @@ -101,24 +69,16 @@ module ActionView end end - def _find_layout(layout) - begin - find(layout) - rescue ActionView::MissingTemplate => e - update_details(:formats => nil) do - raise unless template_lookup.exists?(layout) - end - end - end - - def _render_template(template, layout = nil, options = {}) + # Renders the given template. An string representing the layout can be + # supplied as well. + def _render_template(template, layout = nil, options = {}) #:nodoc: locals = options[:locals] || {} layout = _find_layout(layout) if layout ActiveSupport::Notifications.instrument("action_view.render_template", :identifier => template.identifier, :layout => layout.try(:identifier)) do - content = template.render(self, locals) {|*name| _layout_for(*name) } + content = template.render(self, locals) { |*name| _layout_for(*name) } @_content_for[:layout] = content if layout @@ -130,8 +90,5 @@ module ActionView end end - def _render_layout(layout, locals, &block) - layout.render(self, locals){ |*name| _layout_for(*name, &block) } - end end end diff --git a/actionpack/test/abstract/layouts_test.rb b/actionpack/test/abstract/layouts_test.rb index fcc91d03f1..65a50807fd 100644 --- a/actionpack/test/abstract/layouts_test.rb +++ b/actionpack/test/abstract/layouts_test.rb @@ -8,41 +8,52 @@ module AbstractControllerTests include AbstractController::Rendering include AbstractController::Layouts + def _prefix + "template" + end + self.view_paths = [ActionView::FixtureResolver.new( - "layouts/hello.erb" => "With String <%= yield %>", - "layouts/hello_override.erb" => "With Override <%= yield %>", "abstract_controller_tests/layouts/with_string_implied_child.erb" => - "With Implied <%= yield %>", - "layouts/overwrite.erb" => "Overwrite <%= yield %>", - "layouts/with_false_layout.erb" => "False Layout <%= yield %>" + "With Implied <%= yield %>", + "layouts/hello.erb" => "With String <%= yield %>", + "layouts/hello_override.erb" => "With Override <%= yield %>", + "layouts/overwrite.erb" => "Overwrite <%= yield %>", + "layouts/with_false_layout.erb" => "False Layout <%= yield %>" )] end class Blank < Base - self.view_paths = [] - + self.view_paths = ActionView::FixtureResolver.new("template/index.erb" => "Hello blank!") + def index - render :_template => ActionView::Template::Text.new("Hello blank!") + render end end class WithString < Base layout "hello" - + + append_view_path ActionView::FixtureResolver.new( + "template/index.erb" => "Hello string!", + "template/overwrite_default.erb" => "Hello string!", + "template/overwrite_false.erb" => "Hello string!", + "template/overwrite_string.erb" => "Hello string!" + ) + def index - render :_template => ActionView::Template::Text.new("Hello string!") + render end def overwrite_default - render :_template => ActionView::Template::Text.new("Hello string!"), :layout => :default + render :layout => :default end def overwrite_false - render :_template => ActionView::Template::Text.new("Hello string!"), :layout => false + render :layout => false end def overwrite_string - render :_template => ActionView::Template::Text.new("Hello string!"), :layout => "overwrite" + render :layout => "overwrite" end def overwrite_skip @@ -70,18 +81,28 @@ module AbstractControllerTests class WithProc < Base layout proc { |c| "overwrite" } + append_view_path ActionView::FixtureResolver.new( + "template/index.erb" => "Hello proc!" + ) + def index - render :_template => ActionView::Template::Text.new("Hello proc!") + render end end class WithSymbol < Base layout :hello - + + append_view_path ActionView::FixtureResolver.new( + "template/index.erb" => "Hello symbol!" + ) + def index - render :_template => ActionView::Template::Text.new("Hello symbol!") + render end - private + + private + def hello "overwrite" end @@ -89,11 +110,17 @@ module AbstractControllerTests class WithSymbolReturningString < Base layout :no_hello - + + append_view_path ActionView::FixtureResolver.new( + "template/index.erb" => "Hello missing symbol!" + ) + def index - render :_template => ActionView::Template::Text.new("Hello missing symbol!") + render end - private + + private + def no_hello nil end @@ -101,19 +128,28 @@ module AbstractControllerTests class WithSymbolReturningNil < Base layout :nilz - + + append_view_path ActionView::FixtureResolver.new( + "template/index.erb" => "Hello nilz!" + ) + def index - render :_template => ActionView::Template::Text.new("Hello nilz!") + render end - def nilz() end + def nilz + end end class WithSymbolReturningObj < Base layout :objekt - + + append_view_path ActionView::FixtureResolver.new( + "template/index.erb" => "Hello object!" + ) + def index - render :_template => ActionView::Template::Text.new("Hello nilz!") + render end def objekt @@ -123,33 +159,49 @@ module AbstractControllerTests class WithSymbolAndNoMethod < Base layout :no_method - + + append_view_path ActionView::FixtureResolver.new( + "template/index.erb" => "Hello boom!" + ) + def index - render :_template => ActionView::Template::Text.new("Hello boom!") + render end end class WithMissingLayout < Base layout "missing" - + + append_view_path ActionView::FixtureResolver.new( + "template/index.erb" => "Hello missing!" + ) + def index - render :_template => ActionView::Template::Text.new("Hello missing!") + render end end class WithFalseLayout < Base layout false - + + append_view_path ActionView::FixtureResolver.new( + "template/index.erb" => "Hello false!" + ) + def index - render :_template => ActionView::Template::Text.new("Hello false!") + render end end class WithNilLayout < Base layout nil + + append_view_path ActionView::FixtureResolver.new( + "template/index.erb" => "Hello nil!" + ) def index - render :_template => ActionView::Template::Text.new("Hello nil!") + render end end diff --git a/actionpack/test/abstract/render_test.rb b/actionpack/test/abstract/render_test.rb index db924633ca..e54d056666 100644 --- a/actionpack/test/abstract/render_test.rb +++ b/actionpack/test/abstract/render_test.rb @@ -15,7 +15,6 @@ module AbstractController "renderer/default.erb" => "With Default", "renderer/string.erb" => "With String", "renderer/symbol.erb" => "With Symbol", - "renderer/template_name.erb" => "With Template Name", "string/with_path.erb" => "With String With Path", "some/file.erb" => "With File", "with_format.html.erb" => "With html format", @@ -56,14 +55,6 @@ module AbstractController render :symbol end - def template_name - render :_template_name => :template_name - end - - def object - render :_template => ActionView::Template::Text.new("With Object") - end - def with_html_format render :template => "with_format", :format => :html end @@ -127,16 +118,6 @@ module AbstractController assert_equal "With String With Path", @controller.response_body end - def test_render_template_name - @controller.process(:template_name) - assert_equal "With Template Name", @controller.response_body - end - - def test_render_object - @controller.process(:object) - assert_equal "With Object", @controller.response_body - end - def test_render_with_html_format @controller.process(:with_html_format) assert_equal "With html format", @controller.response_body -- cgit v1.2.3 From 44ebab96da0ab47cc45c64a6efdd2cbb80f9d042 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Mon, 8 Mar 2010 15:19:03 +0100 Subject: Rename Template::Lookup to LookupContext. --- actionpack/lib/abstract_controller/rendering.rb | 35 ++++------- actionpack/lib/action_view.rb | 1 + actionpack/lib/action_view/base.rb | 27 +++------ actionpack/lib/action_view/lookup_context.rb | 80 +++++++++++++++++++++++++ actionpack/lib/action_view/render/layouts.rb | 4 +- actionpack/lib/action_view/render/partials.rb | 2 +- actionpack/lib/action_view/render/rendering.rb | 4 +- actionpack/lib/action_view/template.rb | 1 - actionpack/lib/action_view/template/lookup.rb | 56 ----------------- 9 files changed, 105 insertions(+), 105 deletions(-) create mode 100644 actionpack/lib/action_view/lookup_context.rb delete mode 100644 actionpack/lib/action_view/template/lookup.rb (limited to 'actionpack') diff --git a/actionpack/lib/abstract_controller/rendering.rb b/actionpack/lib/abstract_controller/rendering.rb index d9087ce294..356f1ec7f6 100644 --- a/actionpack/lib/abstract_controller/rendering.rb +++ b/actionpack/lib/abstract_controller/rendering.rb @@ -18,39 +18,26 @@ module AbstractController self._view_paths = ActionView::PathSet.new end - delegate :formats, :formats=, :to => :template_lookup - delegate :_view_paths, :to => :'self.class' + delegate :find_template, :template_exists?, + :view_paths, :formats, :formats=, :to => :lookup_context - def template_lookup - @template_lookup ||= ActionView::Template::Lookup.new(_view_paths, details_for_lookup) + # LookupContext is the object responsible to hold all information required to lookup + # templates, i.e. view paths and details. Check ActionView::LookupContext for more + # information. + def lookup_context + @lookup_context ||= ActionView::LookupContext.new(self.class._view_paths, details_for_lookup) end def details_for_lookup { } end - # The list of view paths for this controller. See ActionView::ViewPathSet for - # more details about writing custom view paths. - def view_paths - template_lookup.view_paths - end - def append_view_path(path) - template_lookup.view_paths.push(*path) + lookup_context.view_paths.push(*path) end def prepend_view_path(path) - template_lookup.view_paths.unshift(*path) - end - - protected - - def template_exists?(*args) - template_lookup.exists?(*args) - end - - def find_template(*args) - template_lookup.find(*args) + lookup_context.view_paths.unshift(*path) end module ClassMethods @@ -191,12 +178,12 @@ module AbstractController options[:template] ||= (options[:action] || action_name).to_s details = _normalize_details(options) - template_lookup.details = details + lookup_context.update_details(details) options end def _normalize_details(options) - details = template_lookup.details + details = {} details[:formats] = Array(options[:format]) if options[:format] details[:locale] = Array(options[:locale]) if options[:locale] details diff --git a/actionpack/lib/action_view.rb b/actionpack/lib/action_view.rb index f111950540..c37cea824a 100644 --- a/actionpack/lib/action_view.rb +++ b/actionpack/lib/action_view.rb @@ -42,6 +42,7 @@ module ActionView autoload :Rendering end + autoload :LookupContext, 'action_view/lookup_context' autoload :MissingTemplate, 'action_view/base' autoload :Resolver, 'action_view/template/resolver' autoload :PathResolver, 'action_view/template/resolver' diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index 656d73e32d..d18f524060 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -242,12 +242,11 @@ module ActionView #:nodoc: klass = self end - klass.new(controller.template_lookup, {}, controller) + klass.new(controller.lookup_context, {}, controller) end - def initialize(template_lookup = nil, assigns_for_first_render = {}, controller = nil, formats = nil) #:nodoc: + def initialize(lookup_context = nil, assigns_for_first_render = {}, controller = nil, formats = nil) #:nodoc: @config = nil - @formats = formats @assigns = assigns_for_first_render.each { |key, value| instance_variable_set("@#{key}", value) } @helpers = self.class.helpers || Module.new @@ -256,27 +255,17 @@ module ActionView #:nodoc: @_content_for = Hash.new { |h,k| h[k] = ActiveSupport::SafeBuffer.new } @_virtual_path = nil - @template_lookup = template_lookup.is_a?(ActionView::Template::Lookup) ? - template_lookup : ActionView::Template::Lookup.new(template_lookup) + @lookup_context = lookup_context.is_a?(ActionView::LookupContext) ? + lookup_context : ActionView::LookupContext.new(lookup_context) + @lookup_context.formats = formats if formats end attr_internal :controller, :template, :config - attr_reader :template_lookup - delegate :find, :formats, :formats=, :view_paths, :view_paths=, :to => :template_lookup + attr_reader :lookup_context - def update_details(details) - old_details = template_lookup.details - template_lookup.details = old_details.merge(details) - - if block_given? - begin - yield - ensure - template_lookup.details = old_details - end - end - end + delegate :find_template, :template_exists?, :formats, :formats=, + :view_paths, :view_paths=, :update_details, :to => :lookup_context def punctuate_body!(part) flush_output_buffer diff --git a/actionpack/lib/action_view/lookup_context.rb b/actionpack/lib/action_view/lookup_context.rb new file mode 100644 index 0000000000..82aebe1678 --- /dev/null +++ b/actionpack/lib/action_view/lookup_context.rb @@ -0,0 +1,80 @@ +module ActionView + # LookupContext is the object responsible to hold all information required to lookup + # templates, i.e. view paths and details. The LookupContext is also responsible to + # generate a key, given to view paths, used in the resolver cache lookup. Since + # this key is generated just once during the request, it speeds up all cache accesses. + class LookupContext #:nodoc: + attr_reader :details, :view_paths + + class DetailsKey #:nodoc: + attr_reader :details + alias :eql? :equal? + + @details_keys = Hash.new + + def self.get(details) + @details_keys[details] ||= new(details) + end + + def initialize(details) + @details, @hash = details, details.hash + end + end + + def initialize(view_paths, details = {}) + @details, @details_key = details, nil + self.view_paths = view_paths + end + + # Shortcut to read formats from details. + def formats + @details[:formats] + end + + # Shortcut to set formats in details. + def formats=(value) + self.details = @details.merge(:formats => Array(value)) + end + + # Whenever setting view paths, makes a copy so we can manipulate then in + # instance objects as we wish. + def view_paths=(paths) + @view_paths = ActionView::Base.process_view_paths(paths) + end + + # Setter for details. Everything this method is invoked, we need to nullify + # the details key if it changed. + def details=(details) + @details = details + @details_key = nil if @details_key && @details_key.details != details + end + + def details_key + @details_key ||= DetailsKey.get(details) unless details.empty? + 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 + self.details = old_details.merge(new_details) + + if block_given? + begin + yield + ensure + self.details = old_details + end + end + end + + def find_template(name, prefix = nil, partial = false) + @view_paths.find(name, details, prefix, partial || false, details_key) + end + + def template_exists?(name, prefix = nil, partial = false) + @view_paths.exists?(name, details, prefix, partial || false, details_key) + end + end +end \ No newline at end of file diff --git a/actionpack/lib/action_view/render/layouts.rb b/actionpack/lib/action_view/render/layouts.rb index e1dbd3c120..b9c63e0090 100644 --- a/actionpack/lib/action_view/render/layouts.rb +++ b/actionpack/lib/action_view/render/layouts.rb @@ -48,10 +48,10 @@ module ActionView # the given name exists across all details before raising the error. def _find_layout(layout) #:nodoc: begin - find(layout) + find_template(layout) rescue ActionView::MissingTemplate => e update_details(:formats => nil) do - raise unless template_lookup.exists?(layout) + raise unless template_exists?(layout) end end end diff --git a/actionpack/lib/action_view/render/partials.rb b/actionpack/lib/action_view/render/partials.rb index 950c9d2cd8..0fe2d560f7 100644 --- a/actionpack/lib/action_view/render/partials.rb +++ b/actionpack/lib/action_view/render/partials.rb @@ -294,7 +294,7 @@ module ActionView def find_template(path=@path) return path unless path.is_a?(String) prefix = @view.controller_path unless path.include?(?/) - @view.find(path, prefix, true) + @view.find_template(path, prefix, true) end def partial_path(object = @object) diff --git a/actionpack/lib/action_view/render/rendering.rb b/actionpack/lib/action_view/render/rendering.rb index 61fea6f49e..96c0b4fe6a 100644 --- a/actionpack/lib/action_view/render/rendering.rb +++ b/actionpack/lib/action_view/render/rendering.rb @@ -63,9 +63,9 @@ module ActionView elsif options.key?(:text) Template::Text.new(options[:text], self.formats.try(:first)) elsif options.key?(:file) - find(options[:file], options[:_prefix]) + find_template(options[:file], options[:_prefix]) elsif options.key?(:template) - find(options[:template], options[:_prefix]) + find_template(options[:template], options[:_prefix]) end end diff --git a/actionpack/lib/action_view/template.rb b/actionpack/lib/action_view/template.rb index c176359253..cd6b1930a1 100644 --- a/actionpack/lib/action_view/template.rb +++ b/actionpack/lib/action_view/template.rb @@ -13,7 +13,6 @@ module ActionView autoload :Handler autoload :Handlers autoload :Text - autoload :Lookup end extend Template::Handlers diff --git a/actionpack/lib/action_view/template/lookup.rb b/actionpack/lib/action_view/template/lookup.rb deleted file mode 100644 index 30de093934..0000000000 --- a/actionpack/lib/action_view/template/lookup.rb +++ /dev/null @@ -1,56 +0,0 @@ -module ActionView - class Template - class Lookup - attr_reader :details, :view_paths - - class DetailsKey - attr_reader :details - alias :eql? :equal? - - @details_keys = Hash.new - - def self.get(details) - @details_keys[details] ||= new(details) - end - - def initialize(details) - @details, @hash = details, details.hash - end - end - - def initialize(view_paths, details = {}) - @details = details - self.view_paths = view_paths - end - - def formats - @details[:formats] - end - - def formats=(value) - self.details = @details.merge(:formats => Array(value)) - end - - def view_paths=(paths) - @view_paths = ActionView::Base.process_view_paths(paths) - end - - def details=(details) - @details = details - @details_key = nil if @details_key && @details_key.details != details - end - - def details_key - @details_key ||= DetailsKey.get(details) unless details.empty? - end - - def find(name, prefix = nil, partial = false) - @view_paths.find(name, details, prefix, partial || false, details_key) - end - - def exists?(name, prefix = nil, partial = false) - @view_paths.exists?(name, details, prefix, partial || false, details_key) - end - end - end -end \ No newline at end of file -- cgit v1.2.3 From 68cda695da27f57cae682d160a13dab4dacb1ef8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Mon, 8 Mar 2010 16:32:40 +0100 Subject: Speed up performance in resolvers by adding fallbacks just when required. --- actionpack/lib/abstract_controller/rendering.rb | 14 ++----- actionpack/lib/action_view/base.rb | 46 +++++++++------------- actionpack/lib/action_view/lookup_context.rb | 16 ++++++++ actionpack/lib/action_view/paths.rb | 2 +- actionpack/lib/action_view/render/layouts.rb | 3 +- actionpack/lib/action_view/render/rendering.rb | 2 +- actionpack/lib/action_view/template/resolver.rb | 31 ++++----------- .../test/template/compiled_templates_test.rb | 2 +- actionpack/test/template/render_test.rb | 6 +-- 9 files changed, 53 insertions(+), 69 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/abstract_controller/rendering.rb b/actionpack/lib/abstract_controller/rendering.rb index 356f1ec7f6..840f0b6c78 100644 --- a/actionpack/lib/abstract_controller/rendering.rb +++ b/actionpack/lib/abstract_controller/rendering.rb @@ -142,8 +142,8 @@ module AbstractController private - # Normalize options, by converting render "foo" to render :template => "prefix/foo" - # and render "/foo" to render :file => "/foo". + # Normalize options by converting render "foo" to render :action => "foo" and + # render "foo/bar" to render :file => "foo/bar". def _normalize_args(action=nil, options={}) case action when NilClass @@ -151,14 +151,8 @@ module AbstractController options, action = action, nil when String, Symbol action = action.to_s - case action.index("/") - when NilClass - options[:action] = action - when 0 - options[:file] = action - else - options[:template] = action - end + key = action.include?(?/) ? :file : :action + options[key] = action else options.merge!(:partial => action) end diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index d18f524060..d2b77b2560 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -173,48 +173,41 @@ module ActionView #:nodoc: module Subclasses end - include Helpers, Rendering, Partials, Layouts, ::ERB::Util - - extend ActiveSupport::Memoizable - - attr_accessor :base_path, :assigns, :template_extension - attr_internal :captures - - class << self - delegate :erb_trim_mode=, :to => 'ActionView::Template::Handlers::ERB' - delegate :logger, :to => 'ActionController::Base', :allow_nil => true - end + include Helpers, Rendering, Partials, Layouts, ::ERB::Util, Context + extend ActiveSupport::Memoizable # Specify whether RJS responses should be wrapped in a try/catch block # that alert()s the caught exception (and then re-raises it). cattr_accessor :debug_rjs @@debug_rjs = false - # :nodoc: - def self.xss_safe? - true + class_attribute :helpers + attr_reader :helpers + + class << self + delegate :erb_trim_mode=, :to => 'ActionView::Template::Handlers::ERB' + delegate :logger, :to => 'ActionController::Base', :allow_nil => true end - attr_internal :request, :layout + attr_accessor :base_path, :assigns, :template_extension, :lookup_context + attr_internal :captures, :request, :layout, :controller, :template, :config - def controller_path - @controller_path ||= controller && controller.controller_path - end + delegate :find_template, :template_exists?, :formats, :formats=, + :view_paths, :view_paths=, :with_fallbacks, :update_details, :to => :lookup_context delegate :request_forgery_protection_token, :template, :params, :session, :cookies, :response, :headers, :flash, :action_name, :controller_name, :to => :controller delegate :logger, :to => :controller, :allow_nil => true - include Context + def self.xss_safe? #:nodoc: + true + end def self.process_view_paths(value) ActionView::PathSet.new(Array(value)) end - class_attribute :helpers - attr_reader :helpers - def self.for_controller(controller) @views ||= {} @@ -260,12 +253,9 @@ module ActionView #:nodoc: @lookup_context.formats = formats if formats end - attr_internal :controller, :template, :config - - attr_reader :lookup_context - - delegate :find_template, :template_exists?, :formats, :formats=, - :view_paths, :view_paths=, :update_details, :to => :lookup_context + def controller_path + @controller_path ||= controller && controller.controller_path + end def punctuate_body!(part) flush_output_buffer diff --git a/actionpack/lib/action_view/lookup_context.rb b/actionpack/lib/action_view/lookup_context.rb index 82aebe1678..e259a78c5c 100644 --- a/actionpack/lib/action_view/lookup_context.rb +++ b/actionpack/lib/action_view/lookup_context.rb @@ -6,6 +6,9 @@ module ActionView class LookupContext #:nodoc: attr_reader :details, :view_paths + mattr_accessor :fallbacks + @@fallbacks = [FileSystemResolver.new(""), FileSystemResolver.new("/")] + class DetailsKey #:nodoc: attr_reader :details alias :eql? :equal? @@ -69,6 +72,19 @@ module ActionView end end + # Added fallbacks to the view paths. Useful in cases you are rendering a file. + def with_fallbacks + added_resolvers = 0 + self.class.fallbacks.each do |resolver| + next if view_paths.include?(resolver) + view_paths.push(resolver) + added_resolvers += 1 + end + yield + ensure + added_resolvers.times { view_paths.pop } + end + def find_template(name, prefix = nil, partial = false) @view_paths.find(name, details, prefix, partial || false, details_key) end diff --git a/actionpack/lib/action_view/paths.rb b/actionpack/lib/action_view/paths.rb index 154a79a8f1..628546e443 100644 --- a/actionpack/lib/action_view/paths.rb +++ b/actionpack/lib/action_view/paths.rb @@ -33,7 +33,7 @@ module ActionView #:nodoc: def typecast! each_with_index do |path, i| next unless path.is_a?(String) - self[i] = FileSystemResolverWithFallback.new(path) + self[i] = FileSystemResolver.new(path) end end end diff --git a/actionpack/lib/action_view/render/layouts.rb b/actionpack/lib/action_view/render/layouts.rb index b9c63e0090..91a92a833a 100644 --- a/actionpack/lib/action_view/render/layouts.rb +++ b/actionpack/lib/action_view/render/layouts.rb @@ -48,7 +48,8 @@ module ActionView # the given name exists across all details before raising the error. def _find_layout(layout) #:nodoc: begin - find_template(layout) + layout =~ /^\// ? + with_fallbacks { find_template(layout) } : find_template(layout) rescue ActionView::MissingTemplate => e update_details(:formats => nil) do raise unless template_exists?(layout) diff --git a/actionpack/lib/action_view/render/rendering.rb b/actionpack/lib/action_view/render/rendering.rb index 96c0b4fe6a..d11f1fa2a7 100644 --- a/actionpack/lib/action_view/render/rendering.rb +++ b/actionpack/lib/action_view/render/rendering.rb @@ -63,7 +63,7 @@ module ActionView elsif options.key?(:text) Template::Text.new(options[:text], self.formats.try(:first)) elsif options.key?(:file) - find_template(options[:file], options[:_prefix]) + with_fallbacks { find_template(options[:file], options[:_prefix]) } elsif options.key?(:template) find_template(options[:template], options[:_prefix]) end diff --git a/actionpack/lib/action_view/template/resolver.rb b/actionpack/lib/action_view/template/resolver.rb index 40326f9193..fde13a4bdf 100644 --- a/actionpack/lib/action_view/template/resolver.rb +++ b/actionpack/lib/action_view/template/resolver.rb @@ -4,7 +4,6 @@ require "active_support/core_ext/array/wrap" require "action_view/template" module ActionView - # Abstract superclass class Resolver class_inheritable_accessor(:registered_details) @@ -30,7 +29,7 @@ module ActionView find_all(*args).first end - # Normalizes the arguments and passes it on to find_template + # Normalizes the arguments and passes it on to find_template. def find_all(name, details = {}, prefix = nil, partial = nil) details = normalize_details(details) name, prefix = normalize_name(name, prefix) @@ -82,21 +81,20 @@ module ActionView end class PathResolver < Resolver - EXTENSION_ORDER = [:locale, :formats, :handlers] def to_s @path.to_s end - alias to_path to_s + alias :to_path :to_s + + private def find_templates(name, details, prefix, partial) path = build_path(name, details, prefix, partial) query(path, EXTENSION_ORDER.map { |ext| details[ext] }) end - private - def build_path(name, details, prefix, partial) path = "" path << "#{prefix}/" unless prefix.empty? @@ -141,25 +139,10 @@ module ActionView super() @path = Pathname.new(path).expand_path end - end - - # TODO: remove hack - class FileSystemResolverWithFallback < Resolver - def initialize(path) - super() - @paths = [FileSystemResolver.new(path), FileSystemResolver.new(""), FileSystemResolver.new("/")] - end - def find_templates(*args) - @paths.each do |p| - template = p.find_templates(*args) - return template unless template.empty? - end - [] - end - - def to_s - @paths.first.to_s + def eql?(resolver) + self.class.equal?(resolver.class) && to_path == resolver.to_path end + alias :== :eql? end end diff --git a/actionpack/test/template/compiled_templates_test.rb b/actionpack/test/template/compiled_templates_test.rb index 632988bb2e..0a3409064f 100644 --- a/actionpack/test/template/compiled_templates_test.rb +++ b/actionpack/test/template/compiled_templates_test.rb @@ -44,7 +44,7 @@ class CompiledTemplatesTest < Test::Unit::TestCase end def render_without_cache(*args) - path = ActionView::FileSystemResolverWithFallback.new(FIXTURE_LOAD_PATH) + path = ActionView::FileSystemResolver.new(FIXTURE_LOAD_PATH) view_paths = ActionView::Base.process_view_paths(path) ActionView::Base.new(view_paths, {}).render(*args) end diff --git a/actionpack/test/template/render_test.rb b/actionpack/test/template/render_test.rb index 6dbadc9304..37a3975a54 100644 --- a/actionpack/test/template/render_test.rb +++ b/actionpack/test/template/render_test.rb @@ -270,7 +270,7 @@ class CachedViewRenderTest < ActiveSupport::TestCase # Ensure view path cache is primed def setup view_paths = ActionController::Base.view_paths - assert_equal ActionView::FileSystemResolverWithFallback, view_paths.first.class + assert_equal ActionView::FileSystemResolver, view_paths.first.class setup_view(view_paths) end end @@ -281,9 +281,9 @@ class LazyViewRenderTest < ActiveSupport::TestCase # Test the same thing as above, but make sure the view path # is not eager loaded def setup - path = ActionView::FileSystemResolverWithFallback.new(FIXTURE_LOAD_PATH) + path = ActionView::FileSystemResolver.new(FIXTURE_LOAD_PATH) view_paths = ActionView::Base.process_view_paths(path) - assert_equal ActionView::FileSystemResolverWithFallback, view_paths.first.class + assert_equal ActionView::FileSystemResolver.new(FIXTURE_LOAD_PATH), view_paths.first setup_view(view_paths) end end -- cgit v1.2.3 From 67a6725bf934452219cc054c8cd0535148d4fcd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Mon, 8 Mar 2010 16:50:10 +0100 Subject: Move ViewPaths module to its own file. --- actionpack/lib/abstract_controller.rb | 1 + actionpack/lib/abstract_controller/rendering.rb | 71 +----------------------- actionpack/lib/abstract_controller/view_paths.rb | 69 +++++++++++++++++++++++ 3 files changed, 71 insertions(+), 70 deletions(-) create mode 100644 actionpack/lib/abstract_controller/view_paths.rb (limited to 'actionpack') diff --git a/actionpack/lib/abstract_controller.rb b/actionpack/lib/abstract_controller.rb index 05348d8ba0..7028cd0379 100644 --- a/actionpack/lib/abstract_controller.rb +++ b/actionpack/lib/abstract_controller.rb @@ -19,4 +19,5 @@ module AbstractController autoload :Logger autoload :Rendering autoload :Translation + autoload :ViewPaths end diff --git a/actionpack/lib/abstract_controller/rendering.rb b/actionpack/lib/abstract_controller/rendering.rb index 840f0b6c78..46a457e3f4 100644 --- a/actionpack/lib/abstract_controller/rendering.rb +++ b/actionpack/lib/abstract_controller/rendering.rb @@ -1,5 +1,4 @@ require "abstract_controller/base" -require "active_support/core_ext/array/wrap" module AbstractController class DoubleRenderError < Error @@ -10,74 +9,6 @@ module AbstractController end end - module ViewPaths - extend ActiveSupport::Concern - - included do - class_attribute :_view_paths - self._view_paths = ActionView::PathSet.new - end - - delegate :find_template, :template_exists?, - :view_paths, :formats, :formats=, :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 - # information. - def lookup_context - @lookup_context ||= ActionView::LookupContext.new(self.class._view_paths, details_for_lookup) - end - - def details_for_lookup - { } - end - - def append_view_path(path) - lookup_context.view_paths.push(*path) - end - - def prepend_view_path(path) - lookup_context.view_paths.unshift(*path) - end - - module ClassMethods - # Append a path to the list of view paths for this controller. - # - # ==== Parameters - # path:: If a String is provided, it gets converted into - # the default view path. You may also provide a custom view path - # (see ActionView::ViewPathSet for more information) - def append_view_path(path) - self.view_paths = view_paths.dup + Array(path) - end - - # Prepend a path to the list of view paths for this controller. - # - # ==== Parameters - # path:: If a String is provided, it gets converted into - # the default view path. You may also provide a custom view path - # (see ActionView::ViewPathSet for more information) - def prepend_view_path(path) - self.view_paths = Array(path) + view_paths.dup - end - - # A list of all of the default view paths for this controller. - def view_paths - _view_paths - end - - # Set the view paths. - # - # ==== Parameters - # paths:: If a ViewPathSet is provided, use that; - # otherwise, process the parameter into a ViewPathSet. - def view_paths=(paths) - self._view_paths = paths.is_a?(ActionView::PathSet) ? paths : ActionView::Base.process_view_paths(paths) - self._view_paths.freeze - end - end - end - module Rendering extend ActiveSupport::Concern include AbstractController::ViewPaths @@ -166,7 +97,7 @@ module AbstractController end if (options.keys & [:partial, :file, :template]).empty? - options[:_prefix] ||= _prefix + options[:_prefix] ||= _prefix end options[:template] ||= (options[:action] || action_name).to_s diff --git a/actionpack/lib/abstract_controller/view_paths.rb b/actionpack/lib/abstract_controller/view_paths.rb new file mode 100644 index 0000000000..ec8f31cdfe --- /dev/null +++ b/actionpack/lib/abstract_controller/view_paths.rb @@ -0,0 +1,69 @@ +module AbstractController + module ViewPaths + extend ActiveSupport::Concern + + included do + class_attribute :_view_paths + self._view_paths = ActionView::PathSet.new + end + + delegate :find_template, :template_exists?, + :view_paths, :formats, :formats=, :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 + # information. + def lookup_context + @lookup_context ||= ActionView::LookupContext.new(self.class._view_paths, details_for_lookup) + end + + def details_for_lookup + { } + end + + def append_view_path(path) + lookup_context.view_paths.push(*path) + end + + def prepend_view_path(path) + lookup_context.view_paths.unshift(*path) + end + + module ClassMethods + # Append a path to the list of view paths for this controller. + # + # ==== Parameters + # path:: If a String is provided, it gets converted into + # the default view path. You may also provide a custom view path + # (see ActionView::ViewPathSet for more information) + def append_view_path(path) + self.view_paths = view_paths.dup + Array(path) + end + + # Prepend a path to the list of view paths for this controller. + # + # ==== Parameters + # path:: If a String is provided, it gets converted into + # the default view path. You may also provide a custom view path + # (see ActionView::ViewPathSet for more information) + def prepend_view_path(path) + self.view_paths = Array(path) + view_paths.dup + end + + # A list of all of the default view paths for this controller. + def view_paths + _view_paths + end + + # Set the view paths. + # + # ==== Parameters + # paths:: If a ViewPathSet is provided, use that; + # otherwise, process the parameter into a ViewPathSet. + def view_paths=(paths) + self._view_paths = paths.is_a?(ActionView::PathSet) ? paths : ActionView::Base.process_view_paths(paths) + self._view_paths.freeze + end + end + end +end \ No newline at end of file -- cgit v1.2.3 From bdf5096816d03f2bdaefd20a07a0fa562543549c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Mon, 8 Mar 2010 20:39:15 +0100 Subject: Move details to lookup_context and make resolvers use the cache key. --- actionpack/lib/abstract_controller/rendering.rb | 10 -- actionpack/lib/action_view/lookup_context.rb | 157 ++++++++++++++++-------- actionpack/lib/action_view/paths.rb | 4 +- actionpack/lib/action_view/template/resolver.rb | 46 ++----- actionpack/test/abstract/render_test.rb | 42 +------ 5 files changed, 118 insertions(+), 141 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/abstract_controller/rendering.rb b/actionpack/lib/abstract_controller/rendering.rb index 46a457e3f4..77c554fa3f 100644 --- a/actionpack/lib/abstract_controller/rendering.rb +++ b/actionpack/lib/abstract_controller/rendering.rb @@ -101,19 +101,9 @@ module AbstractController end options[:template] ||= (options[:action] || action_name).to_s - - details = _normalize_details(options) - lookup_context.update_details(details) options end - def _normalize_details(options) - details = {} - details[:formats] = Array(options[:format]) if options[:format] - details[:locale] = Array(options[:locale]) if options[:locale] - details - end - def _process_options(options) end diff --git a/actionpack/lib/action_view/lookup_context.rb b/actionpack/lib/action_view/lookup_context.rb index e259a78c5c..231882185f 100644 --- a/actionpack/lib/action_view/lookup_context.rb +++ b/actionpack/lib/action_view/lookup_context.rb @@ -1,14 +1,30 @@ +require 'active_support/core_ext/object/try' + module ActionView # LookupContext is the object responsible to hold all information required to lookup # templates, i.e. view paths and details. The LookupContext is also responsible to # generate a key, given to view paths, used in the resolver cache lookup. Since # this key is generated just once during the request, it speeds up all cache accesses. class LookupContext #:nodoc: - attr_reader :details, :view_paths - mattr_accessor :fallbacks @@fallbacks = [FileSystemResolver.new(""), FileSystemResolver.new("/")] + mattr_accessor :registered_details + self.registered_details = {} + + def self.register_detail(name, options = {}) + registered_details[name] = lambda do |value| + value = (value.blank? || options[:accessible] == false) ? + Array(yield) : Array(value) + 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 } + class DetailsKey #:nodoc: attr_reader :details alias :eql? :equal? @@ -22,75 +38,108 @@ module ActionView def initialize(details) @details, @hash = details, details.hash end + + def outdated?(details) + @details != details + end end def initialize(view_paths, details = {}) - @details, @details_key = details, nil self.view_paths = view_paths + self.details = details + @details_key = nil end - # Shortcut to read formats from details. - def formats - @details[:formats] - end - - # Shortcut to set formats in details. - def formats=(value) - self.details = @details.merge(:formats => Array(value)) - end + module ViewPaths + attr_reader :view_paths - # Whenever setting view paths, makes a copy so we can manipulate then in - # instance objects as we wish. - def view_paths=(paths) - @view_paths = ActionView::Base.process_view_paths(paths) - end + # Whenever setting view paths, makes a copy so we can manipulate then in + # instance objects as we wish. + def view_paths=(paths) + @view_paths = ActionView::Base.process_view_paths(paths) + end - # Setter for details. Everything this method is invoked, we need to nullify - # the details key if it changed. - def details=(details) - @details = details - @details_key = nil if @details_key && @details_key.details != details - end + def find_template(name, prefix = nil, partial = false) + key = details_key + @view_paths.find(name, key.details, prefix, partial || false, key) + end - def details_key - @details_key ||= DetailsKey.get(details) unless details.empty? - end + def template_exists?(name, prefix = nil, partial = false) + key = details_key + @view_paths.exists?(name, key.details, prefix, partial || false, key) + 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 - self.details = old_details.merge(new_details) - - if block_given? - begin - yield - ensure - self.details = old_details + # Add fallbacks to the view paths. Useful in cases you are rendering a file. + def with_fallbacks + added_resolvers = 0 + self.class.fallbacks.each do |resolver| + next if view_paths.include?(resolver) + view_paths.push(resolver) + added_resolvers += 1 end + yield + ensure + added_resolvers.times { view_paths.pop } end end - # Added fallbacks to the view paths. Useful in cases you are rendering a file. - def with_fallbacks - added_resolvers = 0 - self.class.fallbacks.each do |resolver| - next if view_paths.include?(resolver) - view_paths.push(resolver) - added_resolvers += 1 + module Details + def details + @details = normalize_details(@details) end - yield - ensure - added_resolvers.times { view_paths.pop } - end - def find_template(name, prefix = nil, partial = false) - @view_paths.find(name, details, prefix, partial || false, details_key) - end + def details=(new_details) + @details = new_details + details + end - def template_exists?(name, prefix = nil, partial = false) - @view_paths.exists?(name, details, prefix, partial || false, details_key) + # 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) + end + + # Shortcut to read formats from details. + def formats + self.details[:formats] + end + + # Shortcut to set formats in details. + def formats=(value) + self.details = @details.merge(:formats => value) + 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 + self.details = old_details.merge(new_details) + + if block_given? + begin + yield + ensure + self.details = old_details + end + end + end + + protected + + def normalize_details(details) + details = details.dup + # TODO: Refactor this concern out of the resolver + details.delete(:formats) if details[:formats] == [:"*/*"] + self.class.registered_details.each do |k, v| + details[k] = v.call(details[k]) + end + details + end end + + include Details + include ViewPaths end end \ No newline at end of file diff --git a/actionpack/lib/action_view/paths.rb b/actionpack/lib/action_view/paths.rb index 628546e443..1205d26e3b 100644 --- a/actionpack/lib/action_view/paths.rb +++ b/actionpack/lib/action_view/paths.rb @@ -11,7 +11,7 @@ module ActionView #:nodoc: def find(path, details = {}, prefix = nil, partial = false, key=nil) each do |resolver| - if template = resolver.find(path, details, prefix, partial) + if template = resolver.find(path, details, prefix, partial, key) return template end end @@ -21,7 +21,7 @@ module ActionView #:nodoc: def exists?(path, details = {}, prefix = nil, partial = false, key=nil) each do |resolver| - if resolver.find(path, details, prefix, partial) + if resolver.find(path, details, prefix, partial, key) return true end end diff --git a/actionpack/lib/action_view/template/resolver.rb b/actionpack/lib/action_view/template/resolver.rb index fde13a4bdf..9a011f7638 100644 --- a/actionpack/lib/action_view/template/resolver.rb +++ b/actionpack/lib/action_view/template/resolver.rb @@ -5,24 +5,9 @@ require "action_view/template" module ActionView class Resolver - - class_inheritable_accessor(:registered_details) - self.registered_details = {} - - def self.register_detail(name, options = {}) - registered_details[name] = lambda do |val| - val = Array.wrap(val || yield) - val |= [nil] unless options[:allow_nil] == false - val - end - end - - register_detail(:locale) { [I18n.locale] } - register_detail(:formats) { Mime::SET.symbols } - register_detail(:handlers) { Template::Handlers.extensions } - def initialize - @cached = {} + @cached = Hash.new { |h1,k1| h1[k1] = + Hash.new { |h2,k2| h2[k2] = Hash.new { |h3, k3| h3[k3] = {} } } } end def find(*args) @@ -30,11 +15,10 @@ module ActionView end # Normalizes the arguments and passes it on to find_template. - def find_all(name, details = {}, prefix = nil, partial = nil) - details = normalize_details(details) + def find_all(name, details = {}, prefix = nil, partial = nil, key=nil) name, prefix = normalize_name(name, prefix) - cached([name, details, prefix, partial]) do + cached(key, prefix, name, partial) do find_templates(name, details, prefix, partial) end end @@ -52,16 +36,6 @@ module ActionView raise NotImplementedError end - def normalize_details(details) - details = details.dup - # TODO: Refactor this concern out of the resolver - details.delete(:formats) if details[:formats] == [:"*/*"] - registered_details.each do |k, v| - details[k] = v.call(details[k]) - end - details - end - # Support legacy foo.erb names even though we now ignore .erb # as well as incorrectly putting part of the path in the template # name instead of the prefix. @@ -73,10 +47,14 @@ module ActionView return parts.pop, [prefix, *parts].compact.join("/") end - def cached(key) - return yield unless caching? - return @cached[key] if @cached.key?(key) - @cached[key] = yield + def cached(key, prefix, name, partial) + return yield unless key && caching? + scope = @cached[key][prefix][name] + if scope.key?(partial) + scope[partial] + else + scope[partial] = yield + end end end diff --git a/actionpack/test/abstract/render_test.rb b/actionpack/test/abstract/render_test.rb index e54d056666..25dc8bd804 100644 --- a/actionpack/test/abstract/render_test.rb +++ b/actionpack/test/abstract/render_test.rb @@ -16,11 +16,7 @@ module AbstractController "renderer/string.erb" => "With String", "renderer/symbol.erb" => "With Symbol", "string/with_path.erb" => "With String With Path", - "some/file.erb" => "With File", - "with_format.html.erb" => "With html format", - "with_format.xml.erb" => "With xml format", - "with_locale.en.erb" => "With en locale", - "with_locale.pl.erb" => "With pl locale" + "some/file.erb" => "With File" )] def template @@ -54,22 +50,6 @@ module AbstractController def symbol render :symbol end - - def with_html_format - render :template => "with_format", :format => :html - end - - def with_xml_format - render :template => "with_format", :format => :xml - end - - def with_en_locale - render :template => "with_locale" - end - - def with_pl_locale - render :template => "with_locale", :locale => :pl - end end class TestRenderer < ActiveSupport::TestCase @@ -117,26 +97,6 @@ module AbstractController @controller.process(:string_with_path) assert_equal "With String With Path", @controller.response_body end - - def test_render_with_html_format - @controller.process(:with_html_format) - assert_equal "With html format", @controller.response_body - end - - def test_render_with_xml_format - @controller.process(:with_xml_format) - assert_equal "With xml format", @controller.response_body - end - - def test_render_with_en_locale - @controller.process(:with_en_locale) - assert_equal "With en locale", @controller.response_body - end - - def test_render_with_pl_locale - @controller.process(:with_pl_locale) - assert_equal "With pl locale", @controller.response_body - end end end end -- cgit v1.2.3 From 36eb1a686c831d5a14998bb9ac7cc60efa363373 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Mon, 8 Mar 2010 20:57:33 +0100 Subject: Bring AM up to date with new rendering stack. --- actionpack/lib/action_view/lookup_context.rb | 5 +++++ actionpack/lib/action_view/paths.rb | 8 ++++++++ actionpack/lib/action_view/render/rendering.rb | 2 ++ 3 files changed, 15 insertions(+) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/lookup_context.rb b/actionpack/lib/action_view/lookup_context.rb index 231882185f..608f1ef818 100644 --- a/actionpack/lib/action_view/lookup_context.rb +++ b/actionpack/lib/action_view/lookup_context.rb @@ -64,6 +64,11 @@ module ActionView @view_paths.find(name, key.details, prefix, partial || false, key) end + def find_all(name, prefix = nil, partial = false) + key = details_key + @view_paths.find_all(name, key.details, prefix, partial || false, key) + end + def template_exists?(name, prefix = nil, partial = false) key = details_key @view_paths.exists?(name, key.details, prefix, partial || false, key) diff --git a/actionpack/lib/action_view/paths.rb b/actionpack/lib/action_view/paths.rb index 1205d26e3b..82a9f9a13c 100644 --- a/actionpack/lib/action_view/paths.rb +++ b/actionpack/lib/action_view/paths.rb @@ -9,6 +9,14 @@ module ActionView #:nodoc: METHOD end + def find_all(path, details = {}, prefix = nil, partial = false, key=nil) + each do |resolver| + templates = resolver.find_all(path, details, prefix, partial, key) + return templates unless templates.empty? + end + [] + end + def find(path, details = {}, prefix = nil, partial = false, key=nil) each do |resolver| if template = resolver.find(path, details, prefix, partial, key) diff --git a/actionpack/lib/action_view/render/rendering.rb b/actionpack/lib/action_view/render/rendering.rb index d11f1fa2a7..0322d4b641 100644 --- a/actionpack/lib/action_view/render/rendering.rb +++ b/actionpack/lib/action_view/render/rendering.rb @@ -64,6 +64,8 @@ module ActionView Template::Text.new(options[:text], self.formats.try(:first)) elsif options.key?(:file) with_fallbacks { find_template(options[:file], options[:_prefix]) } + elsif options.key?(:_template) + options[:_template] elsif options.key?(:template) find_template(options[:template], options[:_prefix]) end -- cgit v1.2.3 From f38e2e03351da463f84f6850fa10718ece98ff26 Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Mon, 8 Mar 2010 12:24:49 -0800 Subject: Add support for mount RackApp, :at => "/sprockets" with a shorthand of mount Sprockets => "/sprockets". This is different from the match syntax in that it cannot be used for controller/action and it does not assume an anchor at the end of the match. For instance, in the above example, if the client asked for "/sprockets/foo.js", the Sprockets app would have a SCRIPT_NAME of "/sprockets" and PATH_INFO of "/foo.js". --- actionpack/lib/action_dispatch/routing/mapper.rb | 27 ++++++++++++---- actionpack/lib/action_dispatch/routing/route.rb | 4 +-- .../lib/action_dispatch/routing/route_set.rb | 4 +-- actionpack/test/dispatch/mount_test.rb | 36 ++++++++++++++++++++++ 4 files changed, 61 insertions(+), 10 deletions(-) create mode 100644 actionpack/test/dispatch/mount_test.rb (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index 7a33259054..e6c563d7b7 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -1,5 +1,3 @@ -require "active_support/core_ext/hash/except" - module ActionDispatch module Routing class Mapper @@ -38,7 +36,7 @@ module ActionDispatch end def to_route - [ app, conditions, requirements, defaults, @options[:as] ] + [ app, conditions, requirements, defaults, @options[:as], @options[:anchor] ] end private @@ -66,7 +64,7 @@ module ActionDispatch # match "account/overview" def using_match_shorthand?(args, options) - args.present? && options.except(:via).empty? && !args.first.include?(':') + args.present? && options.except(:via, :anchor).empty? && !args.first.include?(':') end def normalize_path(path) @@ -87,7 +85,7 @@ module ActionDispatch end def requirements - @requirements ||= (@options[:constraints] || {}).tap do |requirements| + @requirements ||= returning(@options[:constraints] || {}) do |requirements| requirements.reverse_merge!(@scope[:constraints]) if @scope[:constraints] @options.each { |k, v| requirements[k] = v if v.is_a?(Regexp) } end @@ -176,7 +174,8 @@ module ActionDispatch end def match(*args) - @set.add_route(*Mapping.new(@set, @scope, args).to_route) + mapping = Mapping.new(@set, @scope, args).to_route + @set.add_route(*mapping) self end end @@ -295,6 +294,7 @@ module ActionDispatch options = args.extract_options! options = (@scope[:options] || {}).merge(options) + options[:anchor] = true unless options.key?(:anchor) if @scope[:name_prefix] && !options[:as].blank? options[:as] = "#{@scope[:name_prefix]}_#{options[:as]}" @@ -538,6 +538,21 @@ module ActionDispatch end end + def mount(app, options = nil) + if options + path = options.delete(:at) + else + options = app + app, path = options.find { |k, v| k.respond_to?(:call) } + options.delete(app) if app + end + + raise "A rack application must be specified" unless path + + match(path, options.merge(:to => app, :anchor => false)) + self + end + def match(*args) options = args.extract_options! diff --git a/actionpack/lib/action_dispatch/routing/route.rb b/actionpack/lib/action_dispatch/routing/route.rb index e6e44d3546..6f37eadd6b 100644 --- a/actionpack/lib/action_dispatch/routing/route.rb +++ b/actionpack/lib/action_dispatch/routing/route.rb @@ -4,7 +4,7 @@ module ActionDispatch attr_reader :app, :conditions, :defaults, :name attr_reader :path, :requirements - def initialize(app, conditions = {}, requirements = {}, defaults = {}, name = nil) + def initialize(app, conditions, requirements, defaults, name, anchor) @app = app @defaults = defaults @name = name @@ -17,7 +17,7 @@ module ActionDispatch if path = conditions[:path_info] @path = path - conditions[:path_info] = ::Rack::Mount::Strexp.compile(path, requirements, SEPARATORS) + conditions[:path_info] = ::Rack::Mount::Strexp.compile(path, requirements, SEPARATORS, anchor) end @conditions = conditions.inject({}) { |h, (k, v)| diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 5c246d8781..550e54e955 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -293,8 +293,8 @@ module ActionDispatch routes.empty? end - def add_route(app, conditions = {}, requirements = {}, defaults = {}, name = nil) - route = Route.new(app, conditions, requirements, defaults, name) + def add_route(app, conditions = {}, requirements = {}, defaults = {}, name = nil, anchor = true) + route = Route.new(app, conditions, requirements, defaults, name, anchor) @set.add_route(*route) named_routes[name] = route if name routes << route diff --git a/actionpack/test/dispatch/mount_test.rb b/actionpack/test/dispatch/mount_test.rb new file mode 100644 index 0000000000..f89e5fda07 --- /dev/null +++ b/actionpack/test/dispatch/mount_test.rb @@ -0,0 +1,36 @@ +require 'abstract_unit' + +class TestRoutingMount < ActionDispatch::IntegrationTest + SprocketsApp = lambda { |env| + [200, {"Content-Type" => "text/html"}, ["#{env["SCRIPT_NAME"]} -- #{env["PATH_INFO"]}"]] + } + + Router = ActionDispatch::Routing::RouteSet.new + Router.draw do + mount SprocketsApp, :at => "/sprockets" + mount SprocketsApp => "/shorthand" + + scope "/its_a" do + mount SprocketsApp, :at => "/sprocket" + end + end + + def app + Router + end + + def test_mounting_sets_script_name + get "/sprockets/omg" + assert_equal "/sprockets -- /omg", response.body + end + + def test_mounting_works_with_scope + get "/its_a/sprocket/omg" + assert_equal "/its_a/sprocket -- /omg", response.body + end + + def test_mounting_with_shorthand + get "/shorthand/omg" + assert_equal "/shorthand -- /omg", response.body + end +end \ No newline at end of file -- cgit v1.2.3 From 0045f37681acdb8fe844fb8118e93cfe9d73140d Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Mon, 8 Mar 2010 12:30:51 -0800 Subject: Whoops. We meant to switch from returning to tap, not vice versa --- actionpack/lib/action_dispatch/routing/mapper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index e6c563d7b7..dee4516fbe 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -85,7 +85,7 @@ module ActionDispatch end def requirements - @requirements ||= returning(@options[:constraints] || {}) do |requirements| + @requirements ||= (@options[:constraints] || {}).tap do |requirements| requirements.reverse_merge!(@scope[:constraints]) if @scope[:constraints] @options.each { |k, v| requirements[k] = v if v.is_a?(Regexp) } end -- cgit v1.2.3 From 01f0e47663bbbc593af0c36d4cf49124b200e3d8 Mon Sep 17 00:00:00 2001 From: Carl Lerche Date: Mon, 8 Mar 2010 14:02:41 -0800 Subject: Move request forgery protection configuration to the AC config object This is an interim solution pending revisiting the rails framework configuration situation. --- .../metal/request_forgery_protection.rb | 45 ++++++++++++++++++++-- actionpack/lib/action_controller/railtie.rb | 5 ++- 2 files changed, 44 insertions(+), 6 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/metal/request_forgery_protection.rb b/actionpack/lib/action_controller/metal/request_forgery_protection.rb index 276c703307..6765314df2 100644 --- a/actionpack/lib/action_controller/metal/request_forgery_protection.rb +++ b/actionpack/lib/action_controller/metal/request_forgery_protection.rb @@ -12,11 +12,10 @@ module ActionController #:nodoc: included do # Sets the token parameter name for RequestForgery. Calling +protect_from_forgery+ # sets it to :authenticity_token by default. - cattr_accessor :request_forgery_protection_token + config.request_forgery_protection_token ||= true # Controls whether request forgergy protection is turned on or not. Turned off by default only in test mode. - class_attribute :allow_forgery_protection - self.allow_forgery_protection = true + config.allow_forgery_protection ||= true helper_method :form_authenticity_token helper_method :protect_against_forgery? @@ -80,9 +79,47 @@ module ActionController #:nodoc: self.request_forgery_protection_token ||= :authenticity_token before_filter :verify_authenticity_token, options end + + def request_forgery_protection_token + config.request_forgery_protection_token + end + + def request_forgery_protection_token=(val) + config.request_forgery_protection_token = val + end + + def allow_forgery_protection + config.allow_forgery_protection + end + + def allow_forgery_protection=(val) + config.allow_forgery_protection = val + end end protected + + def protect_from_forgery(options = {}) + self.request_forgery_protection_token ||= :authenticity_token + before_filter :verify_authenticity_token, options + end + + def request_forgery_protection_token + config.request_forgery_protection_token + end + + def request_forgery_protection_token=(val) + config.request_forgery_protection_token = val + end + + def allow_forgery_protection + config.allow_forgery_protection + end + + def allow_forgery_protection=(val) + config.allow_forgery_protection = val + end + # The actual before_filter that is used. Modify this to change how you handle unverified requests. def verify_authenticity_token verified_request? || raise(ActionController::InvalidAuthenticityToken) @@ -109,7 +146,7 @@ module ActionController #:nodoc: end def protect_against_forgery? - self.class.allow_forgery_protection + config.allow_forgery_protection end end end diff --git a/actionpack/lib/action_controller/railtie.rb b/actionpack/lib/action_controller/railtie.rb index ca03fc62da..6a3afbb157 100644 --- a/actionpack/lib/action_controller/railtie.rb +++ b/actionpack/lib/action_controller/railtie.rb @@ -46,10 +46,11 @@ module ActionController initializer "action_controller.set_configs" do |app| paths = app.config.paths ac = app.config.action_controller - ac.assets_dir = paths.public.to_a.first + + ac.assets_dir = paths.public.to_a.first ac.javascripts_dir = paths.public.javascripts.to_a.first ac.stylesheets_dir = paths.public.stylesheets.to_a.first - ac.secret = app.config.cookie_secret + ac.secret = app.config.cookie_secret ActionController.base_hook { self.config.replace(ac) } end -- cgit v1.2.3 From 8f082ff4217175f52234f2223658619a9c923afc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Mon, 8 Mar 2010 23:13:24 +0100 Subject: Clean LookupContext API. --- actionpack/lib/abstract_controller/rendering.rb | 2 +- actionpack/lib/abstract_controller/view_paths.rb | 7 ++++-- .../lib/action_controller/metal/compatibility.rb | 3 ++- actionpack/lib/action_view/base.rb | 2 +- actionpack/lib/action_view/lookup_context.rb | 10 ++++---- actionpack/lib/action_view/paths.rb | 29 ++++++++-------------- actionpack/lib/action_view/render/layouts.rb | 4 +-- actionpack/lib/action_view/render/partials.rb | 2 +- actionpack/lib/action_view/render/rendering.rb | 8 +++--- actionpack/lib/action_view/template/resolver.rb | 16 +++++++----- actionpack/test/controller/render_test.rb | 6 ++--- 11 files changed, 43 insertions(+), 46 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/abstract_controller/rendering.rb b/actionpack/lib/abstract_controller/rendering.rb index 77c554fa3f..5048754e33 100644 --- a/actionpack/lib/abstract_controller/rendering.rb +++ b/actionpack/lib/abstract_controller/rendering.rb @@ -97,7 +97,7 @@ module AbstractController end if (options.keys & [:partial, :file, :template]).empty? - options[:_prefix] ||= _prefix + options[:prefix] ||= _prefix end options[:template] ||= (options[:action] || action_name).to_s diff --git a/actionpack/lib/abstract_controller/view_paths.rb b/actionpack/lib/abstract_controller/view_paths.rb index ec8f31cdfe..6513c0778e 100644 --- a/actionpack/lib/abstract_controller/view_paths.rb +++ b/actionpack/lib/abstract_controller/view_paths.rb @@ -7,8 +7,7 @@ module AbstractController self._view_paths = ActionView::PathSet.new end - delegate :find_template, :template_exists?, - :view_paths, :formats, :formats=, :to => :lookup_context + delegate :template_exists?, :view_paths, :formats, :formats=, :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 @@ -29,6 +28,10 @@ module AbstractController lookup_context.view_paths.unshift(*path) end + def template_exists?(*args) + lookup_context.exists?(*args) + end + module ClassMethods # Append a path to the list of view paths for this controller. # diff --git a/actionpack/lib/action_controller/metal/compatibility.rb b/actionpack/lib/action_controller/metal/compatibility.rb index 5cad0814ca..ab8d87b2c4 100644 --- a/actionpack/lib/action_controller/metal/compatibility.rb +++ b/actionpack/lib/action_controller/metal/compatibility.rb @@ -50,8 +50,9 @@ module ActionController end def _normalize_options(options) - # TODO Deprecate this. Rails 2.x allowed to give a template as action. if options[:action] && options[:action].to_s.include?(?/) + ActiveSupport::Deprecation.warn "Giving a path to render :action is deprecated. " << + "Please use render :template instead", caller options[:template] = options.delete(:action) end diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index 38413560f3..564ea6684c 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_template, :template_exists?, :formats, :formats=, + delegate :find, :exists?, :formats, :formats=, :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 608f1ef818..4a4dc0d06c 100644 --- a/actionpack/lib/action_view/lookup_context.rb +++ b/actionpack/lib/action_view/lookup_context.rb @@ -59,19 +59,19 @@ module ActionView @view_paths = ActionView::Base.process_view_paths(paths) end - def find_template(name, prefix = nil, partial = false) + def find(name, prefix = nil, partial = false) key = details_key - @view_paths.find(name, key.details, prefix, partial || false, key) + @view_paths.find(name, prefix, partial || false, key.details, key) end def find_all(name, prefix = nil, partial = false) key = details_key - @view_paths.find_all(name, key.details, prefix, partial || false, key) + @view_paths.find_all(name, prefix, partial || false, key.details, key) end - def template_exists?(name, prefix = nil, partial = false) + def exists?(name, prefix = nil, partial = false) key = details_key - @view_paths.exists?(name, key.details, prefix, partial || false, key) + @view_paths.exists?(name, prefix, partial || false, key.details, key) end # Add fallbacks to the view paths. Useful in cases you are rendering a file. diff --git a/actionpack/lib/action_view/paths.rb b/actionpack/lib/action_view/paths.rb index 82a9f9a13c..35927d09d1 100644 --- a/actionpack/lib/action_view/paths.rb +++ b/actionpack/lib/action_view/paths.rb @@ -9,31 +9,22 @@ module ActionView #:nodoc: METHOD end - def find_all(path, details = {}, prefix = nil, partial = false, key=nil) + def find(path, prefix = nil, partial = false, details = {}, key = nil) + template = find_all(path, prefix, partial, details, key).first + raise MissingTemplate.new(self, "#{prefix}/#{path}", details, partial) unless template + template + end + + def find_all(*args) each do |resolver| - templates = resolver.find_all(path, details, prefix, partial, key) + templates = resolver.find_all(*args) return templates unless templates.empty? end [] end - def find(path, details = {}, prefix = nil, partial = false, key=nil) - each do |resolver| - if template = resolver.find(path, details, prefix, partial, key) - return template - end - end - - raise ActionView::MissingTemplate.new(self, "#{prefix}/#{path}", details, partial) - end - - def exists?(path, details = {}, prefix = nil, partial = false, key=nil) - each do |resolver| - if resolver.find(path, details, prefix, partial, key) - return true - end - end - false + def exists?(*args) + find_all(*args).any? end protected diff --git a/actionpack/lib/action_view/render/layouts.rb b/actionpack/lib/action_view/render/layouts.rb index 91a92a833a..8688de3d18 100644 --- a/actionpack/lib/action_view/render/layouts.rb +++ b/actionpack/lib/action_view/render/layouts.rb @@ -49,10 +49,10 @@ module ActionView def _find_layout(layout) #:nodoc: begin layout =~ /^\// ? - with_fallbacks { find_template(layout) } : find_template(layout) + with_fallbacks { find(layout) } : find(layout) rescue ActionView::MissingTemplate => e update_details(:formats => nil) do - raise unless template_exists?(layout) + raise unless exists?(layout) end end end diff --git a/actionpack/lib/action_view/render/partials.rb b/actionpack/lib/action_view/render/partials.rb index 0fe2d560f7..950c9d2cd8 100644 --- a/actionpack/lib/action_view/render/partials.rb +++ b/actionpack/lib/action_view/render/partials.rb @@ -294,7 +294,7 @@ module ActionView def find_template(path=@path) return path unless path.is_a?(String) prefix = @view.controller_path unless path.include?(?/) - @view.find_template(path, prefix, true) + @view.find(path, prefix, true) end def partial_path(object = @object) diff --git a/actionpack/lib/action_view/render/rendering.rb b/actionpack/lib/action_view/render/rendering.rb index 0322d4b641..47ea70f5ad 100644 --- a/actionpack/lib/action_view/render/rendering.rb +++ b/actionpack/lib/action_view/render/rendering.rb @@ -29,8 +29,6 @@ module ActionView end # This is the API to render a ViewContext's template from a controller. - # TODO Review this name since it does not render only templates, but also - # partials, files and so forth. def render_template(options, &block) _evaluate_assigns_and_ivars @@ -62,12 +60,12 @@ module ActionView Template.new(options[:inline], "inline template", handler, {}) elsif options.key?(:text) Template::Text.new(options[:text], self.formats.try(:first)) - elsif options.key?(:file) - with_fallbacks { find_template(options[:file], options[:_prefix]) } elsif options.key?(:_template) options[:_template] + elsif options.key?(:file) + with_fallbacks { find(options[:file], options[:prefix]) } elsif options.key?(:template) - find_template(options[:template], options[:_prefix]) + find(options[:template], options[:prefix]) end end diff --git a/actionpack/lib/action_view/template/resolver.rb b/actionpack/lib/action_view/template/resolver.rb index 9a011f7638..6e6c4c21ee 100644 --- a/actionpack/lib/action_view/template/resolver.rb +++ b/actionpack/lib/action_view/template/resolver.rb @@ -10,16 +10,20 @@ module ActionView Hash.new { |h2,k2| h2[k2] = Hash.new { |h3, k3| h3[k3] = {} } } } end + def clear_cache + @cached.clear + end + def find(*args) find_all(*args).first end # Normalizes the arguments and passes it on to find_template. - def find_all(name, details = {}, prefix = nil, partial = nil, key=nil) + def find_all(name, prefix=nil, partial=false, details={}, key=nil) name, prefix = normalize_name(name, prefix) cached(key, prefix, name, partial) do - find_templates(name, details, prefix, partial) + find_templates(name, prefix, partial, details) end end @@ -32,7 +36,7 @@ module ActionView # This is what child classes implement. No defaults are needed # because Resolver guarantees that the arguments are present and # normalized. - def find_templates(name, details, prefix, partial) + def find_templates(name, prefix, partial, details) raise NotImplementedError end @@ -68,12 +72,12 @@ module ActionView private - def find_templates(name, details, prefix, partial) - path = build_path(name, details, prefix, partial) + def find_templates(name, prefix, partial, details) + path = build_path(name, prefix, partial, details) query(path, EXTENSION_ORDER.map { |ext| details[ext] }) end - def build_path(name, details, prefix, partial) + def build_path(name, prefix, partial, details) path = "" path << "#{prefix}/" unless prefix.empty? path << (partial ? "_#{name}" : name) diff --git a/actionpack/test/controller/render_test.rb b/actionpack/test/controller/render_test.rb index ecfe14b797..e3c4869391 100644 --- a/actionpack/test/controller/render_test.rb +++ b/actionpack/test/controller/render_test.rb @@ -355,7 +355,7 @@ class TestController < ActionController::Base @before = "i'm before the render" render_to_string :text => "foo" @after = "i'm after the render" - render :action => "test/hello_world" + render :template => "test/hello_world" end def render_to_string_with_exception @@ -369,7 +369,7 @@ class TestController < ActionController::Base rescue end @after = "i'm after the render" - render :action => "test/hello_world" + render :template => "test/hello_world" end def accessing_params_in_template_with_layout @@ -514,7 +514,7 @@ class TestController < ActionController::Base def render_to_string_with_partial @partial_only = render_to_string :partial => "partial_only" @partial_with_locals = render_to_string :partial => "customer", :locals => { :customer => Customer.new("david") } - render :action => "test/hello_world" + render :template => "test/hello_world" end def partial_with_counter -- cgit v1.2.3 From 8e9d9232b0c3d96c662762e13848c275a86c0c61 Mon Sep 17 00:00:00 2001 From: Carl Lerche Date: Mon, 8 Mar 2010 14:22:25 -0800 Subject: Require 'active_support/core_ext/hash/except' in the router. --- actionpack/lib/action_dispatch/routing/mapper.rb | 2 ++ 1 file changed, 2 insertions(+) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index dee4516fbe..ae4470d033 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -1,3 +1,5 @@ +require 'active_support/core_ext/hash/except' + module ActionDispatch module Routing class Mapper -- cgit v1.2.3 From 146a5305d56b636d2fd2c2a09a58f5f3edc2d9c0 Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Mon, 8 Mar 2010 15:57:07 -0800 Subject: Add memoizing to AD::Request --- actionpack/lib/action_dispatch/http/request.rb | 8 ++++++++ 1 file changed, 8 insertions(+) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/http/request.rb b/actionpack/lib/action_dispatch/http/request.rb index 56a2b9bf6a..ea9f0f99c2 100755 --- a/actionpack/lib/action_dispatch/http/request.rb +++ b/actionpack/lib/action_dispatch/http/request.rb @@ -30,6 +30,14 @@ module ActionDispatch METHOD end + def self.new(env) + if request = env["action_dispatch.request"] && request.instance_of?(self) + return request + end + + super + end + def key?(key) @env.key?(key) end -- cgit v1.2.3 From 056042eb829e0507ed605264d43a79ce88112288 Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Mon, 8 Mar 2010 16:49:47 -0800 Subject: Simplify the action endpoint: * Remove ActionEndpoint in favor of passing a block to MiddlewareStack * Always create a Request; the performance win of RackDelegation is around the response; the Request object hit is limited to a single object allocation * #dispatch takes a Request --- actionpack/lib/action_controller/metal.rb | 34 ++++++---------------- .../lib/action_controller/metal/rack_delegation.rb | 5 +--- actionpack/lib/action_controller/middleware.rb | 3 +- actionpack/lib/action_dispatch/middleware/stack.rb | 6 +++- 4 files changed, 17 insertions(+), 31 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/metal.rb b/actionpack/lib/action_controller/metal.rb index 5e0ed201cb..eebd2c943a 100644 --- a/actionpack/lib/action_controller/metal.rb +++ b/actionpack/lib/action_controller/metal.rb @@ -34,7 +34,8 @@ module ActionController # and response object available. You might wish to control the # environment and response manually for performance reasons. - attr_internal :status, :headers, :content_type, :response + attr_internal :status, :headers, :content_type, :response, :request + delegate :session, :to => "@_request" def initialize(*) @_headers = {} @@ -66,8 +67,9 @@ module ActionController end # :api: private - def dispatch(name, env) - @_env = env + def dispatch(name, request) + @_request = request + @_env = request.env @_env['action_controller.instance'] = self process(name) to_a @@ -78,26 +80,6 @@ module ActionController response ? response.to_a : [status, headers, response_body] end - class ActionEndpoint - @@endpoints = Hash.new {|h,k| h[k] = Hash.new {|sh,sk| sh[sk] = {} } } - - def self.for(controller, action, stack) - @@endpoints[controller][action][stack] ||= begin - endpoint = new(controller, action) - stack.build(endpoint) - end - end - - def initialize(controller, action) - @controller, @action = controller, action - @_formats = [Mime::HTML] - end - - def call(env) - @controller.new.dispatch(@action, env) - end - end - class_attribute :middleware_stack self.middleware_stack = ActionDispatch::MiddlewareStack.new @@ -127,8 +109,10 @@ module ActionController # # ==== Returns # Proc:: A rack application - def self.action(name) - ActionEndpoint.for(self, name, middleware_stack) + def self.action(name, klass = ActionDispatch::Request) + middleware_stack.build do |env| + new.dispatch(name, klass.new(env)) + end end end end diff --git a/actionpack/lib/action_controller/metal/rack_delegation.rb b/actionpack/lib/action_controller/metal/rack_delegation.rb index bb55383631..37106733cb 100644 --- a/actionpack/lib/action_controller/metal/rack_delegation.rb +++ b/actionpack/lib/action_controller/metal/rack_delegation.rb @@ -6,14 +6,11 @@ module ActionController extend ActiveSupport::Concern included do - delegate :session, :to => "@_request" delegate :headers, :status=, :location=, :content_type=, :status, :location, :content_type, :to => "@_response" - attr_internal :request end - def dispatch(action, env) - @_request = ActionDispatch::Request.new(env) + def dispatch(action, request) @_response = ActionDispatch::Response.new @_response.request = request super diff --git a/actionpack/lib/action_controller/middleware.rb b/actionpack/lib/action_controller/middleware.rb index 17275793b7..2115b07b3e 100644 --- a/actionpack/lib/action_controller/middleware.rb +++ b/actionpack/lib/action_controller/middleware.rb @@ -6,7 +6,8 @@ module ActionController end def call(env) - @controller.build(@app).dispatch(:index, env) + request = ActionDispatch::Request.new(env) + @controller.build(@app).dispatch(:index, request) end end diff --git a/actionpack/lib/action_dispatch/middleware/stack.rb b/actionpack/lib/action_dispatch/middleware/stack.rb index c52c8c0e6a..5c5362ce4a 100644 --- a/actionpack/lib/action_dispatch/middleware/stack.rb +++ b/actionpack/lib/action_dispatch/middleware/stack.rb @@ -122,7 +122,11 @@ module ActionDispatch find_all { |middleware| middleware.active? } end - def build(app) + def build(app = nil, &blk) + app ||= blk + + raise "MiddlewareStack#build requires an app" unless app + active.reverse.inject(app) { |a, e| e.build(a) } end end -- cgit v1.2.3 From e4558e0dbfc87724fb3ce3fdc38aea3e49843aec Mon Sep 17 00:00:00 2001 From: wycats Date: Mon, 8 Mar 2010 18:48:58 -0800 Subject: Now that class_attribute creates an instance method, remove it to avoid deprecation warnings ;) --- actionpack/lib/action_dispatch/routing/url_for.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/routing/url_for.rb b/actionpack/lib/action_dispatch/routing/url_for.rb index 0ab20dcb39..035b0ec4ca 100644 --- a/actionpack/lib/action_dispatch/routing/url_for.rb +++ b/actionpack/lib/action_dispatch/routing/url_for.rb @@ -90,9 +90,10 @@ module ActionDispatch class_attribute :default_url_options else mattr_accessor :default_url_options - remove_method :default_url_options end + remove_method :default_url_options + self.default_url_options = {} end -- cgit v1.2.3 From 514d3a47f4a6a7a46054b45cb6b78ba37d62618e Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Mon, 8 Mar 2010 21:37:56 -0800 Subject: Remove outdated, distracting commented code --- .../lib/action_dispatch/routing/route_set.rb | 25 ---------------------- 1 file changed, 25 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 550e54e955..8ebad1a9b8 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -168,31 +168,6 @@ module ActionDispatch selector = url_helper_name(name, kind) hash_access_method = hash_access_name(name, kind) - # We use module_eval to avoid leaks. - # - # def users_url(*args) - # if args.empty? || Hash === args.first - # options = hash_for_users_url(args.first || {}) - # else - # options = hash_for_users_url(args.extract_options!) - # default = default_url_options(options) if self.respond_to?(:default_url_options, true) - # options = (default ||= {}).merge(options) - # - # keys = [] - # keys -= options.keys if args.size < keys.size - 1 - # - # args = args.zip(keys).inject({}) do |h, (v, k)| - # h[k] = v - # h - # end - # - # # Tell url_for to skip default_url_options - # options[:use_defaults] = false - # options.merge!(args) - # end - # - # url_for(options) - # end @module.module_eval <<-END_EVAL, __FILE__, __LINE__ + 1 def #{selector}(*args) options = #{hash_access_method}(args.extract_options!) -- cgit v1.2.3 From c507e16dba844c7b066d145bfd5c5d23e7a9c5ad Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Mon, 8 Mar 2010 21:40:04 -0800 Subject: Reinstate default_url_options and remove url_options= writer --- actionpack/lib/action_dispatch/routing/url_for.rb | 66 +++++++---------------- actionpack/test/controller/base_test.rb | 42 +++++++-------- actionpack/test/template/url_helper_test.rb | 2 +- 3 files changed, 39 insertions(+), 71 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/routing/url_for.rb b/actionpack/lib/action_dispatch/routing/url_for.rb index 035b0ec4ca..4629e7e002 100644 --- a/actionpack/lib/action_dispatch/routing/url_for.rb +++ b/actionpack/lib/action_dispatch/routing/url_for.rb @@ -85,43 +85,24 @@ module ActionDispatch extend ActiveSupport::Concern included do - # Including in a class uses an inheritable hash. Modules get a plain hash. - if respond_to?(:class_attribute) - class_attribute :default_url_options - else - mattr_accessor :default_url_options - end - - remove_method :default_url_options - - self.default_url_options = {} - end - - # def default_url_options(options = nil) - # self.class.default_url_options - # end + # TODO: with_routing extends @controller with url_helpers, trickling down to including this module which overrides its default_url_options + unless method_defined?(:default_url_options) + # Including in a class uses an inheritable hash. Modules get a plain hash. + if respond_to?(:class_attribute) + class_attribute :default_url_options + else + mattr_accessor :default_url_options + remove_method :default_url_options + end - def url_options - @url_options ||= begin - # self.class does not respond to default_url_options when the helpers are extended - # onto a singleton - self.class.respond_to?(:default_url_options) ? self.class.default_url_options : {} + self.default_url_options = {} end end - def url_options=(options) - defaults = self.class.respond_to?(:default_url_options) ? self.class.default_url_options : {} - @url_options = defaults.merge(options) + def url_options + default_url_options end - # def merge_options(options) #:nodoc: - # if respond_to?(:default_url_options) && (defaults = default_url_options(options)) - # defaults.merge(options) - # else - # options - # end - # end - # Generate a url based on the options provided, default_url_options and the # routes defined in routes.rb. The following options are supported: # @@ -145,23 +126,14 @@ module ActionDispatch # url_for :controller => 'tasks', :action => 'testing', :host=>'somehost.org', :anchor => 'ok', :only_path => true # => '/tasks/testing#ok' # url_for :controller => 'tasks', :action => 'testing', :trailing_slash=>true # => 'http://somehost.org/tasks/testing/' # url_for :controller => 'tasks', :action => 'testing', :host=>'somehost.org', :number => '33' # => 'http://somehost.org/tasks/testing?number=33' - def url_for(options = {}) - options ||= {} + def url_for(options = nil) case options - when String - options - when Hash - # Handle the deprecated instance level default_url_options - if respond_to?(:default_url_options, true) - ActiveSupport::Deprecation.warn "Overriding the #default_url_options method is deprecated. Instead, set self.url_options = { ... } in a before_filter." - if defaults = default_url_options(options) - options = defaults.merge(options) - end - end - - ActionController::UrlRewriter.rewrite(_router, url_options.merge(options)) - else - polymorphic_url(options) + when String + options + when nil, Hash + ActionController::UrlRewriter.rewrite(_router, url_options.merge(options || {})) + else + polymorphic_url(options) end end end diff --git a/actionpack/test/controller/base_test.rb b/actionpack/test/controller/base_test.rb index ade9a7fcba..3e9f8ae048 100644 --- a/actionpack/test/controller/base_test.rb +++ b/actionpack/test/controller/base_test.rb @@ -181,7 +181,7 @@ class UrlOptionsTest < ActionController::TestCase rescue_action_in_public! end - def test_default_url_options_are_used_if_set + def test_url_options_override with_routing do |set| set.draw do |map| match 'from_view', :to => 'url_options#from_view', :as => :from_view @@ -206,20 +206,18 @@ class DefaultUrlOptionsTest < ActionController::TestCase rescue_action_in_public! end - def test_default_url_options_are_used_if_set + def test_default_url_options_override with_routing do |set| set.draw do |map| match 'from_view', :to => 'default_url_options#from_view', :as => :from_view match ':controller/:action' end - assert_deprecated do - get :from_view, :route => "from_view_url" + get :from_view, :route => "from_view_url" - assert_equal 'http://www.override.com/from_view?locale=en', @response.body - assert_equal 'http://www.override.com/from_view?locale=en', @controller.send(:from_view_url) - assert_equal 'http://www.override.com/default_url_options/new?locale=en', @controller.url_for(:controller => 'default_url_options') - end + assert_equal 'http://www.override.com/from_view?locale=en', @response.body + assert_equal 'http://www.override.com/from_view?locale=en', @controller.send(:from_view_url) + assert_equal 'http://www.override.com/default_url_options/new?locale=en', @controller.url_for(:controller => 'default_url_options') end end @@ -232,21 +230,19 @@ class DefaultUrlOptionsTest < ActionController::TestCase match ':controller/:action' end - assert_deprecated do - get :from_view, :route => "description_path(1)" - - assert_equal '/en/descriptions/1', @response.body - assert_equal '/en/descriptions', @controller.send(:descriptions_path) - assert_equal '/pl/descriptions', @controller.send(:descriptions_path, "pl") - assert_equal '/pl/descriptions', @controller.send(:descriptions_path, :locale => "pl") - assert_equal '/pl/descriptions.xml', @controller.send(:descriptions_path, "pl", "xml") - assert_equal '/en/descriptions.xml', @controller.send(:descriptions_path, :format => "xml") - assert_equal '/en/descriptions/1', @controller.send(:description_path, 1) - assert_equal '/pl/descriptions/1', @controller.send(:description_path, "pl", 1) - assert_equal '/pl/descriptions/1', @controller.send(:description_path, 1, :locale => "pl") - assert_equal '/pl/descriptions/1.xml', @controller.send(:description_path, "pl", 1, "xml") - assert_equal '/en/descriptions/1.xml', @controller.send(:description_path, 1, :format => "xml") - end + get :from_view, :route => "description_path(1)" + + assert_equal '/en/descriptions/1', @response.body + assert_equal '/en/descriptions', @controller.send(:descriptions_path) + assert_equal '/pl/descriptions', @controller.send(:descriptions_path, "pl") + assert_equal '/pl/descriptions', @controller.send(:descriptions_path, :locale => "pl") + assert_equal '/pl/descriptions.xml', @controller.send(:descriptions_path, "pl", "xml") + assert_equal '/en/descriptions.xml', @controller.send(:descriptions_path, :format => "xml") + assert_equal '/en/descriptions/1', @controller.send(:description_path, 1) + assert_equal '/pl/descriptions/1', @controller.send(:description_path, "pl", 1) + assert_equal '/pl/descriptions/1', @controller.send(:description_path, 1, :locale => "pl") + assert_equal '/pl/descriptions/1.xml', @controller.send(:description_path, "pl", 1, "xml") + assert_equal '/en/descriptions/1.xml', @controller.send(:description_path, 1, :format => "xml") end end diff --git a/actionpack/test/template/url_helper_test.rb b/actionpack/test/template/url_helper_test.rb index 533a07b6f4..38ab5521fe 100644 --- a/actionpack/test/template/url_helper_test.rb +++ b/actionpack/test/template/url_helper_test.rb @@ -437,7 +437,7 @@ class UrlHelperControllerTest < ActionController::TestCase end with_url_helper_routing do - assert_deprecated { get :show_named_route, :kind => 'url' } + get :show_named_route, :kind => 'url' assert_equal 'http://testtwo.host/url_helper_controller_test/url_helper/show_named_route', @response.body end end -- cgit v1.2.3 From 00d6271d2b11a14065925529af0c1200406f8beb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Tue, 9 Mar 2010 13:12:11 +0100 Subject: Clean up the API required from ActionView::Template. --- actionpack/lib/abstract_controller/rendering.rb | 2 +- actionpack/lib/action_view/template.rb | 32 ++++++++++++------------- actionpack/lib/action_view/template/resolver.rb | 31 ++++++++++-------------- actionpack/lib/action_view/template/text.rb | 6 +---- actionpack/test/lib/fixture_template.rb | 8 ++++--- 5 files changed, 35 insertions(+), 44 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/abstract_controller/rendering.rb b/actionpack/lib/abstract_controller/rendering.rb index 5048754e33..5c34b83563 100644 --- a/actionpack/lib/abstract_controller/rendering.rb +++ b/actionpack/lib/abstract_controller/rendering.rb @@ -108,7 +108,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/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..c43b357e9e 100644 --- a/actionpack/lib/action_view/template/resolver.rb +++ b/actionpack/lib/action_view/template/resolver.rb @@ -74,7 +74,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 +84,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]) - - format = Mime[details.last] && details.pop.to_sym - locale = details.last && details.pop.to_sym + def extract_handler_and_format(path) + pieces = File.basename(path).split(".") + pieces.shift - 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 -- cgit v1.2.3 From de79525d045b6ea2d83f325bdeeb9380510d045c Mon Sep 17 00:00:00 2001 From: wycats Date: Mon, 8 Mar 2010 21:08:31 -0800 Subject: Get rid of the instance-level URL rewriter --- actionpack/lib/action_controller/test_case.rb | 8 +++-- actionpack/lib/action_controller/url_rewriter.rb | 40 ++------------------- actionpack/test/controller/caching_test.rb | 2 +- actionpack/test/controller/url_rewriter_test.rb | 44 ++++++++---------------- actionpack/test/template/url_helper_test.rb | 2 -- 5 files changed, 25 insertions(+), 71 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb index 7e0a833dfa..c43e560ac1 100644 --- a/actionpack/lib/action_controller/test_case.rb +++ b/actionpack/lib/action_controller/test_case.rb @@ -339,9 +339,13 @@ module ActionController def build_request_uri(action, parameters) unless @request.env["PATH_INFO"] options = @controller.__send__(:url_options).merge(parameters) - options.update(:only_path => true, :action => action, :relative_url_root => nil) - rewriter = ActionController::UrlRewriter.new(@request, parameters) + options.update( + :only_path => true, + :action => action, + :relative_url_root => nil, + :_path_segments => @request.symbolized_path_parameters) + rewriter = ActionController::UrlRewriter url, query_string = rewriter.rewrite(@router, options).split("?", 2) @request.env["SCRIPT_NAME"] = @controller.config.relative_url_root diff --git a/actionpack/lib/action_controller/url_rewriter.rb b/actionpack/lib/action_controller/url_rewriter.rb index 981865517f..b387d49593 100644 --- a/actionpack/lib/action_controller/url_rewriter.rb +++ b/actionpack/lib/action_controller/url_rewriter.rb @@ -2,37 +2,16 @@ require 'active_support/core_ext/hash/except' module ActionController # Rewrites URLs for Base.redirect_to and Base.url_for in the controller. - class UrlRewriter #:nodoc: + module UrlRewriter #:nodoc: RESERVED_OPTIONS = [:anchor, :params, :only_path, :host, :protocol, :port, :trailing_slash, :skip_relative_url_root] - def initialize(request, parameters) - @request, @parameters = request, parameters - end - - def rewrite(router, options = {}) - options[:host] ||= @request.host_with_port - options[:protocol] ||= @request.protocol - - self.class.rewrite(router, options, @request.symbolized_path_parameters) do |options| - process_path_options(options) - end - end - - def to_str - "#{@request.protocol}, #{@request.host_with_port}, #{@request.path}, #{@parameters[:controller]}, #{@parameters[:action]}, #{@request.parameters.inspect}" - end - - alias_method :to_s, :to_str - # ROUTES TODO: Class method code smell - def self.rewrite(router, options, path_segments=nil) + def self.rewrite(router, options) handle_positional_args(options) rewritten_url = "" - # ROUTES TODO: Fix the tests - segments = options.delete(:_path_segments) - path_segments = path_segments ? path_segments.merge(segments || {}) : segments + path_segments = options.delete(:_path_segments) unless options[:only_path] rewritten_url << (options[:protocol] || "http") @@ -81,18 +60,5 @@ module ActionController end end - # Given a Hash of options, generates a route - def process_path_options(options) - options = options.symbolize_keys - options.update(options[:params].symbolize_keys) if options[:params] - - if (overwrite = options.delete(:overwrite_params)) - options.update(@parameters.symbolize_keys) - options.update(overwrite.symbolize_keys) - end - - options - end - end end diff --git a/actionpack/test/controller/caching_test.rb b/actionpack/test/controller/caching_test.rb index 11ef3cdd92..2be91893d4 100644 --- a/actionpack/test/controller/caching_test.rb +++ b/actionpack/test/controller/caching_test.rb @@ -64,7 +64,7 @@ class PageCachingTest < ActionController::TestCase @controller.cache_store = :file_store, FILE_STORE_PATH @params = {:controller => 'posts', :action => 'index', :only_path => true, :skip_relative_url_root => true} - @rewriter = ActionController::UrlRewriter.new(@request, @params) + @rewriter = ActionController::UrlRewriter FileUtils.rm_rf(File.dirname(FILE_STORE_PATH)) FileUtils.mkdir_p(FILE_STORE_PATH) diff --git a/actionpack/test/controller/url_rewriter_test.rb b/actionpack/test/controller/url_rewriter_test.rb index 199b824a7a..3bc8bec3fb 100644 --- a/actionpack/test/controller/url_rewriter_test.rb +++ b/actionpack/test/controller/url_rewriter_test.rb @@ -4,10 +4,24 @@ require 'controller/fake_controllers' ActionController::UrlRewriter class UrlRewriterTests < ActionController::TestCase + class Rewriter + def initialize(request) + @options = { + :host => request.host_with_port, + :protocol => request.protocol + } + end + + def rewrite(router, options) + options = @options.merge(options) + ActionController::UrlRewriter.rewrite(router, options) + end + end + def setup @request = ActionController::TestRequest.new @params = {} - @rewriter = ActionController::UrlRewriter.new(@request, @params) + @rewriter = Rewriter.new(@request) #.new(@request, @params) end def test_port @@ -61,34 +75,6 @@ class UrlRewriterTests < ActionController::TestCase ) end - def test_overwrite_params - @params[:controller] = 'hi' - @params[:action] = 'bye' - @params[:id] = '2' - - assert_equal '/hi/hi/2', @rewriter.rewrite(@router, :only_path => true, :overwrite_params => {:action => 'hi'}) - u = @rewriter.rewrite(@router, :only_path => false, :overwrite_params => {:action => 'hi'}) - assert_match %r(/hi/hi/2$), u - end - - def test_overwrite_removes_original - @params[:controller] = 'search' - @params[:action] = 'list' - @params[:list_page] = 1 - - assert_equal '/search/list?list_page=2', @rewriter.rewrite(@router, :only_path => true, :overwrite_params => {"list_page" => 2}) - u = @rewriter.rewrite(@router, :only_path => false, :overwrite_params => {:list_page => 2}) - assert_equal 'http://test.host/search/list?list_page=2', u - end - - def test_to_str - @params[:controller] = 'hi' - @params[:action] = 'bye' - @request.parameters[:id] = '2' - - assert_equal 'http://, test.host, /, hi, bye, {"id"=>"2"}', @rewriter.to_str - end - def test_trailing_slash options = {:controller => 'foo', :action => 'bar', :id => '3', :only_path => true} assert_equal '/foo/bar/3', @rewriter.rewrite(@router, options) diff --git a/actionpack/test/template/url_helper_test.rb b/actionpack/test/template/url_helper_test.rb index 38ab5521fe..165cb655da 100644 --- a/actionpack/test/template/url_helper_test.rb +++ b/actionpack/test/template/url_helper_test.rb @@ -122,7 +122,6 @@ class UrlHelperTest < ActionView::TestCase url = {:controller => 'weblog', :action => 'show'} @controller = ActionController::Base.new @controller.request = ActionController::TestRequest.new - @controller.url = ActionController::UrlRewriter.new(@controller.request, url) assert_dom_equal(%q{Test Link}, link_to('Test Link', url)) end @@ -131,7 +130,6 @@ class UrlHelperTest < ActionView::TestCase url = {:controller => 'weblog', :action => 'show', :host => 'www.example.com'} @controller = ActionController::Base.new @controller.request = ActionController::TestRequest.new - @controller.url = ActionController::UrlRewriter.new(@controller.request, url) assert_dom_equal(%q{Test Link}, link_to('Test Link', url)) end -- cgit v1.2.3 From 9444ac9312470696b6a5d73cd0044329211ec4c6 Mon Sep 17 00:00:00 2001 From: wycats Date: Tue, 9 Mar 2010 10:20:48 -0800 Subject: Refactor the RouteSet so it uses a Generator object instead of one huge method. --- actionpack/lib/action_controller/metal/url_for.rb | 1 - .../lib/action_dispatch/routing/route_set.rb | 196 ++++++++++++--------- 2 files changed, 109 insertions(+), 88 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/metal/url_for.rb b/actionpack/lib/action_controller/metal/url_for.rb index f6b6cb2ff4..10c7ca9021 100644 --- a/actionpack/lib/action_controller/metal/url_for.rb +++ b/actionpack/lib/action_controller/metal/url_for.rb @@ -3,7 +3,6 @@ module ActionController extend ActiveSupport::Concern include ActionDispatch::Routing::UrlFor - include ActionController::RackDelegation def url_options super.reverse_merge( diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 8ebad1a9b8..e99e39269b 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -276,116 +276,138 @@ module ActionDispatch route end - def options_as_params(options) - # If an explicit :controller was given, always make :action explicit - # too, so that action expiry works as expected for things like - # - # generate({:controller => 'content'}, {:controller => 'content', :action => 'show'}) - # - # (the above is from the unit tests). In the above case, because the - # controller was explicitly given, but no action, the action is implied to - # be "index", not the recalled action of "show". - # - # great fun, eh? - - options_as_params = options.clone - options_as_params[:action] ||= 'index' if options[:controller] - options_as_params[:action] = options_as_params[:action].to_s if options_as_params[:action] - options_as_params - end + class Generator + attr_reader :options, :recall, :set, :script_name, :named_route + + def initialize(options, recall, set, extras = false) + @script_name = options.delete(:script_name) + @named_route = options.delete(:use_route) + @options = options.dup + @recall = recall.dup + @set = set + @extras = extras + + normalize_options! + normalize_controller_action_id! + use_relative_controller! + controller.sub!(%r{^/}, '') if controller + handle_nil_action! + end - def build_expiry(options, recall) - recall.inject({}) do |expiry, (key, recalled_value)| - expiry[key] = (options.key?(key) && options[key].to_param != recalled_value.to_param) - expiry + def controller + @controller ||= @options[:controller] end - end - # Generate the path indicated by the arguments, and return an array of - # the keys that were not used to generate it. - def extra_keys(options, recall={}) - generate_extras(options, recall).last - end + def current_controller + @recall[:controller] + end - def generate_extras(options, recall={}) - generate(options, recall, :generate_extras) - end + def use_recall_for(key) + if @recall[key] && (!@options.key?(key) || @options[key] == @recall[key]) + @options[key] = @recall.delete(key) + end + end - def generate(options, recall = {}, method = :generate) - options, recall = options.dup, recall.dup - script_name = options.delete(:script_name) - named_route = options.delete(:use_route) + def normalize_options! + # If an explicit :controller was given, always make :action explicit + # too, so that action expiry works as expected for things like + # + # generate({:controller => 'content'}, {:controller => 'content', :action => 'show'}) + # + # (the above is from the unit tests). In the above case, because the + # controller was explicitly given, but no action, the action is implied to + # be "index", not the recalled action of "show". - options = options_as_params(options) - expire_on = build_expiry(options, recall) + if options[:controller] + options[:action] ||= 'index' + options[:controller] = options[:controller].to_s + end - recall[:action] ||= 'index' if options[:controller] || recall[:controller] + if options[:action] + options[:action] = options[:action].to_s + end + end - if recall[:controller] && (!options.has_key?(:controller) || options[:controller] == recall[:controller]) - options[:controller] = recall.delete(:controller) + # This pulls :controller, :action, and :id out of the recall. + # The recall key is only used if there is no key in the options + # or if the key in the options is identical. If any of + # :controller, :action or :id is not found, don't pull any + # more keys from the recall. + def normalize_controller_action_id! + @recall[:action] ||= 'index' if current_controller + + use_recall_for(:controller) or return + use_recall_for(:action) or return + use_recall_for(:id) + end - if recall[:action] && (!options.has_key?(:action) || options[:action] == recall[:action]) - options[:action] = recall.delete(:action) + # if the current controller is "foo/bar/baz" and :controller => "baz/bat" + # is specified, the controller becomes "foo/baz/bat" + def use_relative_controller! + if !named_route && different_controller? + old_parts = current_controller.split('/') + size = controller.count("/") + 1 + parts = old_parts[0...-size] << controller + @controller = @options[:controller] = parts.join("/") + end + end - if recall[:id] && (!options.has_key?(:id) || options[:id] == recall[:id]) - options[:id] = recall.delete(:id) - end + # This handles the case of :action => nil being explicitly passed. + # It is identical to :action => "index" + def handle_nil_action! + if options.has_key?(:action) && options[:action].nil? + options[:action] = 'index' end + recall[:action] = options.delete(:action) if options[:action] == 'index' end - options[:controller] = options[:controller].to_s if options[:controller] + def generate + error = ActionController::RoutingError.new("No route matches #{options.inspect}") + path, params = @set.generate(:path_info, named_route, options, recall, opts) - if !named_route && expire_on[:controller] && options[:controller] && options[:controller][0] != ?/ - old_parts = recall[:controller].split('/') - new_parts = options[:controller].split('/') - parts = old_parts[0..-(new_parts.length + 1)] + new_parts - options[:controller] = parts.join('/') - end + raise error unless path - options[:controller] = options[:controller][1..-1] if options[:controller] && options[:controller][0] == ?/ + params.reject! {|k,v| !v } - merged = options.merge(recall) - if options.has_key?(:action) && options[:action].nil? - options.delete(:action) - recall[:action] = 'index' - end - recall[:action] = options.delete(:action) if options[:action] == 'index' - - opts = {} - opts[:parameterize] = lambda { |name, value| - if name == :controller - value - elsif value.is_a?(Array) - value.map { |v| Rack::Mount::Utils.escape_uri(v.to_param) }.join('/') - else - Rack::Mount::Utils.escape_uri(value.to_param) - end - } + return [path, params.keys] if @extras - unless result = @set.generate(:path_info, named_route, options, recall, opts) - raise ActionController::RoutingError, "No route matches #{options.inspect}" + path << "?#{params.to_query}" if params.any? + "#{script_name}#{path}" + rescue Rack::Mount::RoutingError + raise error end - path, params = result - params.each do |k, v| - if v - params[k] = v - else - params.delete(k) + def opts + parameterize = lambda do |name, value| + if name == :controller + value + elsif value.is_a?(Array) + value.map { |v| Rack::Mount::Utils.escape_uri(v.to_param) }.join('/') + else + Rack::Mount::Utils.escape_uri(value.to_param) + end end + {:parameterize => parameterize} end - if path && method == :generate_extras - [path, params.keys] - elsif path - path << "?#{params.to_query}" if params.any? - path = "#{script_name}#{path}" - path - else - raise ActionController::RoutingError, "No route matches #{options.inspect}" + def different_controller? + return false unless current_controller + controller.to_param != current_controller.to_param end - rescue Rack::Mount::RoutingError - raise ActionController::RoutingError, "No route matches #{options.inspect}" + end + + # Generate the path indicated by the arguments, and return an array of + # the keys that were not used to generate it. + def extra_keys(options, recall={}) + generate_extras(options, recall).last + end + + def generate_extras(options, recall={}) + generate(options, recall, true) + end + + def generate(options, recall = {}, extras = false) + Generator.new(options, recall, @set, extras).generate end def call(env) -- cgit v1.2.3 From ea4f8ef33f08a69a68f6b95f392e63ea9cc13602 Mon Sep 17 00:00:00 2001 From: Justin Ko Date: Tue, 9 Mar 2010 16:37:46 -0200 Subject: Reinstate dom_id in controllers. [#3040 state:committed] Signed-off-by: Santiago Pastorino Signed-off-by: Jeremy Kemper --- actionpack/lib/action_controller/base.rb | 1 + actionpack/test/controller/base_test.rb | 8 ++++++++ 2 files changed, 9 insertions(+) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb index d00afa6d4e..fcd3cb9bd3 100644 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -29,6 +29,7 @@ module ActionController include ActionController::Verification include ActionController::RequestForgeryProtection include ActionController::Streaming + include ActionController::RecordIdentifier include ActionController::HttpAuthentication::Basic::ControllerMethods include ActionController::HttpAuthentication::Digest::ControllerMethods diff --git a/actionpack/test/controller/base_test.rb b/actionpack/test/controller/base_test.rb index 3e9f8ae048..f047e7da30 100644 --- a/actionpack/test/controller/base_test.rb +++ b/actionpack/test/controller/base_test.rb @@ -76,6 +76,9 @@ class UrlOptionsController < ActionController::Base end end +class RecordIdentifierController < ActionController::Base +end + class ControllerClassTests < ActiveSupport::TestCase def test_controller_path assert_equal 'empty', EmptyController.controller_path @@ -102,6 +105,11 @@ class ControllerClassTests < ActiveSupport::TestCase assert_equal [:password], parameters end + + def test_record_identifier + assert_respond_to RecordIdentifierController.new, :dom_id + assert_respond_to RecordIdentifierController.new, :dom_class + end end class ControllerInstanceTests < Test::Unit::TestCase -- cgit v1.2.3 From 7db80f87e9c194713c2016820e39af6043ddf8d0 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Tue, 9 Mar 2010 20:50:35 -0600 Subject: Move AC::UrlRewriter onto route set --- actionpack/lib/action_controller.rb | 1 - actionpack/lib/action_controller/test_case.rb | 33 ++++++----- actionpack/lib/action_controller/url_rewriter.rb | 64 ---------------------- .../lib/action_dispatch/routing/route_set.rb | 56 +++++++++++++++++++ actionpack/lib/action_dispatch/routing/url_for.rb | 2 +- actionpack/test/controller/caching_test.rb | 5 +- actionpack/test/controller/url_rewriter_test.rb | 5 +- 7 files changed, 76 insertions(+), 90 deletions(-) delete mode 100644 actionpack/lib/action_controller/url_rewriter.rb (limited to 'actionpack') diff --git a/actionpack/lib/action_controller.rb b/actionpack/lib/action_controller.rb index 3b97f38498..536154fc6b 100644 --- a/actionpack/lib/action_controller.rb +++ b/actionpack/lib/action_controller.rb @@ -46,7 +46,6 @@ module ActionController eager_autoload do autoload :RecordIdentifier - autoload :UrlRewriter # TODO: Don't autoload exceptions, setup explicit # requires for files that need them diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb index c43e560ac1..072d289964 100644 --- a/actionpack/lib/action_controller/test_case.rb +++ b/actionpack/lib/action_controller/test_case.rb @@ -335,23 +335,22 @@ module ActionController @request.remote_addr = '208.77.188.166' # example.com end - private - def build_request_uri(action, parameters) - unless @request.env["PATH_INFO"] - options = @controller.__send__(:url_options).merge(parameters) - options.update( - :only_path => true, - :action => action, - :relative_url_root => nil, - :_path_segments => @request.symbolized_path_parameters) - - rewriter = ActionController::UrlRewriter - url, query_string = rewriter.rewrite(@router, options).split("?", 2) - - @request.env["SCRIPT_NAME"] = @controller.config.relative_url_root - @request.env["PATH_INFO"] = url - @request.env["QUERY_STRING"] = query_string || "" + private + def build_request_uri(action, parameters) + unless @request.env["PATH_INFO"] + options = @controller.__send__(:url_options).merge(parameters) + options.update( + :only_path => true, + :action => action, + :relative_url_root => nil, + :_path_segments => @request.symbolized_path_parameters) + + url, query_string = @router.rewrite(options).split("?", 2) + + @request.env["SCRIPT_NAME"] = @controller.config.relative_url_root + @request.env["PATH_INFO"] = url + @request.env["QUERY_STRING"] = query_string || "" + end end end - end end diff --git a/actionpack/lib/action_controller/url_rewriter.rb b/actionpack/lib/action_controller/url_rewriter.rb deleted file mode 100644 index b387d49593..0000000000 --- a/actionpack/lib/action_controller/url_rewriter.rb +++ /dev/null @@ -1,64 +0,0 @@ -require 'active_support/core_ext/hash/except' - -module ActionController - # Rewrites URLs for Base.redirect_to and Base.url_for in the controller. - module UrlRewriter #:nodoc: - RESERVED_OPTIONS = [:anchor, :params, :only_path, :host, :protocol, :port, :trailing_slash, :skip_relative_url_root] - - # ROUTES TODO: Class method code smell - def self.rewrite(router, options) - handle_positional_args(options) - - rewritten_url = "" - - path_segments = options.delete(:_path_segments) - - unless options[:only_path] - rewritten_url << (options[:protocol] || "http") - rewritten_url << "://" unless rewritten_url.match("://") - rewritten_url << rewrite_authentication(options) - - raise "Missing host to link to! Please provide :host parameter or set default_url_options[:host]" unless options[:host] - - rewritten_url << options[:host] - rewritten_url << ":#{options.delete(:port)}" if options.key?(:port) - end - - path_options = options.except(*RESERVED_OPTIONS) - path_options = yield(path_options) if block_given? - path = router.generate(path_options, path_segments || {}) - - # ROUTES TODO: This can be called directly, so script_name should probably be set in the router - rewritten_url << (options[:trailing_slash] ? path.sub(/\?|\z/) { "/" + $& } : path) - rewritten_url << "##{Rack::Utils.escape(options[:anchor].to_param.to_s)}" if options[:anchor] - - rewritten_url - end - - protected - - def self.handle_positional_args(options) - return unless args = options.delete(:_positional_args) - - keys = options.delete(:_positional_keys) - keys -= options.keys if args.size < keys.size - 1 # take format into account - - args = args.zip(keys).inject({}) do |h, (v, k)| - h[k] = v - h - end - - # Tell url_for to skip default_url_options - options.merge!(args) - end - - def self.rewrite_authentication(options) - if options[:user] && options[:password] - "#{Rack::Utils.escape(options.delete(:user))}:#{Rack::Utils.escape(options.delete(:password))}@" - else - "" - end - end - - end -end diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index e99e39269b..15c7cd00ba 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -410,6 +410,38 @@ module ActionDispatch Generator.new(options, recall, @set, extras).generate end + RESERVED_OPTIONS = [:anchor, :params, :only_path, :host, :protocol, :port, :trailing_slash, :skip_relative_url_root] + + # TODO: Terrible method name + def rewrite(options) + handle_positional_args(options) + + rewritten_url = "" + + path_segments = options.delete(:_path_segments) + + unless options[:only_path] + rewritten_url << (options[:protocol] || "http") + rewritten_url << "://" unless rewritten_url.match("://") + rewritten_url << rewrite_authentication(options) + + raise "Missing host to link to! Please provide :host parameter or set default_url_options[:host]" unless options[:host] + + rewritten_url << options[:host] + rewritten_url << ":#{options.delete(:port)}" if options.key?(:port) + end + + path_options = options.except(*RESERVED_OPTIONS) + path_options = yield(path_options) if block_given? + path = generate(path_options, path_segments || {}) + + # ROUTES TODO: This can be called directly, so script_name should probably be set in the router + rewritten_url << (options[:trailing_slash] ? path.sub(/\?|\z/) { "/" + $& } : path) + rewritten_url << "##{Rack::Utils.escape(options[:anchor].to_param.to_s)}" if options[:anchor] + + rewritten_url + end + def call(env) @set.call(env) end @@ -435,6 +467,30 @@ module ActionDispatch raise ActionController::RoutingError, "No route matches #{path.inspect}" end + + private + def handle_positional_args(options) + return unless args = options.delete(:_positional_args) + + keys = options.delete(:_positional_keys) + keys -= options.keys if args.size < keys.size - 1 # take format into account + + args = args.zip(keys).inject({}) do |h, (v, k)| + h[k] = v + h + end + + # Tell url_for to skip default_url_options + options.merge!(args) + end + + def rewrite_authentication(options) + if options[:user] && options[:password] + "#{Rack::Utils.escape(options.delete(:user))}:#{Rack::Utils.escape(options.delete(:password))}@" + else + "" + end + end end end end diff --git a/actionpack/lib/action_dispatch/routing/url_for.rb b/actionpack/lib/action_dispatch/routing/url_for.rb index 4629e7e002..0ba04316d7 100644 --- a/actionpack/lib/action_dispatch/routing/url_for.rb +++ b/actionpack/lib/action_dispatch/routing/url_for.rb @@ -131,7 +131,7 @@ module ActionDispatch when String options when nil, Hash - ActionController::UrlRewriter.rewrite(_router, url_options.merge(options || {})) + _router.rewrite(url_options.merge(options || {})) else polymorphic_url(options) end diff --git a/actionpack/test/controller/caching_test.rb b/actionpack/test/controller/caching_test.rb index 2be91893d4..08efd5a48c 100644 --- a/actionpack/test/controller/caching_test.rb +++ b/actionpack/test/controller/caching_test.rb @@ -64,7 +64,6 @@ class PageCachingTest < ActionController::TestCase @controller.cache_store = :file_store, FILE_STORE_PATH @params = {:controller => 'posts', :action => 'index', :only_path => true, :skip_relative_url_root => true} - @rewriter = ActionController::UrlRewriter FileUtils.rm_rf(File.dirname(FILE_STORE_PATH)) FileUtils.mkdir_p(FILE_STORE_PATH) @@ -82,9 +81,9 @@ class PageCachingTest < ActionController::TestCase match '/', :to => 'posts#index', :as => :main end @params[:format] = 'rss' - assert_equal '/posts.rss', @rewriter.rewrite(@router, @params) + assert_equal '/posts.rss', @router.rewrite(@params) @params[:format] = nil - assert_equal '/', @rewriter.rewrite(@router, @params) + assert_equal '/', @router.rewrite(@params) end end diff --git a/actionpack/test/controller/url_rewriter_test.rb b/actionpack/test/controller/url_rewriter_test.rb index 3bc8bec3fb..cf775846df 100644 --- a/actionpack/test/controller/url_rewriter_test.rb +++ b/actionpack/test/controller/url_rewriter_test.rb @@ -1,8 +1,6 @@ require 'abstract_unit' require 'controller/fake_controllers' -ActionController::UrlRewriter - class UrlRewriterTests < ActionController::TestCase class Rewriter def initialize(request) @@ -13,8 +11,7 @@ class UrlRewriterTests < ActionController::TestCase end def rewrite(router, options) - options = @options.merge(options) - ActionController::UrlRewriter.rewrite(router, options) + router.rewrite(@options.merge(options)) end end -- cgit v1.2.3 From e38ea982ff8fea5b616297b458ca2c669de0d659 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Tue, 9 Mar 2010 20:57:43 -0600 Subject: Unused RouteSet#url_for is hogging a good method name --- actionpack/lib/action_dispatch/routing/route_set.rb | 17 ++++------------- 1 file changed, 4 insertions(+), 13 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 15c7cd00ba..aa1e25aa8b 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -235,31 +235,22 @@ module ActionDispatch named_routes.install(destinations, regenerate_code) end - def url_for - @url_for ||= begin - router = self - Module.new do - extend ActiveSupport::Concern - include UrlFor - - define_method(:_router) { router } - end - end - end - def url_helpers @url_helpers ||= begin router = self Module.new do extend ActiveSupport::Concern - include router.url_for + include UrlFor # ROUTES TODO: install_helpers isn't great... can we make a module with the stuff that # we can include? + # Yes plz - JP included do router.install_helpers(self) end + + define_method(:_router) { router } end end end -- cgit v1.2.3 From 4d2470f7daad8cebd0a69f5ea0509a41af0596b8 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Tue, 9 Mar 2010 21:00:24 -0600 Subject: RouteSet#rewrite => url_for --- actionpack/lib/action_controller/test_case.rb | 2 +- actionpack/lib/action_dispatch/routing/route_set.rb | 3 +-- actionpack/lib/action_dispatch/routing/url_for.rb | 2 +- actionpack/test/controller/caching_test.rb | 4 ++-- actionpack/test/controller/url_rewriter_test.rb | 2 +- 5 files changed, 6 insertions(+), 7 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/test_case.rb b/actionpack/lib/action_controller/test_case.rb index 072d289964..cdb5db32aa 100644 --- a/actionpack/lib/action_controller/test_case.rb +++ b/actionpack/lib/action_controller/test_case.rb @@ -345,7 +345,7 @@ module ActionController :relative_url_root => nil, :_path_segments => @request.symbolized_path_parameters) - url, query_string = @router.rewrite(options).split("?", 2) + url, query_string = @router.url_for(options).split("?", 2) @request.env["SCRIPT_NAME"] = @controller.config.relative_url_root @request.env["PATH_INFO"] = url diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index aa1e25aa8b..2b9fc9e0de 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -403,8 +403,7 @@ module ActionDispatch RESERVED_OPTIONS = [:anchor, :params, :only_path, :host, :protocol, :port, :trailing_slash, :skip_relative_url_root] - # TODO: Terrible method name - def rewrite(options) + def url_for(options) handle_positional_args(options) rewritten_url = "" diff --git a/actionpack/lib/action_dispatch/routing/url_for.rb b/actionpack/lib/action_dispatch/routing/url_for.rb index 0ba04316d7..7ebd5e44e9 100644 --- a/actionpack/lib/action_dispatch/routing/url_for.rb +++ b/actionpack/lib/action_dispatch/routing/url_for.rb @@ -131,7 +131,7 @@ module ActionDispatch when String options when nil, Hash - _router.rewrite(url_options.merge(options || {})) + _router.url_for(url_options.merge(options || {})) else polymorphic_url(options) end diff --git a/actionpack/test/controller/caching_test.rb b/actionpack/test/controller/caching_test.rb index 08efd5a48c..8a0c118d3c 100644 --- a/actionpack/test/controller/caching_test.rb +++ b/actionpack/test/controller/caching_test.rb @@ -81,9 +81,9 @@ class PageCachingTest < ActionController::TestCase match '/', :to => 'posts#index', :as => :main end @params[:format] = 'rss' - assert_equal '/posts.rss', @router.rewrite(@params) + assert_equal '/posts.rss', @router.url_for(@params) @params[:format] = nil - assert_equal '/', @router.rewrite(@params) + assert_equal '/', @router.url_for(@params) end end diff --git a/actionpack/test/controller/url_rewriter_test.rb b/actionpack/test/controller/url_rewriter_test.rb index cf775846df..7b46a48a1d 100644 --- a/actionpack/test/controller/url_rewriter_test.rb +++ b/actionpack/test/controller/url_rewriter_test.rb @@ -11,7 +11,7 @@ class UrlRewriterTests < ActionController::TestCase end def rewrite(router, options) - router.rewrite(@options.merge(options)) + router.url_for(@options.merge(options)) end end -- cgit v1.2.3 From 1cc2a61ea655fea246f4c3e22a9e4a494e99d952 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Tue, 9 Mar 2010 21:20:13 -0600 Subject: Allow default_url_options to be set on route set --- actionpack/lib/action_dispatch/routing/mapper.rb | 5 +++++ actionpack/lib/action_dispatch/routing/route_set.rb | 4 ++++ actionpack/test/dispatch/routing_test.rb | 4 ++++ 3 files changed, 13 insertions(+) (limited to 'actionpack') diff --git a/actionpack/lib/action_dispatch/routing/mapper.rb b/actionpack/lib/action_dispatch/routing/mapper.rb index ae4470d033..0b7b09ee7a 100644 --- a/actionpack/lib/action_dispatch/routing/mapper.rb +++ b/actionpack/lib/action_dispatch/routing/mapper.rb @@ -180,6 +180,11 @@ module ActionDispatch @set.add_route(*mapping) self end + + def default_url_options=(options) + @set.default_url_options = options + end + alias_method :default_url_options, :default_url_options= end module HttpHelpers diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 2b9fc9e0de..26f37161a7 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -186,6 +186,7 @@ module ActionDispatch attr_accessor :routes, :named_routes attr_accessor :disable_clear_and_finalize, :resources_path_names + attr_accessor :default_url_options def self.default_resources_path_names { :new => 'new', :edit => 'edit' } @@ -196,6 +197,7 @@ module ActionDispatch self.named_routes = NamedRouteCollection.new self.resources_path_names = self.class.default_resources_path_names.dup self.controller_namespaces = Set.new + self.default_url_options = {} @disable_clear_and_finalize = false clear! @@ -404,6 +406,8 @@ module ActionDispatch RESERVED_OPTIONS = [:anchor, :params, :only_path, :host, :protocol, :port, :trailing_slash, :skip_relative_url_root] def url_for(options) + options = default_url_options.merge(options || {}) + handle_positional_args(options) rewritten_url = "" diff --git a/actionpack/test/dispatch/routing_test.rb b/actionpack/test/dispatch/routing_test.rb index b46276c453..f5fcf9b0df 100644 --- a/actionpack/test/dispatch/routing_test.rb +++ b/actionpack/test/dispatch/routing_test.rb @@ -15,6 +15,8 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest stub_controllers do |routes| Routes = routes Routes.draw do + default_url_options :host => "rubyonrails.org" + controller :sessions do get 'login' => :new, :as => :login post 'login' => :create @@ -189,6 +191,8 @@ class TestRoutingMapper < ActionDispatch::IntegrationTest assert_equal '/login', url_for(:controller => 'sessions', :action => 'create', :only_path => true) assert_equal '/login', url_for(:controller => 'sessions', :action => 'new', :only_path => true) + + assert_equal 'http://rubyonrails.org/login', Routes.url_for(:controller => 'sessions', :action => 'create') end end -- cgit v1.2.3 From dcd110c724aa5111e67e7264e6bc76ebdda6d50f Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Tue, 9 Mar 2010 21:25:09 -0600 Subject: skip_relative_url_root url_for option is dead --- actionpack/lib/action_controller/caching/pages.rb | 6 +++--- actionpack/lib/action_dispatch/routing/route_set.rb | 2 +- actionpack/lib/action_dispatch/routing/url_for.rb | 2 -- actionpack/test/controller/caching_test.rb | 2 +- 4 files changed, 5 insertions(+), 7 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/caching/pages.rb b/actionpack/lib/action_controller/caching/pages.rb index 36a97d390c..fe95f0e0d7 100644 --- a/actionpack/lib/action_controller/caching/pages.rb +++ b/actionpack/lib/action_controller/caching/pages.rb @@ -121,10 +121,10 @@ module ActionController #:nodoc: if options.is_a?(Hash) if options[:action].is_a?(Array) options[:action].dup.each do |action| - self.class.expire_page(url_for(options.merge(:only_path => true, :skip_relative_url_root => true, :action => action))) + self.class.expire_page(url_for(options.merge(:only_path => true, :action => action))) end else - self.class.expire_page(url_for(options.merge(:only_path => true, :skip_relative_url_root => true))) + self.class.expire_page(url_for(options.merge(:only_path => true))) end else self.class.expire_page(options) @@ -139,7 +139,7 @@ module ActionController #:nodoc: path = case options when Hash - url_for(options.merge(:only_path => true, :skip_relative_url_root => true, :format => params[:format])) + url_for(options.merge(:only_path => true, :format => params[:format])) when String options else diff --git a/actionpack/lib/action_dispatch/routing/route_set.rb b/actionpack/lib/action_dispatch/routing/route_set.rb index 26f37161a7..722be432c7 100644 --- a/actionpack/lib/action_dispatch/routing/route_set.rb +++ b/actionpack/lib/action_dispatch/routing/route_set.rb @@ -403,7 +403,7 @@ module ActionDispatch Generator.new(options, recall, @set, extras).generate end - RESERVED_OPTIONS = [:anchor, :params, :only_path, :host, :protocol, :port, :trailing_slash, :skip_relative_url_root] + RESERVED_OPTIONS = [:anchor, :params, :only_path, :host, :protocol, :port, :trailing_slash] def url_for(options) options = default_url_options.merge(options || {}) diff --git a/actionpack/lib/action_dispatch/routing/url_for.rb b/actionpack/lib/action_dispatch/routing/url_for.rb index 7ebd5e44e9..ec78f53fa6 100644 --- a/actionpack/lib/action_dispatch/routing/url_for.rb +++ b/actionpack/lib/action_dispatch/routing/url_for.rb @@ -113,8 +113,6 @@ module ActionDispatch # provided either explicitly, or via +default_url_options+. # * :port - Optionally specify the port to connect to. # * :anchor - An anchor name to be appended to the path. - # * :skip_relative_url_root - If true, the url is not constructed using the - # +relative_url_root+ set in ActionController::Base.relative_url_root. # * :trailing_slash - If true, adds a trailing slash, as in "/archive/2009/" # # Any other key (:controller, :action, etc.) given to diff --git a/actionpack/test/controller/caching_test.rb b/actionpack/test/controller/caching_test.rb index 8a0c118d3c..a3c8fdbb6e 100644 --- a/actionpack/test/controller/caching_test.rb +++ b/actionpack/test/controller/caching_test.rb @@ -63,7 +63,7 @@ class PageCachingTest < ActionController::TestCase @controller = PageCachingTestController.new @controller.cache_store = :file_store, FILE_STORE_PATH - @params = {:controller => 'posts', :action => 'index', :only_path => true, :skip_relative_url_root => true} + @params = {:controller => 'posts', :action => 'index', :only_path => true} FileUtils.rm_rf(File.dirname(FILE_STORE_PATH)) FileUtils.mkdir_p(FILE_STORE_PATH) -- cgit v1.2.3 From 4464b8e87bedd69816d4658c9386cc360affb62e Mon Sep 17 00:00:00 2001 From: Carlhuda Date: Tue, 9 Mar 2010 18:00:28 -0800 Subject: Deprecate block_called_from_erb? pending a solution for getting it into apps --- actionpack/lib/action_view/helpers.rb | 1 + .../lib/action_view/helpers/capture_helper.rb | 14 ++--- .../helpers/deprecated_block_helpers.rb | 35 +++++++++++++ .../lib/action_view/helpers/javascript_helper.rb | 8 +-- actionpack/lib/action_view/helpers/tag_helper.rb | 26 ++-------- .../lib/action_view/template/handlers/erb.rb | 46 +++++++++++++++-- actionpack/test/template/erb/tag_helper_test.rb | 60 ++++++++++++++++++++++ actionpack/test/template/javascript_helper_test.rb | 12 ----- actionpack/test/template/tag_helper_test.rb | 16 +++--- 9 files changed, 154 insertions(+), 64 deletions(-) create mode 100644 actionpack/lib/action_view/helpers/deprecated_block_helpers.rb create mode 100644 actionpack/test/template/erb/tag_helper_test.rb (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers.rb b/actionpack/lib/action_view/helpers.rb index b4f649385a..e359b0bdac 100644 --- a/actionpack/lib/action_view/helpers.rb +++ b/actionpack/lib/action_view/helpers.rb @@ -10,6 +10,7 @@ module ActionView #:nodoc: autoload :CsrfHelper, 'action_view/helpers/csrf_helper' autoload :DateHelper, 'action_view/helpers/date_helper' autoload :DebugHelper, 'action_view/helpers/debug_helper' + autoload :DeprecatedBlockHelpers, 'action_view/helpers/deprecated_block_helpers' autoload :FormHelper, 'action_view/helpers/form_helper' autoload :FormOptionsHelper, 'action_view/helpers/form_options_helper' autoload :FormTagHelper, 'action_view/helpers/form_tag_helper' diff --git a/actionpack/lib/action_view/helpers/capture_helper.rb b/actionpack/lib/action_view/helpers/capture_helper.rb index 8c48300ed3..75fc2fddeb 100644 --- a/actionpack/lib/action_view/helpers/capture_helper.rb +++ b/actionpack/lib/action_view/helpers/capture_helper.rb @@ -30,14 +30,10 @@ module ActionView # <%= @greeting %> # # - def capture(*args, &block) - # Return captured buffer in erb. - if block_called_from_erb?(block) - with_output_buffer { block.call(*args) } - else - # Return block result otherwise, but protect buffer also. - with_output_buffer { return block.call(*args) } - end + def capture(*args) + value = nil + buffer = with_output_buffer { value = yield *args } + buffer.presence || value end # Calling content_for stores a block of markup in an identifier for later use. @@ -143,7 +139,7 @@ module ActionView # Defaults to a new empty string. def with_output_buffer(buf = nil) #:nodoc: unless buf - buf = ActiveSupport::SafeBuffer.new + buf = ActionView::OutputBuffer.new buf.force_encoding(output_buffer.encoding) if buf.respond_to?(:force_encoding) end self.output_buffer, old_buffer = buf, output_buffer diff --git a/actionpack/lib/action_view/helpers/deprecated_block_helpers.rb b/actionpack/lib/action_view/helpers/deprecated_block_helpers.rb new file mode 100644 index 0000000000..ffbffbf25e --- /dev/null +++ b/actionpack/lib/action_view/helpers/deprecated_block_helpers.rb @@ -0,0 +1,35 @@ +module ActionView + module Helpers + module DeprecatedBlockHelpers + extend ActiveSupport::Concern + + include ActionView::Helpers::TagHelper + include ActionView::Helpers::TextHelper + include ActionView::Helpers::JavaScriptHelper + + def content_tag(*, &block) + block_called_from_erb?(block) ? safe_concat(super) : super + end + + def javascript_tag(*, &block) + block_called_from_erb?(block) ? safe_concat(super) : super + end + + BLOCK_CALLED_FROM_ERB = 'defined? __in_erb_template' + + if RUBY_VERSION < '1.9.0' + # Check whether we're called from an erb template. + # We'd return a string in any other case, but erb <%= ... %> + # can't take an <% end %> later on, so we have to use <% ... %> + # and implicitly concat. + def block_called_from_erb?(block) + block && eval(BLOCK_CALLED_FROM_ERB, block) + end + else + def block_called_from_erb?(block) + block && eval(BLOCK_CALLED_FROM_ERB, block.binding) + end + end + end + end +end \ No newline at end of file diff --git a/actionpack/lib/action_view/helpers/javascript_helper.rb b/actionpack/lib/action_view/helpers/javascript_helper.rb index 2c73ff88f7..8dab3094dd 100644 --- a/actionpack/lib/action_view/helpers/javascript_helper.rb +++ b/actionpack/lib/action_view/helpers/javascript_helper.rb @@ -83,13 +83,7 @@ module ActionView content_or_options_with_block end - tag = content_tag(:script, javascript_cdata_section(content), html_options.merge(:type => Mime::JS)) - - if block_called_from_erb?(block) - safe_concat(tag) - else - tag - end + content_tag(:script, javascript_cdata_section(content), html_options.merge(:type => Mime::JS)) end def javascript_cdata_section(content) #:nodoc: diff --git a/actionpack/lib/action_view/helpers/tag_helper.rb b/actionpack/lib/action_view/helpers/tag_helper.rb index 513d72880c..d9d2588a2a 100644 --- a/actionpack/lib/action_view/helpers/tag_helper.rb +++ b/actionpack/lib/action_view/helpers/tag_helper.rb @@ -7,6 +7,9 @@ module ActionView module TagHelper include ERB::Util + extend ActiveSupport::Concern + include CaptureHelper + BOOLEAN_ATTRIBUTES = %w(disabled readonly multiple checked autobuffer autoplay controls loop selected hidden scoped async defer reversed ismap seemless muted required @@ -69,13 +72,7 @@ module ActionView def content_tag(name, content_or_options_with_block = nil, options = nil, escape = true, &block) if block_given? options = content_or_options_with_block if content_or_options_with_block.is_a?(Hash) - content_tag = content_tag_string(name, capture(&block), options, escape) - - if block_called_from_erb?(block) - safe_concat(content_tag) - else - content_tag - end + content_tag_string(name, capture(&block), options, escape) else content_tag_string(name, content_or_options_with_block, options, escape) end @@ -109,21 +106,6 @@ module ActionView end private - BLOCK_CALLED_FROM_ERB = 'defined? __in_erb_template' - - if RUBY_VERSION < '1.9.0' - # Check whether we're called from an erb template. - # We'd return a string in any other case, but erb <%= ... %> - # can't take an <% end %> later on, so we have to use <% ... %> - # and implicitly concat. - def block_called_from_erb?(block) - block && eval(BLOCK_CALLED_FROM_ERB, block) - end - else - def block_called_from_erb?(block) - block && eval(BLOCK_CALLED_FROM_ERB, block.binding) - end - end def content_tag_string(name, content, options, escape = true) tag_options = tag_options(options, escape) if options diff --git a/actionpack/lib/action_view/template/handlers/erb.rb b/actionpack/lib/action_view/template/handlers/erb.rb index 4b7cec50f3..3fcae167ff 100644 --- a/actionpack/lib/action_view/template/handlers/erb.rb +++ b/actionpack/lib/action_view/template/handlers/erb.rb @@ -3,10 +3,46 @@ require 'active_support/core_ext/string/output_safety' require 'erubis' module ActionView + class OutputBuffer + def initialize + @buffer = ActiveSupport::SafeBuffer.new + end + + def safe_concat(value) + @buffer.safe_concat(value) + end + + def <<(value) + @buffer << value.to_s + end + + def length + @buffer.length + end + + def [](*args) + @buffer[*args] + end + + def to_s + @buffer.to_s + end + + def empty? + @buffer.empty? + end + + if "".respond_to?(:force_encoding) + def force_encoding(encoding) + @buffer.force_encoding(encoding) + end + end + end + module Template::Handlers class Erubis < ::Erubis::Eruby def add_preamble(src) - src << "@output_buffer = ActiveSupport::SafeBuffer.new;" + src << "@output_buffer = ActionView::OutputBuffer.new;" end def add_text(src, text) @@ -15,10 +51,10 @@ module ActionView end def add_expr_literal(src, code) - if code =~ /\s*raw\s+(.*)/ - src << "@output_buffer.safe_concat((" << $1 << ").to_s);" + if code =~ /(do|\{)(\s*\|[^|]*\|)?\s*\Z/ + src << '@output_buffer << ' << code else - src << '@output_buffer << ((' << code << ').to_s);' + src << '@output_buffer << (' << code << ');' end end @@ -42,7 +78,7 @@ module ActionView self.erb_trim_mode = '-' self.default_format = Mime::HTML - + cattr_accessor :erb_implementation self.erb_implementation = Erubis diff --git a/actionpack/test/template/erb/tag_helper_test.rb b/actionpack/test/template/erb/tag_helper_test.rb new file mode 100644 index 0000000000..d9ca828b43 --- /dev/null +++ b/actionpack/test/template/erb/tag_helper_test.rb @@ -0,0 +1,60 @@ +require "abstract_unit" + +module ERBTest + module SharedTagHelpers + extend ActiveSupport::Testing::Declarative + + def render_content(start, inside) + template = block_helper(start, inside) + ActionView::Template::Handlers::Erubis.new(template).evaluate(context.new) + end + + test "percent equals works for content_tag" do + assert_equal "
Hello world
", render_content("content_tag(:div)", "Hello world") + end + + test "percent equals works for javascript_tag" do + expected_output = "" + assert_equal expected_output, render_content("javascript_tag", "alert('Hello')") + end + + test "percent equals works for javascript_tag with options" do + expected_output = "" + assert_equal expected_output, render_content("javascript_tag(:id => 'the_js_tag')", "alert('Hello')") + end + end + + class TagHelperTest < ActiveSupport::TestCase + def context + Class.new do + include ActionView::Helpers::TagHelper + include ActionView::Helpers::JavaScriptHelper + + attr_accessor :output_buffer + end + end + + def block_helper(str, rest) + "<%= #{str} do %>#{rest}<% end %>" + end + + include SharedTagHelpers + end + + class DeprecatedTagHelperTest < ActiveSupport::TestCase + def context + Class.new do + include ActionView::Helpers::TagHelper + include ActionView::Helpers::JavaScriptHelper + include ActionView::Helpers::DeprecatedBlockHelpers + attr_accessor :output_buffer + end + end + + def block_helper(str, rest) + "<% __in_erb_template=true %><% #{str} do %>#{rest}<% end %>" + end + + include SharedTagHelpers + end +end \ No newline at end of file diff --git a/actionpack/test/template/javascript_helper_test.rb b/actionpack/test/template/javascript_helper_test.rb index 6604f1c095..f49b763881 100644 --- a/actionpack/test/template/javascript_helper_test.rb +++ b/actionpack/test/template/javascript_helper_test.rb @@ -74,18 +74,6 @@ class JavaScriptHelperTest < ActionView::TestCase javascript_tag("alert('hello')", :id => "the_js_tag") end - def test_javascript_tag_with_block_in_erb - __in_erb_template = '' - javascript_tag { concat "alert('hello')" } - assert_dom_equal "", output_buffer - end - - def test_javascript_tag_with_block_and_options_in_erb - __in_erb_template = '' - javascript_tag(:id => "the_js_tag") { concat "alert('hello')" } - assert_dom_equal "", output_buffer - end - def test_javascript_cdata_section assert_dom_equal "\n//\n", javascript_cdata_section("alert('hello')") end diff --git a/actionpack/test/template/tag_helper_test.rb b/actionpack/test/template/tag_helper_test.rb index 3858ffde40..256d9bdcde 100644 --- a/actionpack/test/template/tag_helper_test.rb +++ b/actionpack/test/template/tag_helper_test.rb @@ -42,15 +42,13 @@ class TagHelperTest < ActionView::TestCase end def test_content_tag_with_block_in_erb - __in_erb_template = '' - content_tag(:div) { concat "Hello world!" } - assert_dom_equal "
Hello world!
", output_buffer + buffer = content_tag(:div) { concat "Hello world!" } + assert_dom_equal "
Hello world!
", buffer end def test_content_tag_with_block_and_options_in_erb - __in_erb_template = '' - content_tag(:div, :class => "green") { concat "Hello world!" } - assert_dom_equal %(
Hello world!
), output_buffer + buffer = content_tag(:div, :class => "green") { concat "Hello world!" } + assert_dom_equal %(
Hello world!
), buffer end def test_content_tag_with_block_and_options_out_of_erb @@ -68,10 +66,10 @@ class TagHelperTest < ActionView::TestCase output_buffer end + # TAG TODO: Move this into a real template def test_content_tag_nested_in_content_tag_in_erb - __in_erb_template = true - content_tag("p") { concat content_tag("b", "Hello") } - assert_equal '

Hello

', output_buffer + buffer = content_tag("p") { concat content_tag("b", "Hello") } + assert_equal '

Hello

', buffer end def test_content_tag_with_escaped_array_class -- cgit v1.2.3 From 7b622786fcc5046a06989ec7a3cbf46f92e04dea Mon Sep 17 00:00:00 2001 From: wycats Date: Tue, 9 Mar 2010 23:41:39 -0800 Subject: Make form helpers work with <%= --- .../helpers/deprecated_block_helpers.rb | 17 +++ actionpack/lib/action_view/helpers/form_helper.rb | 23 +++- .../lib/action_view/helpers/form_options_helper.rb | 2 + .../lib/action_view/helpers/form_tag_helper.rb | 20 ++- .../lib/action_view/template/handlers/erb.rb | 8 ++ actionpack/test/template/date_helper_test.rb | 14 +- actionpack/test/template/erb/tag_helper_test.rb | 46 +++++-- actionpack/test/template/form_helper_test.rb | 144 +++++++++++---------- .../test/template/form_options_helper_test.rb | 22 ++-- actionpack/test/template/form_tag_helper_test.rb | 18 +-- 10 files changed, 188 insertions(+), 126 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/deprecated_block_helpers.rb b/actionpack/lib/action_view/helpers/deprecated_block_helpers.rb index ffbffbf25e..3d0657e873 100644 --- a/actionpack/lib/action_view/helpers/deprecated_block_helpers.rb +++ b/actionpack/lib/action_view/helpers/deprecated_block_helpers.rb @@ -6,6 +6,7 @@ module ActionView include ActionView::Helpers::TagHelper include ActionView::Helpers::TextHelper include ActionView::Helpers::JavaScriptHelper + include ActionView::Helpers::FormHelper def content_tag(*, &block) block_called_from_erb?(block) ? safe_concat(super) : super @@ -15,6 +16,22 @@ module ActionView block_called_from_erb?(block) ? safe_concat(super) : super end + def form_for(*, &block) + block_called_from_erb?(block) ? safe_concat(super) : super + end + + def form_tag(*, &block) + block_called_from_erb?(block) ? safe_concat(super) : super + end + + def fields_for(*, &block) + block_called_from_erb?(block) ? safe_concat(super) : super + end + + def field_set_tag(*, &block) + block_called_from_erb?(block) ? safe_concat(super) : super + end + BLOCK_CALLED_FROM_ERB = 'defined? __in_erb_template' if RUBY_VERSION < '1.9.0' diff --git a/actionpack/lib/action_view/helpers/form_helper.rb b/actionpack/lib/action_view/helpers/form_helper.rb index 742e873a49..48df26efaa 100644 --- a/actionpack/lib/action_view/helpers/form_helper.rb +++ b/actionpack/lib/action_view/helpers/form_helper.rb @@ -92,6 +92,10 @@ module ActionView # link:classes/ActionView/Helpers/DateHelper.html, and # link:classes/ActionView/Helpers/ActiveRecordHelper.html module FormHelper + extend ActiveSupport::Concern + + include FormTagHelper + # Creates a form and a scope around a specific model object that is used # as a base for questioning about values for the fields. # @@ -309,9 +313,9 @@ module ActionView options[:html][:remote] = true if options.delete(:remote) - safe_concat(form_tag(options.delete(:url) || {}, options.delete(:html) || {})) - fields_for(object_name, *(args << options), &proc) - safe_concat('') + output = form_tag(options.delete(:url) || {}, options.delete(:html) || {}) + output << fields_for(object_name, *(args << options), &proc) + output.safe_concat('') end def apply_form_for_options!(object_or_array, options) #:nodoc: @@ -528,7 +532,10 @@ module ActionView end builder = options[:builder] || ActionView::Base.default_form_builder - yield builder.new(object_name, object, self, options, block) + + with_output_buffer do + yield builder.new(object_name, object, self, options, block) + end end # Returns a label tag tailored for labelling an input field for a specified attribute (identified by +method+) on an object @@ -1183,9 +1190,11 @@ module ActionView if association.is_a?(Array) explicit_child_index = options[:child_index] - association.map do |child| - fields_for_nested_model("#{name}[#{explicit_child_index || nested_child_index(name)}]", child, options, block) - end.join + output = ActiveSupport::SafeBuffer.new + association.each do |child| + output << fields_for_nested_model("#{name}[#{explicit_child_index || nested_child_index(name)}]", child, options, block) + end + output elsif association fields_for_nested_model(name, association, options, block) end diff --git a/actionpack/lib/action_view/helpers/form_options_helper.rb b/actionpack/lib/action_view/helpers/form_options_helper.rb index 7f74be27cb..7039ecd233 100644 --- a/actionpack/lib/action_view/helpers/form_options_helper.rb +++ b/actionpack/lib/action_view/helpers/form_options_helper.rb @@ -97,7 +97,9 @@ module ActionView # # module FormOptionsHelper + # ERB::Util can mask some helpers like textilize. Make sure to include them. include ERB::Util + include TextHelper # Create a select tag and a series of contained option tags for the provided object and method. # The option currently held by the object will be selected, provided that the object is available. diff --git a/actionpack/lib/action_view/helpers/form_tag_helper.rb b/actionpack/lib/action_view/helpers/form_tag_helper.rb index 7dcaee7e34..573733ffea 100644 --- a/actionpack/lib/action_view/helpers/form_tag_helper.rb +++ b/actionpack/lib/action_view/helpers/form_tag_helper.rb @@ -10,6 +10,11 @@ module ActionView # NOTE: The HTML options disabled, readonly, and multiple can all be treated as booleans. So specifying # :disabled => true will give disabled="disabled". module FormTagHelper + extend ActiveSupport::Concern + + include UrlHelper + include TextHelper + # Starts a form tag that points the action to an url configured with url_for_options just like # ActionController::Base#url_for. The method for the form defaults to POST. # @@ -441,10 +446,10 @@ module ActionView # # =>

def field_set_tag(legend = nil, options = nil, &block) content = capture(&block) - safe_concat(tag(:fieldset, options, true)) - safe_concat(content_tag(:legend, legend)) unless legend.blank? - concat(content) - safe_concat("") + output = tag(:fieldset, options, true) + output.safe_concat(content_tag(:legend, legend)) unless legend.blank? + output.concat(content) + output.safe_concat("") end private @@ -477,9 +482,10 @@ module ActionView def form_tag_in_block(html_options, &block) content = capture(&block) - safe_concat(form_tag_html(html_options)) - concat(content) - safe_concat("") + output = ActiveSupport::SafeBuffer.new + output.safe_concat(form_tag_html(html_options)) + output << content + output.safe_concat("") end def token_tag diff --git a/actionpack/lib/action_view/template/handlers/erb.rb b/actionpack/lib/action_view/template/handlers/erb.rb index 3fcae167ff..937694ce8e 100644 --- a/actionpack/lib/action_view/template/handlers/erb.rb +++ b/actionpack/lib/action_view/template/handlers/erb.rb @@ -28,10 +28,18 @@ module ActionView @buffer.to_s end + def to_str + @buffer.to_str + end + def empty? @buffer.empty? end + def html_safe? + @buffer.html_safe? + end + if "".respond_to?(:force_encoding) def force_encoding(encoding) @buffer.force_encoding(encoding) diff --git a/actionpack/test/template/date_helper_test.rb b/actionpack/test/template/date_helper_test.rb index 9a2d490854..da2477b6f8 100644 --- a/actionpack/test/template/date_helper_test.rb +++ b/actionpack/test/template/date_helper_test.rb @@ -1250,7 +1250,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.written_on = Date.new(2004, 6, 15) - fields_for :post, @post do |f| + output_buffer = fields_for :post, @post do |f| concat f.date_select(:written_on) end @@ -1266,7 +1266,7 @@ class DateHelperTest < ActionView::TestCase @post.written_on = Date.new(2004, 6, 15) id = 27 - fields_for :post, @post, :index => id do |f| + output_buffer = fields_for :post, @post, :index => id do |f| concat f.date_select(:written_on) end @@ -1282,7 +1282,7 @@ class DateHelperTest < ActionView::TestCase @post.written_on = Date.new(2004, 6, 15) id = nil - fields_for :post, @post, :index => id do |f| + output_buffer = fields_for :post, @post, :index => id do |f| concat f.date_select(:written_on) end @@ -1478,7 +1478,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.written_on = Date.new(2004, 6, 15) - fields_for :post, @post do |f| + output_buffer = fields_for :post, @post do |f| concat f.date_select(:written_on, {}, :class => 'selector') end @@ -1642,7 +1642,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.written_on = Time.local(2004, 6, 15, 15, 16, 35) - fields_for :post, @post do |f| + output_buffer = fields_for :post, @post do |f| concat f.time_select(:written_on, {}, :class => 'selector') end @@ -1816,7 +1816,7 @@ class DateHelperTest < ActionView::TestCase @post = Post.new @post.updated_at = Time.local(2004, 6, 15, 16, 35) - fields_for :post, @post do |f| + output_buffer = fields_for :post, @post do |f| concat f.datetime_select(:updated_at, {}, :class => 'selector') end @@ -2052,7 +2052,7 @@ class DateHelperTest < ActionView::TestCase @post.updated_at = Time.local(2004, 6, 15, 16, 35) id = 456 - fields_for :post, @post, :index => id do |f| + output_buffer = fields_for :post, @post, :index => id do |f| concat f.datetime_select(:updated_at) end diff --git a/actionpack/test/template/erb/tag_helper_test.rb b/actionpack/test/template/erb/tag_helper_test.rb index d9ca828b43..b91539ef0b 100644 --- a/actionpack/test/template/erb/tag_helper_test.rb +++ b/actionpack/test/template/erb/tag_helper_test.rb @@ -1,6 +1,28 @@ require "abstract_unit" module ERBTest + class ViewContext + mock_controller = Class.new do + include SharedTestRoutes.url_helpers + end + + include ActionView::Helpers::TagHelper + include ActionView::Helpers::JavaScriptHelper + include ActionView::Helpers::FormHelper + + attr_accessor :output_buffer + + def protect_against_forgery?() false end + + define_method(:controller) do + mock_controller.new + end + end + + class DeprecatedViewContext < ViewContext + include ActionView::Helpers::DeprecatedBlockHelpers + end + module SharedTagHelpers extend ActiveSupport::Testing::Declarative @@ -22,16 +44,21 @@ module ERBTest expected_output = "" assert_equal expected_output, render_content("javascript_tag(:id => 'the_js_tag')", "alert('Hello')") end + + test "percent equals works with form tags" do + expected_output = "
hello
" + assert_equal expected_output, render_content("form_tag('foo')", "<%= 'hello' %>") + end + + test "percent equals works with fieldset tags" do + expected_output = "
foohello
" + assert_equal expected_output, render_content("field_set_tag('foo')", "<%= 'hello' %>") + end end class TagHelperTest < ActiveSupport::TestCase def context - Class.new do - include ActionView::Helpers::TagHelper - include ActionView::Helpers::JavaScriptHelper - - attr_accessor :output_buffer - end + ViewContext end def block_helper(str, rest) @@ -43,12 +70,7 @@ module ERBTest class DeprecatedTagHelperTest < ActiveSupport::TestCase def context - Class.new do - include ActionView::Helpers::TagHelper - include ActionView::Helpers::JavaScriptHelper - include ActionView::Helpers::DeprecatedBlockHelpers - attr_accessor :output_buffer - end + DeprecatedViewContext end def block_helper(str, rest) diff --git a/actionpack/test/template/form_helper_test.rb b/actionpack/test/template/form_helper_test.rb index d143c39c9c..7c5ccfd6ed 100644 --- a/actionpack/test/template/form_helper_test.rb +++ b/actionpack/test/template/form_helper_test.rb @@ -4,6 +4,10 @@ require 'controller/fake_models' class FormHelperTest < ActionView::TestCase tests ActionView::Helpers::FormHelper + def form_for(*) + @output_buffer = super + end + def setup super @@ -590,9 +594,9 @@ class FormHelperTest < ActionView::TestCase def test_nested_fields_for form_for(:post, @post) do |f| - f.fields_for(:comment, @post) do |c| + concat f.fields_for(:comment, @post) { |c| concat c.text_field(:title) - end + } end expected = "
" + @@ -605,9 +609,9 @@ class FormHelperTest < ActionView::TestCase def test_nested_fields_for_with_nested_collections form_for('post[]', @post) do |f| concat f.text_field(:title) - f.fields_for('comment[]', @comment) do |c| + concat f.fields_for('comment[]', @comment) { |c| concat c.text_field(:name) - end + } end expected = "" + @@ -621,9 +625,9 @@ class FormHelperTest < ActionView::TestCase def test_nested_fields_for_with_index_and_parent_fields form_for('post', @post, :index => 1) do |c| concat c.text_field(:title) - c.fields_for('comment', @comment, :index => 1) do |r| + concat c.fields_for('comment', @comment, :index => 1) { |r| concat r.text_field(:name) - end + } end expected = "" + @@ -635,10 +639,10 @@ class FormHelperTest < ActionView::TestCase end def test_form_for_with_index_and_nested_fields_for - form_for(:post, @post, :index => 1) do |f| - f.fields_for(:comment, @post) do |c| + output_buffer = form_for(:post, @post, :index => 1) do |f| + concat f.fields_for(:comment, @post) { |c| concat c.text_field(:title) - end + } end expected = "" + @@ -650,9 +654,9 @@ class FormHelperTest < ActionView::TestCase def test_nested_fields_for_with_index_on_both form_for(:post, @post, :index => 1) do |f| - f.fields_for(:comment, @post, :index => 5) do |c| + concat f.fields_for(:comment, @post, :index => 5) { |c| concat c.text_field(:title) - end + } end expected = "" + @@ -664,9 +668,9 @@ class FormHelperTest < ActionView::TestCase def test_nested_fields_for_with_auto_index form_for("post[]", @post) do |f| - f.fields_for(:comment, @post) do |c| + concat f.fields_for(:comment, @post) { |c| concat c.text_field(:title) - end + } end expected = "" + @@ -678,9 +682,9 @@ class FormHelperTest < ActionView::TestCase def test_nested_fields_for_with_index_radio_button form_for(:post, @post) do |f| - f.fields_for(:comment, @post, :index => 5) do |c| + concat f.fields_for(:comment, @post, :index => 5) { |c| concat c.radio_button(:title, "hello") - end + } end expected = "" + @@ -692,9 +696,9 @@ class FormHelperTest < ActionView::TestCase def test_nested_fields_for_with_auto_index_on_both form_for("post[]", @post) do |f| - f.fields_for("comment[]", @post) do |c| + concat f.fields_for("comment[]", @post) { |c| concat c.text_field(:title) - end + } end expected = "" + @@ -705,16 +709,16 @@ class FormHelperTest < ActionView::TestCase end def test_nested_fields_for_with_index_and_auto_index - form_for("post[]", @post) do |f| - f.fields_for(:comment, @post, :index => 5) do |c| + output_buffer = form_for("post[]", @post) do |f| + concat f.fields_for(:comment, @post, :index => 5) { |c| concat c.text_field(:title) - end + } end - form_for(:post, @post, :index => 1) do |f| - f.fields_for("comment[]", @post) do |c| + output_buffer << form_for(:post, @post, :index => 1) do |f| + concat f.fields_for("comment[]", @post) { |c| concat c.text_field(:title) - end + } end expected = "" + @@ -732,9 +736,9 @@ class FormHelperTest < ActionView::TestCase form_for(:post, @post) do |f| concat f.text_field(:title) - f.fields_for(:author) do |af| + concat f.fields_for(:author) { |af| concat af.text_field(:name) - end + } end expected = '' + @@ -759,9 +763,9 @@ class FormHelperTest < ActionView::TestCase form_for(:post, @post) do |f| concat f.text_field(:title) - f.fields_for(:author) do |af| + concat f.fields_for(:author) { |af| concat af.text_field(:name) - end + } end expected = '' + @@ -778,10 +782,10 @@ class FormHelperTest < ActionView::TestCase form_for(:post, @post) do |f| concat f.text_field(:title) - f.fields_for(:author) do |af| + concat f.fields_for(:author) { |af| concat af.hidden_field(:id) concat af.text_field(:name) - end + } end expected = '' + @@ -799,9 +803,9 @@ class FormHelperTest < ActionView::TestCase form_for(:post, @post) do |f| concat f.text_field(:title) @post.comments.each do |comment| - f.fields_for(:comments, comment) do |cf| + concat f.fields_for(:comments, comment) { |cf| concat cf.text_field(:name) - end + } end end @@ -822,10 +826,10 @@ class FormHelperTest < ActionView::TestCase form_for(:post, @post) do |f| concat f.text_field(:title) @post.comments.each do |comment| - f.fields_for(:comments, comment) do |cf| + concat f.fields_for(:comments, comment) { |cf| concat cf.hidden_field(:id) concat cf.text_field(:name) - end + } end end @@ -846,9 +850,9 @@ class FormHelperTest < ActionView::TestCase form_for(:post, @post) do |f| concat f.text_field(:title) @post.comments.each do |comment| - f.fields_for(:comments, comment) do |cf| + concat f.fields_for(:comments, comment) { |cf| concat cf.text_field(:name) - end + } end end @@ -867,9 +871,9 @@ class FormHelperTest < ActionView::TestCase form_for(:post, @post) do |f| concat f.text_field(:title) @post.comments.each do |comment| - f.fields_for(:comments, comment) do |cf| + concat f.fields_for(:comments, comment) { |cf| concat cf.text_field(:name) - end + } end end @@ -903,9 +907,9 @@ class FormHelperTest < ActionView::TestCase form_for(:post, @post) do |f| concat f.text_field(:title) - f.fields_for(:comments, @post.comments) do |cf| + concat f.fields_for(:comments, @post.comments) { |cf| concat cf.text_field(:name) - end + } end expected = '' + @@ -925,9 +929,9 @@ class FormHelperTest < ActionView::TestCase form_for(:post, @post) do |f| concat f.text_field(:title) - f.fields_for(:comments, comments) do |cf| + concat f.fields_for(:comments, comments) { |cf| concat cf.text_field(:name) - end + } end expected = '' + @@ -947,10 +951,10 @@ class FormHelperTest < ActionView::TestCase form_for(:post, @post) do |f| concat f.text_field(:title) - f.fields_for(:comments) do |cf| + concat f.fields_for(:comments) { |cf| concat cf.text_field(:name) yielded_comments << cf.object - end + } end expected = '' + @@ -968,9 +972,9 @@ class FormHelperTest < ActionView::TestCase @post.comments = [] form_for(:post, @post) do |f| - f.fields_for(:comments, Comment.new(321), :child_index => 'abc') do |cf| + concat f.fields_for(:comments, Comment.new(321), :child_index => 'abc') { |cf| concat cf.text_field(:name) - end + } end expected = '' + @@ -988,24 +992,24 @@ class FormHelperTest < ActionView::TestCase @post.tags[0].relevances = [] @post.tags[1].relevances = [] form_for(:post, @post) do |f| - f.fields_for(:comments, @post.comments[0]) do |cf| + concat f.fields_for(:comments, @post.comments[0]) { |cf| concat cf.text_field(:name) - cf.fields_for(:relevances, CommentRelevance.new(314)) do |crf| + concat cf.fields_for(:relevances, CommentRelevance.new(314)) { |crf| concat crf.text_field(:value) - end - end - f.fields_for(:tags, @post.tags[0]) do |tf| + } + } + concat f.fields_for(:tags, @post.tags[0]) { |tf| concat tf.text_field(:value) - tf.fields_for(:relevances, TagRelevance.new(3141)) do |trf| + concat tf.fields_for(:relevances, TagRelevance.new(3141)) { |trf| concat trf.text_field(:value) - end - end - f.fields_for('tags', @post.tags[1]) do |tf| + } + } + concat f.fields_for('tags', @post.tags[1]) { |tf| concat tf.text_field(:value) - tf.fields_for(:relevances, TagRelevance.new(31415)) do |trf| + concat tf.fields_for(:relevances, TagRelevance.new(31415)) { |trf| concat trf.text_field(:value) - end - end + } + } end expected = '' + @@ -1027,7 +1031,7 @@ class FormHelperTest < ActionView::TestCase end def test_fields_for - fields_for(:post, @post) do |f| + output_buffer = fields_for(:post, @post) do |f| concat f.text_field(:title) concat f.text_area(:body) concat f.check_box(:secret) @@ -1043,7 +1047,7 @@ class FormHelperTest < ActionView::TestCase end def test_fields_for_with_index - fields_for("post[]", @post) do |f| + output_buffer = fields_for("post[]", @post) do |f| concat f.text_field(:title) concat f.text_area(:body) concat f.check_box(:secret) @@ -1059,7 +1063,7 @@ class FormHelperTest < ActionView::TestCase end def test_fields_for_with_nil_index_option_override - fields_for("post[]", @post, :index => nil) do |f| + output_buffer = fields_for("post[]", @post, :index => nil) do |f| concat f.text_field(:title) concat f.text_area(:body) concat f.check_box(:secret) @@ -1075,7 +1079,7 @@ class FormHelperTest < ActionView::TestCase end def test_fields_for_with_index_option_override - fields_for("post[]", @post, :index => "abc") do |f| + output_buffer = fields_for("post[]", @post, :index => "abc") do |f| concat f.text_field(:title) concat f.text_area(:body) concat f.check_box(:secret) @@ -1091,7 +1095,7 @@ class FormHelperTest < ActionView::TestCase end def test_fields_for_without_object - fields_for(:post) do |f| + output_buffer = fields_for(:post) do |f| concat f.text_field(:title) concat f.text_area(:body) concat f.check_box(:secret) @@ -1107,7 +1111,7 @@ class FormHelperTest < ActionView::TestCase end def test_fields_for_with_only_object - fields_for(@post) do |f| + output_buffer = fields_for(@post) do |f| concat f.text_field(:title) concat f.text_area(:body) concat f.check_box(:secret) @@ -1123,7 +1127,7 @@ class FormHelperTest < ActionView::TestCase end def test_fields_for_object_with_bracketed_name - fields_for("author[post]", @post) do |f| + output_buffer = fields_for("author[post]", @post) do |f| concat f.label(:title) concat f.text_field(:title) end @@ -1134,7 +1138,7 @@ class FormHelperTest < ActionView::TestCase end def test_fields_for_object_with_bracketed_name_and_index - fields_for("author[post]", @post, :index => 1) do |f| + output_buffer = fields_for("author[post]", @post, :index => 1) do |f| concat f.label(:title) concat f.text_field(:title) end @@ -1153,9 +1157,9 @@ class FormHelperTest < ActionView::TestCase concat post_form.text_field(:title) concat post_form.text_area(:body) - fields_for(:parent_post, @post) do |parent_fields| + concat fields_for(:parent_post, @post) { |parent_fields| concat parent_fields.check_box(:secret) - end + } end expected = @@ -1174,9 +1178,9 @@ class FormHelperTest < ActionView::TestCase concat post_form.text_field(:title) concat post_form.text_area(:body) - post_form.fields_for(@comment) do |comment_fields| + concat post_form.fields_for(@comment) { |comment_fields| concat comment_fields.text_field(:name) - end + } end expected = @@ -1273,7 +1277,7 @@ class FormHelperTest < ActionView::TestCase end def test_fields_for_with_labelled_builder - fields_for(:post, @post, :builder => LabelledFormBuilder) do |f| + output_buffer = fields_for(:post, @post, :builder => LabelledFormBuilder) do |f| concat f.text_field(:title) concat f.text_area(:body) concat f.check_box(:secret) diff --git a/actionpack/test/template/form_options_helper_test.rb b/actionpack/test/template/form_options_helper_test.rb index aa40e46aa8..5799e3db53 100644 --- a/actionpack/test/template/form_options_helper_test.rb +++ b/actionpack/test/template/form_options_helper_test.rb @@ -293,7 +293,7 @@ class FormOptionsHelperTest < ActionView::TestCase @post = Post.new @post.category = "" - fields_for :post, @post do |f| + output_buffer = fields_for :post, @post do |f| concat f.select(:category, %w( abe hest)) end @@ -307,7 +307,7 @@ class FormOptionsHelperTest < ActionView::TestCase @post = Post.new @post.category = "" - fields_for :post, @post, :index => 108 do |f| + output_buffer = fields_for :post, @post, :index => 108 do |f| concat f.select(:category, %w( abe hest)) end @@ -322,7 +322,7 @@ class FormOptionsHelperTest < ActionView::TestCase @post.category = "" def @post.to_param; 108; end - fields_for "post[]", @post do |f| + output_buffer = fields_for "post[]", @post do |f| concat f.select(:category, %w( abe hest)) end @@ -336,7 +336,7 @@ class FormOptionsHelperTest < ActionView::TestCase @post = Post.new options = "" - fields_for :post, @post do |f| + output_buffer = fields_for :post, @post do |f| concat f.select(:category, options, :prompt => 'The prompt') end @@ -462,7 +462,7 @@ class FormOptionsHelperTest < ActionView::TestCase @post = Post.new @post.author_name = "Babe" - fields_for :post, @post do |f| + output_buffer = fields_for :post, @post do |f| concat f.collection_select(:author_name, dummy_posts, :author_name, :author_name) end @@ -476,7 +476,7 @@ class FormOptionsHelperTest < ActionView::TestCase @post = Post.new @post.author_name = "Babe" - fields_for :post, @post, :index => 815 do |f| + output_buffer = fields_for :post, @post, :index => 815 do |f| concat f.collection_select(:author_name, dummy_posts, :author_name, :author_name) end @@ -491,7 +491,7 @@ class FormOptionsHelperTest < ActionView::TestCase @post.author_name = "Babe" def @post.to_param; 815; end - fields_for "post[]", @post do |f| + output_buffer = fields_for "post[]", @post do |f| concat f.collection_select(:author_name, dummy_posts, :author_name, :author_name) end @@ -570,7 +570,7 @@ class FormOptionsHelperTest < ActionView::TestCase def test_time_zone_select_under_fields_for @firm = Firm.new("D") - fields_for :firm, @firm do |f| + output_buffer = fields_for :firm, @firm do |f| concat f.time_zone_select(:time_zone) end @@ -589,7 +589,7 @@ class FormOptionsHelperTest < ActionView::TestCase def test_time_zone_select_under_fields_for_with_index @firm = Firm.new("D") - fields_for :firm, @firm, :index => 305 do |f| + output_buffer = fields_for :firm, @firm, :index => 305 do |f| concat f.time_zone_select(:time_zone) end @@ -609,7 +609,7 @@ class FormOptionsHelperTest < ActionView::TestCase @firm = Firm.new("D") def @firm.to_param; 305; end - fields_for "firm[]", @firm do |f| + output_buffer = fields_for "firm[]", @firm do |f| concat f.time_zone_select(:time_zone) end @@ -787,7 +787,7 @@ class FormOptionsHelperTest < ActionView::TestCase @post = Post.new @post.origin = 'dk' - fields_for :post, @post do |f| + output_buffer = fields_for :post, @post do |f| concat f.grouped_collection_select("origin", @continents, :countries, :continent_name, :country_id, :country_name) end diff --git a/actionpack/test/template/form_tag_helper_test.rb b/actionpack/test/template/form_tag_helper_test.rb index c7d4bc986c..868a35c476 100644 --- a/actionpack/test/template/form_tag_helper_test.rb +++ b/actionpack/test/template/form_tag_helper_test.rb @@ -59,16 +59,14 @@ class FormTagHelperTest < ActionView::TestCase end def test_form_tag_with_block_in_erb - __in_erb_template = '' - form_tag("http://example.com") { concat "Hello world!" } + output_buffer = form_tag("http://example.com") { concat "Hello world!" } expected = %(Hello world!) assert_dom_equal expected, output_buffer end def test_form_tag_with_block_and_method_in_erb - __in_erb_template = '' - form_tag("http://example.com", :method => :put) { concat "Hello world!" } + output_buffer = form_tag("http://example.com", :method => :put) { concat "Hello world!" } expected = %(
Hello world!
) assert_dom_equal expected, output_buffer @@ -332,26 +330,22 @@ class FormTagHelperTest < ActionView::TestCase end def test_field_set_tag_in_erb - __in_erb_template = '' - field_set_tag("Your details") { concat "Hello world!" } + output_buffer = field_set_tag("Your details") { concat "Hello world!" } expected = %(
Your detailsHello world!
) assert_dom_equal expected, output_buffer - self.output_buffer = ''.html_safe - field_set_tag { concat "Hello world!" } + output_buffer = field_set_tag { concat "Hello world!" } expected = %(
Hello world!
) assert_dom_equal expected, output_buffer - self.output_buffer = ''.html_safe - field_set_tag('') { concat "Hello world!" } + output_buffer = field_set_tag('') { concat "Hello world!" } expected = %(
Hello world!
) assert_dom_equal expected, output_buffer - self.output_buffer = ''.html_safe - field_set_tag('', :class => 'format') { concat "Hello world!" } + output_buffer = field_set_tag('', :class => 'format') { concat "Hello world!" } expected = %(
Hello world!
) assert_dom_equal expected, output_buffer -- cgit v1.2.3 From ec0973c2abeb80eb3c93c5df070592da56ef5b7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Wed, 10 Mar 2010 16:44:24 +0100 Subject: Remove uneeded methods. --- .../action_controller/metal/http_authentication.rb | 22 ++++------------------ .../lib/action_dispatch/http/mime_negotiation.rb | 15 --------------- 2 files changed, 4 insertions(+), 33 deletions(-) (limited to 'actionpack') 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 :format parameter of the request. - # If no \format is given it returns :jsfor Ajax requests and :html - # 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. # -- cgit v1.2.3 From 07cf49aadf3195db6ddefc58932efc88a6704a09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jos=C3=A9=20Valim?= Date: Wed, 10 Mar 2010 22:11:48 +0100 Subject: Optimize and clean up how details key get expired. --- actionpack/lib/abstract_controller.rb | 1 + actionpack/lib/abstract_controller/rendering.rb | 28 +++++++++++ actionpack/lib/abstract_controller/view_paths.rb | 3 +- actionpack/lib/action_view.rb | 1 + actionpack/lib/action_view/base.rb | 2 +- actionpack/lib/action_view/lookup_context.rb | 57 +++++++++++----------- actionpack/lib/action_view/template/resolver.rb | 5 ++ .../test/template/compiled_templates_test.rb | 3 -- actionpack/test/template/render_test.rb | 8 +-- 9 files changed, 71 insertions(+), 37 deletions(-) (limited to 'actionpack') 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 5c34b83563..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: 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_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/resolver.rb b/actionpack/lib/action_view/template/resolver.rb index c43b357e9e..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. 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 -- cgit v1.2.3