From bdf783b5a8b83b1d565027130de4743fda336523 Mon Sep 17 00:00:00 2001 From: Sven Fuchs Date: Sun, 10 Aug 2008 21:25:24 +0200 Subject: update i18n usage for pluralization hashes (api change) --- actionpack/lib/action_view/locale/en-US.rb | 57 ++++++++++++++++++----- actionpack/test/template/date_helper_i18n_test.rb | 22 +++++++++ 2 files changed, 67 insertions(+), 12 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/locale/en-US.rb b/actionpack/lib/action_view/locale/en-US.rb index 2c3676dca8..0119b3d9c1 100644 --- a/actionpack/lib/action_view/locale/en-US.rb +++ b/actionpack/lib/action_view/locale/en-US.rb @@ -1,17 +1,47 @@ I18n.backend.store_translations :'en-US', { :datetime => { :distance_in_words => { - :half_a_minute => 'half a minute', - :less_than_x_seconds => ['less than 1 second', 'less than {{count}} seconds'], - :x_seconds => ['1 second', '{{count}} seconds'], - :less_than_x_minutes => ['less than a minute', 'less than {{count}} minutes'], - :x_minutes => ['1 minute', '{{count}} minutes'], - :about_x_hours => ['about 1 hour', 'about {{count}} hours'], - :x_days => ['1 day', '{{count}} days'], - :about_x_months => ['about 1 month', 'about {{count}} months'], - :x_months => ['1 month', '{{count}} months'], - :about_x_years => ['about 1 year', 'about {{count}} year'], - :over_x_years => ['over 1 year', 'over {{count}} years'] + :half_a_minute => 'half a minute', + :less_than_x_seconds => { + :one => 'less than 1 second', + :many => 'less than {{count}} seconds' + }, + :x_seconds => { + :one => '1 second', + :many => '{{count}} seconds' + }, + :less_than_x_minutes => { + :one => 'less than a minute', + :many => 'less than {{count}} minutes' + }, + :x_minutes => { + :one => '1 minute', + :many => '{{count}} minutes' + }, + :about_x_hours => { + :one => 'about 1 hour', + :many => 'about {{count}} hours' + }, + :x_days => { + :one => '1 day', + :many => '{{count}} days' + }, + :about_x_months => { + :one => 'about 1 month', + :many => 'about {{count}} months' + }, + :x_months => { + :one => '1 month', + :many => '{{count}} months' + }, + :about_x_years => { + :one => 'about 1 year', + :many => 'about {{count}} years' + }, + :over_x_years => { + :one => 'over 1 year', + :many => 'over {{count}} years' + } } }, :number => { @@ -46,7 +76,10 @@ I18n.backend.store_translations :'en-US', { }, :active_record => { :error => { - :header_message => ["1 error prohibited this {{object_name}} from being saved", "{{count}} errors prohibited this {{object_name}} from being saved"], + :header_message => { + :one => "1 error prohibited this {{object_name}} from being saved", + :many => "{{count}} errors prohibited this {{object_name}} from being saved" + }, :message => "There were problems with the following fields:" } } diff --git a/actionpack/test/template/date_helper_i18n_test.rb b/actionpack/test/template/date_helper_i18n_test.rb index 2b40074498..bf3b2588c8 100644 --- a/actionpack/test/template/date_helper_i18n_test.rb +++ b/actionpack/test/template/date_helper_i18n_test.rb @@ -47,6 +47,28 @@ class DateHelperDistanceOfTimeInWordsI18nTests < Test::Unit::TestCase I18n.expects(:t).with(key, options) distance_of_time_in_words(@from, to, include_seconds, :locale => 'en-US') end + + def test_distance_of_time_pluralizations + { [:'less_than_x_seconds', 1] => 'less than 1 second', + [:'less_than_x_seconds', 2] => 'less than 2 seconds', + [:'less_than_x_minutes', 1] => 'less than a minute', + [:'less_than_x_minutes', 2] => 'less than 2 minutes', + [:'x_minutes', 1] => '1 minute', + [:'x_minutes', 2] => '2 minutes', + [:'about_x_hours', 1] => 'about 1 hour', + [:'about_x_hours', 2] => 'about 2 hours', + [:'x_days', 1] => '1 day', + [:'x_days', 2] => '2 days', + [:'about_x_years', 1] => 'about 1 year', + [:'about_x_years', 2] => 'about 2 years', + [:'over_x_years', 1] => 'over 1 year', + [:'over_x_years', 2] => 'over 2 years' + + }.each do |args, expected| + key, count = *args + assert_equal expected, I18n.t(key, :count => count, :scope => 'datetime.distance_in_words') + end + end end end -- cgit v1.2.3 From f26380b7757666fa793c150538e8444a640d29aa Mon Sep 17 00:00:00 2001 From: Sven Fuchs Date: Wed, 13 Aug 2008 09:53:25 +0200 Subject: switch to using I18n.load_translations instead of requiring plain ruby files --- actionpack/lib/action_view.rb | 2 +- actionpack/lib/action_view/locale/en-US.rb | 155 +++++++++++++++-------------- 2 files changed, 79 insertions(+), 78 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view.rb b/actionpack/lib/action_view.rb index dd555b3792..7e9ae9432d 100644 --- a/actionpack/lib/action_view.rb +++ b/actionpack/lib/action_view.rb @@ -35,7 +35,7 @@ require 'action_view/partials' require 'action_view/template_error' I18n.backend.populate do - require 'action_view/locale/en-US.rb' + I18n.load_translations File.dirname(__FILE__) + '/action_view/locale/en-US.rb' end ActionView::Base.class_eval do diff --git a/actionpack/lib/action_view/locale/en-US.rb b/actionpack/lib/action_view/locale/en-US.rb index 0119b3d9c1..8cce874700 100644 --- a/actionpack/lib/action_view/locale/en-US.rb +++ b/actionpack/lib/action_view/locale/en-US.rb @@ -1,86 +1,87 @@ -I18n.backend.store_translations :'en-US', { - :datetime => { - :distance_in_words => { - :half_a_minute => 'half a minute', - :less_than_x_seconds => { - :one => 'less than 1 second', - :many => 'less than {{count}} seconds' - }, - :x_seconds => { - :one => '1 second', - :many => '{{count}} seconds' - }, - :less_than_x_minutes => { - :one => 'less than a minute', - :many => 'less than {{count}} minutes' - }, - :x_minutes => { - :one => '1 minute', - :many => '{{count}} minutes' - }, - :about_x_hours => { - :one => 'about 1 hour', - :many => 'about {{count}} hours' - }, - :x_days => { - :one => '1 day', - :many => '{{count}} days' +{ :'en-US' => { + :datetime => { + :distance_in_words => { + :half_a_minute => 'half a minute', + :less_than_x_seconds => { + :one => 'less than 1 second', + :many => 'less than {{count}} seconds' + }, + :x_seconds => { + :one => '1 second', + :many => '{{count}} seconds' + }, + :less_than_x_minutes => { + :one => 'less than a minute', + :many => 'less than {{count}} minutes' + }, + :x_minutes => { + :one => '1 minute', + :many => '{{count}} minutes' + }, + :about_x_hours => { + :one => 'about 1 hour', + :many => 'about {{count}} hours' + }, + :x_days => { + :one => '1 day', + :many => '{{count}} days' + }, + :about_x_months => { + :one => 'about 1 month', + :many => 'about {{count}} months' + }, + :x_months => { + :one => '1 month', + :many => '{{count}} months' + }, + :about_x_years => { + :one => 'about 1 year', + :many => 'about {{count}} years' + }, + :over_x_years => { + :one => 'over 1 year', + :many => 'over {{count}} years' + } + } + }, + :number => { + :format => { + :precision => 3, + :separator => '.', + :delimiter => ',' }, - :about_x_months => { - :one => 'about 1 month', - :many => 'about {{count}} months' + :currency => { + :format => { + :unit => '$', + :precision => 2, + :format => '%u%n' + } }, - :x_months => { - :one => '1 month', - :many => '{{count}} months' + :human => { + :format => { + :precision => 1, + :delimiter => '' + } }, - :about_x_years => { - :one => 'about 1 year', - :many => 'about {{count}} years' + :percentage => { + :format => { + :delimiter => '' + } }, - :over_x_years => { - :one => 'over 1 year', - :many => 'over {{count}} years' + :precision => { + :format => { + :delimiter => '' + } } - } - }, - :number => { - :format => { - :precision => 3, - :separator => '.', - :delimiter => ',' }, - :currency => { - :format => { - :unit => '$', - :precision => 2, - :format => '%u%n' + :active_record => { + :error => { + :header_message => { + :one => "1 error prohibited this {{object_name}} from being saved", + :many => "{{count}} errors prohibited this {{object_name}} from being saved" + }, + :message => "There were problems with the following fields:" } - }, - :human => { - :format => { - :precision => 1, - :delimiter => '' - } - }, - :percentage => { - :format => { - :delimiter => '' - } - }, - :precision => { - :format => { - :delimiter => '' - } - } - }, - :active_record => { - :error => { - :header_message => { - :one => "1 error prohibited this {{object_name}} from being saved", - :many => "{{count}} errors prohibited this {{object_name}} from being saved" - }, - :message => "There were problems with the following fields:" } } -} +} \ No newline at end of file -- cgit v1.2.3 From ffeab4e0c171aecced4ddbe29b82aed064be9bdb Mon Sep 17 00:00:00 2001 From: Iain Hecker Date: Thu, 14 Aug 2008 01:28:31 +0200 Subject: Cleaned up ActiveRecord i18n scoping --- .../action_view/helpers/active_record_helper.rb | 8 +++---- actionpack/lib/action_view/locale/en-US.rb | 18 +++++++------- .../template/active_record_helper_i18n_test.rb | 28 +++++++++++----------- 3 files changed, 28 insertions(+), 26 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/active_record_helper.rb b/actionpack/lib/action_view/helpers/active_record_helper.rb index fce03ff605..c339e10701 100644 --- a/actionpack/lib/action_view/helpers/active_record_helper.rb +++ b/actionpack/lib/action_view/helpers/active_record_helper.rb @@ -189,15 +189,15 @@ module ActionView end options[:object_name] ||= params.first - I18n.with_options :locale => options[:locale], :scope => [:active_record, :error] do |locale| + I18n.with_options :locale => options[:locale], :scope => [:activerecord, :errors, :template] do |locale| header_message = if options.include?(:header_message) options[:header_message] else object_name = options[:object_name].to_s.gsub('_', ' ') - object_name = I18n.t(object_name, :default => object_name) - locale.t :header_message, :count => count, :object_name => object_name + object_name = I18n.t(object_name, :default => object_name, :scope => [:activerecord, :models], :count => 1) + locale.t :header, :count => count, :model => object_name end - message = options.include?(:message) ? options[:message] : locale.t(:message) + message = options.include?(:message) ? options[:message] : locale.t(:body) error_messages = objects.sum {|object| object.errors.full_messages.map {|msg| content_tag(:li, msg) } }.join contents = '' diff --git a/actionpack/lib/action_view/locale/en-US.rb b/actionpack/lib/action_view/locale/en-US.rb index 8cce874700..d4647b5a48 100644 --- a/actionpack/lib/action_view/locale/en-US.rb +++ b/actionpack/lib/action_view/locale/en-US.rb @@ -74,14 +74,16 @@ } } }, - :active_record => { - :error => { - :header_message => { - :one => "1 error prohibited this {{object_name}} from being saved", - :many => "{{count}} errors prohibited this {{object_name}} from being saved" - }, - :message => "There were problems with the following fields:" + :activerecord => { + :errors => { + :template => { + :header => { + :one => "1 error prohibited this {{model}} from being saved", + :many => "{{count}} errors prohibited this {{model}} from being saved" + }, + :body => "There were problems with the following fields:" + } } } } -} \ No newline at end of file +} diff --git a/actionpack/test/template/active_record_helper_i18n_test.rb b/actionpack/test/template/active_record_helper_i18n_test.rb index feec64aa30..7ba9659814 100644 --- a/actionpack/test/template/active_record_helper_i18n_test.rb +++ b/actionpack/test/template/active_record_helper_i18n_test.rb @@ -10,37 +10,37 @@ class ActiveRecordHelperI18nTest < Test::Unit::TestCase @object_name = 'book' stubs(:content_tag).returns 'content_tag' - I18n.stubs(:t).with(:'header_message', :locale => 'en-US', :scope => [:active_record, :error], :count => 1, :object_name => '').returns "1 error prohibited this from being saved" - I18n.stubs(:t).with(:'message', :locale => 'en-US', :scope => [:active_record, :error]).returns 'There were problems with the following fields:' + I18n.stubs(:t).with(:'header', :locale => 'en-US', :scope => [:activerecord, :errors, :template], :count => 1, :model => '').returns "1 error prohibited this from being saved" + I18n.stubs(:t).with(:'body', :locale => 'en-US', :scope => [:activerecord, :errors, :template]).returns 'There were problems with the following fields:' end - def test_error_messages_for_given_a_header_message_option_it_does_not_translate_header_message - I18n.expects(:translate).with(:'header_message', :locale => 'en-US', :scope => [:active_record, :error], :count => 1, :object_name => '').never + def test_error_messages_for_given_a_header_option_it_does_not_translate_header_message + I18n.expects(:translate).with(:'header', :locale => 'en-US', :scope => [:activerecord, :errors, :template], :count => 1, :model => '').never error_messages_for(:object => @object, :header_message => 'header message', :locale => 'en-US') end - def test_error_messages_for_given_no_header_message_option_it_translates_header_message - I18n.expects(:t).with(:'header_message', :locale => 'en-US', :scope => [:active_record, :error], :count => 1, :object_name => '').returns 'header message' - I18n.expects(:t).with('', :default => '').once.returns '' + def test_error_messages_for_given_no_header_option_it_translates_header_message + I18n.expects(:t).with(:'header', :locale => 'en-US', :scope => [:activerecord, :errors, :template], :count => 1, :model => '').returns 'header message' + I18n.expects(:t).with('', :default => '', :count => 1, :scope => [:activerecord, :models]).once.returns '' error_messages_for(:object => @object, :locale => 'en-US') end def test_error_messages_for_given_a_message_option_it_does_not_translate_message - I18n.expects(:t).with(:'message', :locale => 'en-US', :scope => [:active_record, :error]).never - I18n.expects(:t).with('', :default => '').once.returns '' + I18n.expects(:t).with(:'body', :locale => 'en-US', :scope => [:activerecord, :errors, :template]).never + I18n.expects(:t).with('', :default => '', :count => 1, :scope => [:activerecord, :models]).once.returns '' error_messages_for(:object => @object, :message => 'message', :locale => 'en-US') end def test_error_messages_for_given_no_message_option_it_translates_message - I18n.expects(:t).with(:'message', :locale => 'en-US', :scope => [:active_record, :error]).returns 'There were problems with the following fields:' - I18n.expects(:t).with('', :default => '').once.returns '' + I18n.expects(:t).with(:'body', :locale => 'en-US', :scope => [:activerecord, :errors, :template]).returns 'There were problems with the following fields:' + I18n.expects(:t).with('', :default => '', :count => 1, :scope => [:activerecord, :models]).once.returns '' error_messages_for(:object => @object, :locale => 'en-US') end def test_error_messages_for_given_object_name_it_translates_object_name - I18n.expects(:t).with(:header_message, :locale => 'en-US', :scope => [:active_record, :error], :count => 1, :object_name => @object_name).returns "1 error prohibited this #{@object_name} from being saved" - I18n.expects(:t).with(@object_name, :default => @object_name).once.returns @object_name + I18n.expects(:t).with(:header, :locale => 'en-US', :scope => [:activerecord, :errors, :template], :count => 1, :model => @object_name).returns "1 error prohibited this #{@object_name} from being saved" + I18n.expects(:t).with(@object_name, :default => @object_name, :count => 1, :scope => [:activerecord, :models]).once.returns @object_name error_messages_for(:object => @object, :locale => 'en-US', :object_name => @object_name) end end -end \ No newline at end of file +end -- cgit v1.2.3 From f1f4e84a7ef88d941f6508673bb448de640d6f77 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Thu, 14 Aug 2008 12:23:29 -0700 Subject: Fix asset file paths with dangling queries in mtime check --- actionpack/lib/action_view/helpers/asset_tag_helper.rb | 8 ++++++-- 1 file changed, 6 insertions(+), 2 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 c2b4f51c9c..623ed1e8df 100644 --- a/actionpack/lib/action_view/helpers/asset_tag_helper.rb +++ b/actionpack/lib/action_view/helpers/asset_tag_helper.rb @@ -612,7 +612,7 @@ module ActionView end def join_asset_file_contents(paths) - paths.collect { |path| File.read(File.join(ASSETS_DIR, path.split("?").first)) }.join("\n\n") + paths.collect { |path| File.read(asset_file_path(path)) }.join("\n\n") end def write_asset_file_contents(joined_asset_path, asset_paths) @@ -621,10 +621,14 @@ module ActionView # Set mtime to the latest of the combined files to allow for # consistent ETag without a shared filesystem. - mt = asset_paths.map { |p| File.mtime(File.join(ASSETS_DIR, p)) }.max + mt = asset_paths.map { |p| File.mtime(asset_file_path(p)) }.max File.utime(mt, mt, joined_asset_path) end + def asset_file_path(path) + File.join(ASSETS_DIR, path.split('?').first) + end + def collect_asset_files(*path) dir = path.first -- cgit v1.2.3 From 8aad8cb3906fce40fa583839fec7f8591fab8ec7 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Thu, 14 Aug 2008 21:45:14 -0700 Subject: Set cache control to require revalidation if cache freshness response headers are set. Don't set Content-Length header if 304 status. --- actionpack/lib/action_controller/response.rb | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/response.rb b/actionpack/lib/action_controller/response.rb index a85fad0d39..7b57f499bb 100644 --- a/actionpack/lib/action_controller/response.rb +++ b/actionpack/lib/action_controller/response.rb @@ -79,7 +79,13 @@ module ActionController # :nodoc: end def last_modified - Time.rfc2822(headers['Last-Modified']) + if last = headers['Last-Modified'] + Time.httpdate(last) + end + end + + def last_modified? + headers.include?('Last-Modified') end def last_modified=(utc_time) @@ -87,6 +93,7 @@ module ActionController # :nodoc: end def etag; headers['ETag'] end + def etag?; headers.include?('ETag') end def etag=(etag) headers['ETag'] = %("#{Digest::MD5.hexdigest(ActiveSupport::Cache.expand_cache_key(etag))}") end @@ -98,22 +105,22 @@ module ActionController # :nodoc: end def prepare! + set_content_length! handle_conditional_get! convert_content_type! - set_content_length! end private def handle_conditional_get! if nonempty_ok_response? - set_conditional_cache_control! - self.etag ||= body if request && request.etag_matches?(etag) self.status = '304 Not Modified' self.body = '' end end + + set_conditional_cache_control! if etag? || last_modified? end def nonempty_ok_response? @@ -142,7 +149,9 @@ module ActionController # :nodoc: # Don't set the Content-Length for block-based bodies as that would mean reading it all into memory. Not nice # for, say, a 2GB streaming file. def set_content_length! - self.headers["Content-Length"] = body.size unless body.respond_to?(:call) + unless body.respond_to?(:call) || (status && status[0..2] == '304') + self.headers["Content-Length"] ||= body.size + end end end end -- cgit v1.2.3 From 894f9ccc5354c29e102f316f388d1dc0b98ef080 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Sun, 17 Aug 2008 19:04:01 -0500 Subject: Use RackRequest as a mock instead of StubCGI into RequestTest --- actionpack/test/controller/request_test.rb | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) (limited to 'actionpack') diff --git a/actionpack/test/controller/request_test.rb b/actionpack/test/controller/request_test.rb index 226c1ac018..045dab4141 100644 --- a/actionpack/test/controller/request_test.rb +++ b/actionpack/test/controller/request_test.rb @@ -397,7 +397,6 @@ class RequestTest < Test::Unit::TestCase end end - class UrlEncodedRequestParameterParsingTest < Test::Unit::TestCase def setup @query_string = "action=create_customer&full_name=David%20Heinemeier%20Hansson&customerId=1" @@ -509,7 +508,6 @@ class UrlEncodedRequestParameterParsingTest < Test::Unit::TestCase ) end - def test_request_hash_parsing query = { "note[viewers][viewer][][type]" => ["User", "Group"], @@ -521,7 +519,6 @@ class UrlEncodedRequestParameterParsingTest < Test::Unit::TestCase assert_equal(expected, ActionController::AbstractRequest.parse_request_parameters(query)) end - def test_parse_params input = { "customers[boston][first][name]" => [ "David" ], @@ -704,7 +701,6 @@ class UrlEncodedRequestParameterParsingTest < Test::Unit::TestCase end end - class MultipartRequestParameterParsingTest < Test::Unit::TestCase FIXTURE_PATH = File.dirname(__FILE__) + '/../fixtures/multipart' @@ -852,20 +848,20 @@ class XmlParamsParsingTest < Test::Unit::TestCase private def parse_body(body) - env = { 'CONTENT_TYPE' => 'application/xml', + env = { 'rack.input' => StringIO.new(body), + 'CONTENT_TYPE' => 'application/xml', 'CONTENT_LENGTH' => body.size.to_s } - cgi = ActionController::Integration::Session::StubCGI.new(env, body) - ActionController::CgiRequest.new(cgi).request_parameters + ActionController::RackRequest.new(env).request_parameters end end class LegacyXmlParamsParsingTest < XmlParamsParsingTest private def parse_body(body) - env = { 'HTTP_X_POST_DATA_FORMAT' => 'xml', - 'CONTENT_LENGTH' => body.size.to_s } - cgi = ActionController::Integration::Session::StubCGI.new(env, body) - ActionController::CgiRequest.new(cgi).request_parameters + env = { 'rack.input' => StringIO.new(body), + 'HTTP_X_POST_DATA_FORMAT' => 'xml', + 'CONTENT_LENGTH' => body.size.to_s } + ActionController::RackRequest.new(env).request_parameters end end @@ -884,9 +880,9 @@ class JsonParamsParsingTest < Test::Unit::TestCase private def parse_body(body,content_type) - env = { 'CONTENT_TYPE' => content_type, + env = { 'rack.input' => StringIO.new(body), + 'CONTENT_TYPE' => content_type, 'CONTENT_LENGTH' => body.size.to_s } - cgi = ActionController::Integration::Session::StubCGI.new(env, body) - ActionController::CgiRequest.new(cgi).request_parameters + ActionController::RackRequest.new(env).request_parameters end end -- cgit v1.2.3 From b8e930aa016e26471046d3f7d7ca1c10103791e7 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Sun, 17 Aug 2008 19:09:38 -0500 Subject: Merge RackProcess#normalize_headers logic into AbstractResponse#prepare! --- actionpack/lib/action_controller/rack_process.rb | 87 ++++++++++++++---------- actionpack/test/controller/rack_test.rb | 35 ++++++---- 2 files changed, 75 insertions(+), 47 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/rack_process.rb b/actionpack/lib/action_controller/rack_process.rb index dcbcf8bc1d..221613b854 100644 --- a/actionpack/lib/action_controller/rack_process.rb +++ b/actionpack/lib/action_controller/rack_process.rb @@ -143,23 +143,26 @@ end_msg end class RackResponse < AbstractResponse #:nodoc: - attr_accessor :status - def initialize(request) - @request = request + @cgi = request.cgi @writer = lambda { |x| @body << x } @block = nil super() end + # Retrieve status from instance variable if has already been delete + def status + @status || super + end + def out(output = $stdout, &block) @block = block - normalize_headers(@headers) - if [204, 304].include?(@status.to_i) - @headers.delete "Content-Type" - [status, @headers.to_hash, []] + @status = headers.delete("Status") + if [204, 304].include?(status.to_i) + headers.delete("Content-Type") + [status, headers.to_hash, []] else - [status, @headers.to_hash, self] + [status, headers.to_hash, self] end end alias to_a out @@ -191,43 +194,57 @@ end_msg @block == nil && @body.empty? end - private - def normalize_headers(options = "text/html") - if options.is_a?(String) - headers['Content-Type'] = options unless headers['Content-Type'] - else - headers['Content-Length'] = options.delete('Content-Length').to_s if options['Content-Length'] + def prepare! + super - headers['Content-Type'] = options.delete('type') || "text/html" - headers['Content-Type'] += "; charset=" + options.delete('charset') if options['charset'] + convert_language! + convert_expires! + set_status! + set_cookies! + end - headers['Content-Language'] = options.delete('language') if options['language'] - headers['Expires'] = options.delete('expires') if options['expires'] + private + def convert_language! + headers["Content-Language"] = headers.delete("language") if headers["language"] + end - @status = options.delete('Status') || "200 OK" + def convert_expires! + headers["Expires"] = headers.delete("") if headers["expires"] + end - # Convert 'cookie' header to 'Set-Cookie' headers. - # Because Set-Cookie header can appear more the once in the response body, - # we store it in a line break separated string that will be translated to - # multiple Set-Cookie header by the handler. - if cookie = options.delete('cookie') - cookies = [] + def convert_content_type! + super + headers['Content-Type'] = headers.delete('type') || "text/html" + headers['Content-Type'] += "; charset=" + headers.delete('charset') if headers['charset'] + end - case cookie - when Array then cookie.each { |c| cookies << c.to_s } - when Hash then cookie.each { |_, c| cookies << c.to_s } - else cookies << cookie.to_s - end + def set_content_length! + super + headers["Content-Length"] = headers["Content-Length"].to_s if headers["Content-Length"] + end - @request.cgi.output_cookies.each { |c| cookies << c.to_s } if @request.cgi.output_cookies + def set_status! + self.status ||= "200 OK" + end - headers['Set-Cookie'] = [headers['Set-Cookie'], cookies].flatten.compact + def set_cookies! + # Convert 'cookie' header to 'Set-Cookie' headers. + # Because Set-Cookie header can appear more the once in the response body, + # we store it in a line break separated string that will be translated to + # multiple Set-Cookie header by the handler. + if cookie = headers.delete('cookie') + cookies = [] + + case cookie + when Array then cookie.each { |c| cookies << c.to_s } + when Hash then cookie.each { |_, c| cookies << c.to_s } + else cookies << cookie.to_s end - options.each { |k,v| headers[k] = v } - end + @cgi.output_cookies.each { |c| cookies << c.to_s } if @cgi.output_cookies - "" + headers['Set-Cookie'] = [headers['Set-Cookie'], cookies].flatten.compact + end end end diff --git a/actionpack/test/controller/rack_test.rb b/actionpack/test/controller/rack_test.rb index d1650de1fc..30a1144aad 100644 --- a/actionpack/test/controller/rack_test.rb +++ b/actionpack/test/controller/rack_test.rb @@ -236,10 +236,17 @@ class RackResponseTest < BaseRackTest def test_simple_output @response.body = "Hello, World!" + @response.prepare! status, headers, body = @response.out(@output) assert_equal "200 OK", status - assert_equal({"Content-Type" => "text/html", "Cache-Control" => "no-cache", "Set-Cookie" => []}, headers) + assert_equal({ + "Content-Type" => "text/html", + "Cache-Control" => "private, max-age=0, must-revalidate", + "ETag" => '"65a8e27d8879283831b664bd8b7f0ad4"', + "Set-Cookie" => [], + "Content-Length" => "13" + }, headers) parts = [] body.each { |part| parts << part } @@ -250,6 +257,7 @@ class RackResponseTest < BaseRackTest @response.body = Proc.new do |response, output| 5.times { |n| output.write(n) } end + @response.prepare! status, headers, body = @response.out(@output) assert_equal "200 OK", status @@ -265,13 +273,16 @@ class RackResponseTest < BaseRackTest @request.cgi.send :instance_variable_set, '@output_cookies', [cookie] @response.body = "Hello, World!" + @response.prepare! status, headers, body = @response.out(@output) assert_equal "200 OK", status assert_equal({ "Content-Type" => "text/html", - "Cache-Control" => "no-cache", - "Set-Cookie" => ["name=Josh; path="] + "Cache-Control" => "private, max-age=0, must-revalidate", + "ETag" => '"65a8e27d8879283831b664bd8b7f0ad4"', + "Set-Cookie" => ["name=Josh; path="], + "Content-Length" => "13" }, headers) parts = [] @@ -285,18 +296,18 @@ class RackResponseHeadersTest < BaseRackTest super @response = ActionController::RackResponse.new(@request) @output = StringIO.new('') - @response.headers['Status'] = 200 + @response.headers['Status'] = "200 OK" end def test_content_type [204, 304].each do |c| - @response.headers['Status'] = c - assert !response_headers.has_key?("Content-Type") + @response.headers['Status'] = c.to_s + assert !response_headers.has_key?("Content-Type"), "#{c} should not have Content-Type header" end [200, 302, 404, 500].each do |c| - @response.headers['Status'] = c - assert response_headers.has_key?("Content-Type") + @response.headers['Status'] = c.to_s + assert response_headers.has_key?("Content-Type"), "#{c} did not have Content-Type header" end end @@ -305,8 +316,8 @@ class RackResponseHeadersTest < BaseRackTest end private - - def response_headers - @response.out(@output)[1] - end + def response_headers + @response.prepare! + @response.out(@output)[1] + end end -- cgit v1.2.3 From f245658495865eff0882589b3e159704e48e1820 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Sun, 17 Aug 2008 19:13:49 -0500 Subject: Use Response status accessor instead of the Status header --- actionpack/lib/action_controller/test_process.rb | 34 ++++++++++++------------ 1 file changed, 17 insertions(+), 17 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/test_process.rb b/actionpack/lib/action_controller/test_process.rb index 0c705207e3..c6b1470070 100644 --- a/actionpack/lib/action_controller/test_process.rb +++ b/actionpack/lib/action_controller/test_process.rb @@ -138,7 +138,7 @@ module ActionController #:nodoc: @host = "test.host" @request_uri = "/" @user_agent = "Rails Testing" - self.remote_addr = "0.0.0.0" + self.remote_addr = "0.0.0.0" @env["SERVER_PORT"] = 80 @env['REQUEST_METHOD'] = "GET" end @@ -160,16 +160,16 @@ module ActionController #:nodoc: module TestResponseBehavior #:nodoc: # The response code of the request def response_code - headers['Status'][0,3].to_i rescue 0 + status[0,3].to_i rescue 0 end - + # Returns a String to ensure compatibility with Net::HTTPResponse def code - headers['Status'].to_s.split(' ')[0] + status.to_s.split(' ')[0] end def message - headers['Status'].to_s.split(' ',2)[1] + status.to_s.split(' ',2)[1] end # Was the response successful? @@ -246,11 +246,11 @@ module ActionController #:nodoc: # Does the specified template object exist? def has_template_object?(name=nil) - !template_objects[name].nil? + !template_objects[name].nil? end # Returns the response cookies, converted to a Hash of (name => CGI::Cookie) pairs - # + # # assert_equal ['AuthorOfNewPage'], r.cookies['author'].value def cookies headers['cookie'].inject({}) { |hash, cookie| hash[cookie.name] = cookie; hash } @@ -322,7 +322,7 @@ module ActionController #:nodoc: # # Usage example, within a functional test: # post :change_avatar, :avatar => ActionController::TestUploadedFile.new(Test::Unit::TestCase.fixture_path + '/files/spongebob.png', 'image/png') - # + # # Pass a true third parameter to ensure the uploaded file is opened in binary mode (only required for Windows): # post :change_avatar, :avatar => ActionController::TestUploadedFile.new(Test::Unit::TestCase.fixture_path + '/files/spongebob.png', 'image/png', :binary) require 'tempfile' @@ -403,13 +403,13 @@ module ActionController #:nodoc: end alias xhr :xml_http_request - def assigns(key = nil) - if key.nil? - @response.template.assigns - else - @response.template.assigns[key.to_s] - end - end + def assigns(key = nil) + if key.nil? + @response.template.assigns + else + @response.template.assigns[key.to_s] + end + end def session @response.session @@ -468,7 +468,7 @@ module ActionController #:nodoc: # post :change_avatar, :avatar => fixture_file_upload('/files/spongebob.png', 'image/png', :binary) def fixture_file_upload(path, mime_type = nil, binary = false) ActionController::TestUploadedFile.new( - Test::Unit::TestCase.respond_to?(:fixture_path) ? Test::Unit::TestCase.fixture_path + path : path, + Test::Unit::TestCase.respond_to?(:fixture_path) ? Test::Unit::TestCase.fixture_path + path : path, mime_type, binary ) @@ -476,7 +476,7 @@ module ActionController #:nodoc: # A helper to make it easier to test different route configurations. # This method temporarily replaces ActionController::Routing::Routes - # with a new RouteSet instance. + # with a new RouteSet instance. # # The new instance is yielded to the passed block. Typically the block # will create some routes using map.draw { map.connect ... }: -- cgit v1.2.3 From dbb0abfb7e9eb9a63b721a38625e3eff66ced49d Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Sun, 17 Aug 2008 19:18:18 -0500 Subject: More integration test coverage --- actionpack/test/controller/integration_test.rb | 32 +++++++++++++++++++++++--- 1 file changed, 29 insertions(+), 3 deletions(-) (limited to 'actionpack') diff --git a/actionpack/test/controller/integration_test.rb b/actionpack/test/controller/integration_test.rb index 475e13897b..a709343a94 100644 --- a/actionpack/test/controller/integration_test.rb +++ b/actionpack/test/controller/integration_test.rb @@ -265,6 +265,10 @@ class IntegrationProcessTest < ActionController::IntegrationTest cookies["cookie_3"] = "chocolate" render :text => "Gone", :status => 410 end + + def redirect + redirect_to :action => "get" + end end def test_get @@ -274,6 +278,9 @@ class IntegrationProcessTest < ActionController::IntegrationTest assert_equal "OK", status_message assert_equal "200 OK", response.headers["Status"] assert_equal ["200 OK"], headers["status"] + assert_response 200 + assert_response :success + assert_response :ok assert_equal [], response.headers["cookie"] assert_equal [], headers["cookie"] assert_equal({}, cookies) @@ -290,6 +297,9 @@ class IntegrationProcessTest < ActionController::IntegrationTest assert_equal "Created", status_message assert_equal "201 Created", response.headers["Status"] assert_equal ["201 Created"], headers["status"] + assert_response 201 + assert_response :success + assert_response :created assert_equal [], response.headers["cookie"] assert_equal [], headers["cookie"] assert_equal({}, cookies) @@ -308,6 +318,8 @@ class IntegrationProcessTest < ActionController::IntegrationTest assert_equal "Gone", status_message assert_equal "410 Gone", response.headers["Status"] assert_equal ["410 Gone"], headers["status"] + assert_response 410 + assert_response :gone assert_equal nil, response.headers["Set-Cookie"] assert_equal ["cookie_1=; path=/", "cookie_3=chocolate; path=/"], headers['set-cookie'] assert_equal [[], ["chocolate"]], response.headers["cookie"] @@ -317,14 +329,28 @@ class IntegrationProcessTest < ActionController::IntegrationTest end end + def test_redirect + with_test_route_set do + get '/redirect' + assert_equal 302, status + assert_equal "Found", status_message + assert_equal "302 Found", response.headers["Status"] + assert_equal ["302 Found"], headers["status"] + assert_response 302 + assert_response :redirect + assert_response :found + assert_equal "You are being redirected.", response.body + assert_kind_of HTML::Document, html_document + assert_equal 1, request_count + end + end + private def with_test_route_set with_routing do |set| set.draw do |map| map.with_options :controller => "IntegrationProcessTest::Integration" do |c| - c.connect '/get', :action => "get" - c.connect '/post', :action => "post" - c.connect '/cookie_monster', :action => "cookie_monster" + c.connect "/:action" end end yield -- cgit v1.2.3 From 38c7d73e73d569211c4dfadf96fc295a925b7c9c Mon Sep 17 00:00:00 2001 From: Ryan Bates Date: Sun, 17 Aug 2008 19:29:24 -0500 Subject: pass yielded arguments to block for ActionView::Base#render with :layout [#847 state:resolved] Signed-off-by: Joshua Peek --- actionpack/lib/action_view/base.rb | 23 +++++-------- actionpack/lib/action_view/partials.rb | 38 ++++++++++++++++++++-- actionpack/lib/action_view/renderable.rb | 9 ++++- actionpack/test/controller/layout_test.rb | 19 +++++------ actionpack/test/controller/new_render_test.rb | 9 +++++ .../test/_layout_for_block_with_args.html.erb | 3 ++ .../using_layout_around_block_with_args.html.erb | 1 + 7 files changed, 74 insertions(+), 28 deletions(-) create mode 100644 actionpack/test/fixtures/test/_layout_for_block_with_args.html.erb create mode 100644 actionpack/test/fixtures/test/using_layout_around_block_with_args.html.erb (limited to 'actionpack') diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index ad59d92086..f7f9f70298 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -246,12 +246,18 @@ module ActionView #:nodoc: if partial_layout = options.delete(:layout) if block_given? - wrap_content_for_layout capture(&block) do + begin + @_proc_for_layout = block concat(render(options.merge(:partial => partial_layout))) + ensure + @_proc_for_layout = nil end else - wrap_content_for_layout render(options) do + begin + original_content_for_layout, @content_for_layout = @content_for_layout, render(options) render(options.merge(:partial => partial_layout)) + ensure + @content_for_layout = original_content_for_layout end end elsif options[:file] @@ -367,13 +373,6 @@ module ActionView #:nodoc: InlineTemplate.new(text, type).render(self, local_assigns) end - def wrap_content_for_layout(content) - original_content_for_layout, @content_for_layout = @content_for_layout, content - yield - ensure - @content_for_layout = original_content_for_layout - end - # Evaluate the local assigns and pushes them to the view. def evaluate_assigns unless @assigns_added @@ -392,11 +391,5 @@ module ActionView #:nodoc: controller.response.content_type ||= content_type end end - - def execute(method, local_assigns = {}) - send(method, local_assigns) do |*names| - instance_variable_get "@content_for_#{names.first || 'layout'}" - end - end end end diff --git a/actionpack/lib/action_view/partials.rb b/actionpack/lib/action_view/partials.rb index 894b88534c..b661a62677 100644 --- a/actionpack/lib/action_view/partials.rb +++ b/actionpack/lib/action_view/partials.rb @@ -68,7 +68,7 @@ module ActionView # # <%# app/views/users/_editor.html.erb &> #
- # Deadline: $<%= user.deadline %> + # Deadline: <%= user.deadline %> # <%= yield %> #
# @@ -82,7 +82,7 @@ module ActionView # # Here's the editor: #
- # Deadline: $<%= user.deadline %> + # Deadline: <%= user.deadline %> # Name: <%= user.name %> #
# @@ -101,6 +101,40 @@ module ActionView # # # As you can see, the :locals hash is shared between both the partial and its layout. + # + # If you pass arguments to "yield" then this will be passed to the block. One way to use this is to pass + # an array to layout and treat it as an enumerable. + # + # <%# app/views/users/_user.html.erb &> + #
+ # Budget: $<%= user.budget %> + # <%= yield user %> + #
+ # + # <%# app/views/users/index.html.erb &> + # <% render :layout => @users do |user| %> + # Title: <%= user.title %> + # <% end %> + # + # This will render the layout for each user and yield to the block, passing the user, each time. + # + # You can also yield multiple times in one layout and use block arguments to differentiate the sections. + # + # <%# app/views/users/_user.html.erb &> + #
+ # <%= yield user, :header %> + # Budget: $<%= user.budget %> + # <%= yield user, :footer %> + #
+ # + # <%# app/views/users/index.html.erb &> + # <% render :layout => @users do |user, section| %> + # <%- case section when :header -%> + # Title: <%= user.title %> + # <%- when :footer -%> + # Deadline: <%= user.deadline %> + # <%- end -%> + # <% end %> module Partials extend ActiveSupport::Memoizable diff --git a/actionpack/lib/action_view/renderable.rb b/actionpack/lib/action_view/renderable.rb index 89ac500717..a28689dc69 100644 --- a/actionpack/lib/action_view/renderable.rb +++ b/actionpack/lib/action_view/renderable.rb @@ -31,7 +31,14 @@ module ActionView view.send(:evaluate_assigns) view.send(:set_controller_content_type, mime_type) if respond_to?(:mime_type) - view.send(:execute, method_name(local_assigns), local_assigns) + + view.send(method_name(local_assigns), local_assigns) do |*names| + if proc = view.instance_variable_get("@_proc_for_layout") + view.capture(*names, &proc) + else + view.instance_variable_get("@content_for_#{names.first || 'layout'}") + end + end end def method_name(local_assigns) diff --git a/actionpack/test/controller/layout_test.rb b/actionpack/test/controller/layout_test.rb index 72c01a9102..71f110f241 100644 --- a/actionpack/test/controller/layout_test.rb +++ b/actionpack/test/controller/layout_test.rb @@ -41,19 +41,19 @@ class LayoutAutoDiscoveryTest < Test::Unit::TestCase @request.host = "www.nextangle.com" end - + def test_application_layout_is_default_when_no_controller_match @controller = ProductController.new get :hello assert_equal 'layout_test.rhtml hello.rhtml', @response.body end - + def test_controller_name_layout_name_match @controller = ItemController.new get :hello assert_equal 'item.rhtml hello.rhtml', @response.body end - + def test_third_party_template_library_auto_discovers_layout ThirdPartyTemplateLibraryController.view_paths.reload! @controller = ThirdPartyTemplateLibraryController.new @@ -63,14 +63,14 @@ class LayoutAutoDiscoveryTest < Test::Unit::TestCase assert_response :success assert_equal 'Mab', @response.body end - + def test_namespaced_controllers_auto_detect_layouts @controller = ControllerNameSpace::NestedController.new get :hello assert_equal 'layouts/controller_name_space/nested', @controller.active_layout assert_equal 'controller_name_space/nested.rhtml hello.rhtml', @response.body end - + def test_namespaced_controllers_auto_detect_layouts @controller = MultipleExtensions.new get :hello @@ -115,7 +115,7 @@ class ExemptFromLayoutTest < Test::Unit::TestCase def test_rhtml_exempt_from_layout_status_should_prevent_layout_render ActionController::Base.exempt_from_layout :rhtml - + assert @controller.send!(:template_exempt_from_layout?, 'test.rhtml') assert @controller.send!(:template_exempt_from_layout?, 'hello.rhtml') @@ -156,19 +156,19 @@ class LayoutSetInResponseTest < Test::Unit::TestCase get :hello assert_equal 'layouts/layout_test', @response.layout end - + def test_layout_set_when_set_in_controller @controller = HasOwnLayoutController.new get :hello assert_equal 'layouts/item', @response.layout end - + def test_layout_set_when_using_render @controller = SetsLayoutInRenderController.new get :hello assert_equal 'layouts/third_party_template_library', @response.layout end - + def test_layout_is_not_set_when_none_rendered @controller = RendersNoLayoutController.new get :hello @@ -249,4 +249,3 @@ class LayoutSymlinkedIsRenderedTest < Test::Unit::TestCase assert_equal "layouts/symlinked/symlinked_layout", @response.layout end end - \ No newline at end of file diff --git a/actionpack/test/controller/new_render_test.rb b/actionpack/test/controller/new_render_test.rb index be99350cd2..82919b7777 100644 --- a/actionpack/test/controller/new_render_test.rb +++ b/actionpack/test/controller/new_render_test.rb @@ -435,6 +435,10 @@ class NewRenderTestController < ActionController::Base render :action => "using_layout_around_block" end + def render_using_layout_around_block_with_args + render :action => "using_layout_around_block_with_args" + end + def render_using_layout_around_block_in_main_layout_and_within_content_for_layout render :action => "using_layout_around_block" end @@ -969,4 +973,9 @@ EOS get :render_using_layout_around_block_in_main_layout_and_within_content_for_layout assert_equal "Before (Anthony)\nInside from first block in layout\nAfter\nBefore (David)\nInside from block\nAfter\nBefore (Ramm)\nInside from second block in layout\nAfter\n", @response.body end + + def test_using_layout_around_block_with_args + get :render_using_layout_around_block_with_args + assert_equal "Before\narg1arg2\nAfter", @response.body + end end diff --git a/actionpack/test/fixtures/test/_layout_for_block_with_args.html.erb b/actionpack/test/fixtures/test/_layout_for_block_with_args.html.erb new file mode 100644 index 0000000000..307533208d --- /dev/null +++ b/actionpack/test/fixtures/test/_layout_for_block_with_args.html.erb @@ -0,0 +1,3 @@ +Before +<%= yield 'arg1', 'arg2' %> +After \ No newline at end of file diff --git a/actionpack/test/fixtures/test/using_layout_around_block_with_args.html.erb b/actionpack/test/fixtures/test/using_layout_around_block_with_args.html.erb new file mode 100644 index 0000000000..71b1f30ad0 --- /dev/null +++ b/actionpack/test/fixtures/test/using_layout_around_block_with_args.html.erb @@ -0,0 +1 @@ +<% render(:layout => "layout_for_block_with_args") do |*args| %><%= args.join %><% end %> \ No newline at end of file -- cgit v1.2.3 From c1a8690d582c08777055caf449c03f85b4c8aa4b Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Mon, 18 Aug 2008 22:38:58 -0500 Subject: Consistently use the framework's configured logger and avoid reverting to RAILS_DEFAULT_LOGGER unless necessary. --- actionpack/lib/action_controller/dispatcher.rb | 4 ++-- actionpack/lib/action_view/base.rb | 3 ++- actionpack/lib/action_view/paths.rb | 2 +- actionpack/lib/action_view/renderable.rb | 2 +- 4 files changed, 6 insertions(+), 5 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/dispatcher.rb b/actionpack/lib/action_controller/dispatcher.rb index 835d8e834e..7e46f572fe 100644 --- a/actionpack/lib/action_controller/dispatcher.rb +++ b/actionpack/lib/action_controller/dispatcher.rb @@ -24,7 +24,7 @@ module ActionController to_prepare(:activerecord_instantiate_observers) { ActiveRecord::Base.instantiate_observers } end - after_dispatch :flush_logger if defined?(RAILS_DEFAULT_LOGGER) && RAILS_DEFAULT_LOGGER.respond_to?(:flush) + after_dispatch :flush_logger if Base.logger && Base.logger.respond_to?(:flush) end # Backward-compatible class method takes CGI-specific args. Deprecated @@ -142,7 +142,7 @@ module ActionController end def flush_logger - RAILS_DEFAULT_LOGGER.flush + Base.logger.flush end protected diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index f7f9f70298..62a01b33dd 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -169,6 +169,7 @@ module ActionView #:nodoc: class << self delegate :erb_trim_mode=, :to => 'ActionView::TemplateHandlers::ERB' + delegate :logger, :to => 'ActionController::Base' end def self.cache_template_loading=(*args) @@ -328,7 +329,7 @@ module ActionView #:nodoc: else template = Template.new(template_path, view_paths) - if self.class.warn_cache_misses && logger = ActionController::Base.logger + if self.class.warn_cache_misses && logger logger.debug "[PERFORMANCE] Rendering a template that was " + "not found in view path. Templates outside the view path are " + "not cached and result in expensive disk operations. Move this " + diff --git a/actionpack/lib/action_view/paths.rb b/actionpack/lib/action_view/paths.rb index d97f963540..6a118a1cfa 100644 --- a/actionpack/lib/action_view/paths.rb +++ b/actionpack/lib/action_view/paths.rb @@ -3,7 +3,7 @@ module ActionView #:nodoc: def self.type_cast(obj) if obj.is_a?(String) if Base.warn_cache_misses && defined?(Rails) && Rails.initialized? - Rails.logger.debug "[PERFORMANCE] Processing view path during a " + + Base.logger.debug "[PERFORMANCE] Processing view path during a " + "request. This an expense disk operation that should be done at " + "boot. You can manually process this view path with " + "ActionView::Base.process_view_paths(#{obj.inspect}) and set it " + diff --git a/actionpack/lib/action_view/renderable.rb b/actionpack/lib/action_view/renderable.rb index a28689dc69..c011f21550 100644 --- a/actionpack/lib/action_view/renderable.rb +++ b/actionpack/lib/action_view/renderable.rb @@ -72,7 +72,7 @@ module ActionView end_src begin - logger = ActionController::Base.logger + logger = Base.logger logger.debug "Compiling template #{render_symbol}" if logger ActionView::Base::CompiledTemplates.module_eval(source, filename, 0) -- cgit v1.2.3 From 977317da55b6ba9bbb1326392516480902145c5b Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Tue, 19 Aug 2008 16:29:02 -0500 Subject: hack around CGI session close --- actionpack/lib/action_controller/rack_process.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/rack_process.rb b/actionpack/lib/action_controller/rack_process.rb index 221613b854..69bfc549c1 100644 --- a/actionpack/lib/action_controller/rack_process.rb +++ b/actionpack/lib/action_controller/rack_process.rb @@ -156,6 +156,10 @@ end_msg end def out(output = $stdout, &block) + # Nasty hack because CGI sessions are closed after the normal + # prepare! statement + set_cookies! + @block = block @status = headers.delete("Status") if [204, 304].include?(status.to_i) @@ -200,7 +204,7 @@ end_msg convert_language! convert_expires! set_status! - set_cookies! + # set_cookies! end private -- cgit v1.2.3 From 6e4ea66dc0d41ef611e2b2187e940321f5dc748a Mon Sep 17 00:00:00 2001 From: Jamis Buck Date: Tue, 19 Aug 2008 16:07:17 -0600 Subject: Make AbstractRequest.if_modified_sense return nil if the header could not be parsed --- actionpack/CHANGELOG | 2 ++ actionpack/lib/action_controller/request.rb | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG index 6f65d4003d..db3378d9d9 100644 --- a/actionpack/CHANGELOG +++ b/actionpack/CHANGELOG @@ -1,5 +1,7 @@ *Edge* +* Made AbstractRequest.if_modified_sense return nil if the header could not be parsed [Jamis Buck] + * Added back ActionController::Base.allow_concurrency flag [Josh Peek] * AbstractRequest.relative_url_root is no longer automatically configured by a HTTP header. It can now be set in your configuration environment with config.action_controller.relative_url_root [Josh Peek] diff --git a/actionpack/lib/action_controller/request.rb b/actionpack/lib/action_controller/request.rb index 90bced14e6..364e6201cc 100644 --- a/actionpack/lib/action_controller/request.rb +++ b/actionpack/lib/action_controller/request.rb @@ -100,7 +100,7 @@ module ActionController def if_modified_since if since = env['HTTP_IF_MODIFIED_SINCE'] - Time.rfc2822(since) + Time.rfc2822(since) rescue nil end end memoize :if_modified_since -- cgit v1.2.3 From 71c4ff07ab4313c1f4781d59ad2f4528f5875665 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Tue, 19 Aug 2008 18:53:46 -0500 Subject: Delegate xhr helper method to integration session --- actionpack/lib/action_controller/integration.rb | 2 +- actionpack/test/controller/integration_test.rb | 19 ++++++++++++++++++- 2 files changed, 19 insertions(+), 2 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/integration.rb b/actionpack/lib/action_controller/integration.rb index 1d2b81355c..ca5923de2f 100644 --- a/actionpack/lib/action_controller/integration.rb +++ b/actionpack/lib/action_controller/integration.rb @@ -451,7 +451,7 @@ EOF end %w(get post put head delete cookies assigns - xml_http_request get_via_redirect post_via_redirect).each do |method| + xml_http_request xhr get_via_redirect post_via_redirect).each do |method| define_method(method) do |*args| reset! unless @integration_session # reset the html_document variable, but only for new get/post calls diff --git a/actionpack/test/controller/integration_test.rb b/actionpack/test/controller/integration_test.rb index a709343a94..b878962df3 100644 --- a/actionpack/test/controller/integration_test.rb +++ b/actionpack/test/controller/integration_test.rb @@ -253,7 +253,10 @@ class IntegrationProcessTest < ActionController::IntegrationTest session :off def get - render :text => "OK", :status => 200 + respond_to do |format| + format.html { render :text => "OK", :status => 200 } + format.js { render :text => "JS OK", :status => 200 } + end end def post @@ -345,6 +348,20 @@ class IntegrationProcessTest < ActionController::IntegrationTest end end + def test_xml_http_request_get + with_test_route_set do + xhr :get, '/get' + assert_equal 200, status + assert_equal "OK", status_message + assert_equal "200 OK", response.headers["Status"] + assert_equal ["200 OK"], headers["status"] + assert_response 200 + assert_response :success + assert_response :ok + assert_equal "JS OK", response.body + end + end + private def with_test_route_set with_routing do |set| -- cgit v1.2.3 From a8ece12fe2ac7838407954453e0d31af6186a5db Mon Sep 17 00:00:00 2001 From: Ryan Bates Date: Tue, 19 Aug 2008 19:09:04 -0500 Subject: Return nil instead of a space when passing an empty collection or nil to 'render :partial' [#791 state:resolved] Signed-off-by: Joshua Peek --- actionpack/lib/action_controller/base.rb | 9 ++++++--- actionpack/lib/action_view/base.rb | 2 +- actionpack/lib/action_view/partials.rb | 2 +- actionpack/test/controller/render_test.rb | 2 +- actionpack/test/template/render_test.rb | 8 ++++++++ 5 files changed, 17 insertions(+), 6 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb index 0fdbcbd26f..09414e7702 100644 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -939,8 +939,7 @@ module ActionController #:nodoc: render_for_text(generator.to_s, options[:status]) elsif options[:nothing] - # Safari doesn't pass the headers of the return if the response is zero length - render_for_text(" ", options[:status]) + render_for_text(nil, options[:status]) else render_for_file(default_template_name, options[:status], true) @@ -1154,7 +1153,11 @@ module ActionController #:nodoc: response.body ||= '' response.body << text.to_s else - response.body = text.is_a?(Proc) ? text : text.to_s + response.body = case text + when Proc then text + when nil then " " # Safari doesn't pass the headers of the return if the response is zero length + else text.to_s + end end end diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index 62a01b33dd..46bacbcbc1 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -263,7 +263,7 @@ module ActionView #:nodoc: end elsif options[:file] render_file(options[:file], nil, options[:locals]) - elsif options[:partial] && options[:collection] + elsif options[:partial] && options.has_key?(:collection) render_partial_collection(options[:partial], options[:collection], options[:spacer_template], options[:locals], options[:as]) elsif options[:partial] render_partial(options[:partial], options[:object], options[:locals]) diff --git a/actionpack/lib/action_view/partials.rb b/actionpack/lib/action_view/partials.rb index b661a62677..074ba5a2b5 100644 --- a/actionpack/lib/action_view/partials.rb +++ b/actionpack/lib/action_view/partials.rb @@ -161,7 +161,7 @@ module ActionView end def render_partial_collection(partial_path, collection, partial_spacer_template = nil, local_assigns = {}, as = nil) #:nodoc: - return " " if collection.empty? + return nil if collection.blank? local_assigns = local_assigns ? local_assigns.clone : {} spacer = partial_spacer_template ? render(:partial => partial_spacer_template) : '' diff --git a/actionpack/test/controller/render_test.rb b/actionpack/test/controller/render_test.rb index 1b9b12acc6..3008f5ca03 100644 --- a/actionpack/test/controller/render_test.rb +++ b/actionpack/test/controller/render_test.rb @@ -329,7 +329,7 @@ class RenderTest < Test::Unit::TestCase def test_render_text_with_nil get :render_text_with_nil assert_response 200 - assert_equal '', @response.body + assert_equal ' ', @response.body end def test_render_text_with_false diff --git a/actionpack/test/template/render_test.rb b/actionpack/test/template/render_test.rb index 31cfdce531..25bbc263dd 100644 --- a/actionpack/test/template/render_test.rb +++ b/actionpack/test/template/render_test.rb @@ -87,6 +87,14 @@ class ViewRenderTest < Test::Unit::TestCase @view.render(:partial => "test/local_inspector", :collection => [ Customer.new("mary") ]) end + def test_render_partial_with_empty_collection_should_return_nil + assert_nil @view.render(:partial => "test/customer", :collection => []) + end + + def test_render_partial_with_nil_collection_should_return_nil + assert_nil @view.render(:partial => "test/customer", :collection => nil) + end + # TODO: The reason for this test is unclear, improve documentation def test_render_partial_and_fallback_to_layout assert_equal "Before (Josh)\n\nAfter", @view.render(:partial => "test/layout_for_partial", :locals => { :name => "Josh" }) -- cgit v1.2.3 From 6f530de9443a4e2ab3d193624ff6ecd3c2b06de2 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Tue, 19 Aug 2008 20:15:51 -0500 Subject: Test coverage for integration testing with parameters --- actionpack/test/controller/integration_test.rb | 32 ++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) (limited to 'actionpack') diff --git a/actionpack/test/controller/integration_test.rb b/actionpack/test/controller/integration_test.rb index b878962df3..a5373912f5 100644 --- a/actionpack/test/controller/integration_test.rb +++ b/actionpack/test/controller/integration_test.rb @@ -259,6 +259,10 @@ class IntegrationProcessTest < ActionController::IntegrationTest end end + def get_with_params + render :text => "foo: #{params[:foo]}", :status => 200 + end + def post render :text => "Created", :status => 201 end @@ -362,6 +366,34 @@ class IntegrationProcessTest < ActionController::IntegrationTest end end + def test_get_with_query_string + 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 nil, request.env["QUERY_STRING"] + assert_equal 'foo=bar', request.query_string + assert_equal 'bar', request.parameters['foo'] + + assert_equal 200, status + assert_equal "foo: bar", response.body + end + end + + 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 'foo=bar', request.env["QUERY_STRING"] + assert_equal 'foo=bar', request.query_string + assert_equal 'bar', request.parameters['foo'] + + assert_equal 200, status + assert_equal "foo: bar", response.body + end + end + private def with_test_route_set with_routing do |set| -- cgit v1.2.3 From 3a2ff17af66dfb135ead212de458e7f6860c8004 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Tue, 19 Aug 2008 20:22:27 -0500 Subject: Don't shadow query string method --- actionpack/lib/action_controller/rack_process.rb | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/rack_process.rb b/actionpack/lib/action_controller/rack_process.rb index 69bfc549c1..1ace16da07 100644 --- a/actionpack/lib/action_controller/rack_process.rb +++ b/actionpack/lib/action_controller/rack_process.rb @@ -25,7 +25,7 @@ module ActionController #:nodoc: end %w[ AUTH_TYPE GATEWAY_INTERFACE PATH_INFO - PATH_TRANSLATED QUERY_STRING REMOTE_HOST + PATH_TRANSLATED REMOTE_HOST REMOTE_IDENT REMOTE_USER SCRIPT_NAME SERVER_NAME SERVER_PROTOCOL @@ -37,6 +37,15 @@ module ActionController #:nodoc: end end + def query_string + qs = super + if !qs.blank? + qs + else + @env['QUERY_STRING'] + end + end + def body_stream #:nodoc: @env['rack.input'] end -- cgit v1.2.3 From 7ee01c8c5415579a68fe4bf073f69cf5796bf7c9 Mon Sep 17 00:00:00 2001 From: Iain Hecker Date: Tue, 19 Aug 2008 23:33:39 +0200 Subject: Changed locale file to yml for actionpack, but still broken --- actionpack/lib/action_view.rb | 2 +- actionpack/lib/action_view/locale/en-US.rb | 89 ----------------------------- actionpack/lib/action_view/locale/en-US.yml | 89 +++++++++++++++++++++++++++++ 3 files changed, 90 insertions(+), 90 deletions(-) delete mode 100644 actionpack/lib/action_view/locale/en-US.rb create mode 100644 actionpack/lib/action_view/locale/en-US.yml (limited to 'actionpack') diff --git a/actionpack/lib/action_view.rb b/actionpack/lib/action_view.rb index 7e9ae9432d..f13324a9d0 100644 --- a/actionpack/lib/action_view.rb +++ b/actionpack/lib/action_view.rb @@ -35,7 +35,7 @@ require 'action_view/partials' require 'action_view/template_error' I18n.backend.populate do - I18n.load_translations File.dirname(__FILE__) + '/action_view/locale/en-US.rb' + I18n.load_translations File.dirname(__FILE__) + '/action_view/locale/en-US.yml' end ActionView::Base.class_eval do diff --git a/actionpack/lib/action_view/locale/en-US.rb b/actionpack/lib/action_view/locale/en-US.rb deleted file mode 100644 index d4647b5a48..0000000000 --- a/actionpack/lib/action_view/locale/en-US.rb +++ /dev/null @@ -1,89 +0,0 @@ -{ :'en-US' => { - :datetime => { - :distance_in_words => { - :half_a_minute => 'half a minute', - :less_than_x_seconds => { - :one => 'less than 1 second', - :many => 'less than {{count}} seconds' - }, - :x_seconds => { - :one => '1 second', - :many => '{{count}} seconds' - }, - :less_than_x_minutes => { - :one => 'less than a minute', - :many => 'less than {{count}} minutes' - }, - :x_minutes => { - :one => '1 minute', - :many => '{{count}} minutes' - }, - :about_x_hours => { - :one => 'about 1 hour', - :many => 'about {{count}} hours' - }, - :x_days => { - :one => '1 day', - :many => '{{count}} days' - }, - :about_x_months => { - :one => 'about 1 month', - :many => 'about {{count}} months' - }, - :x_months => { - :one => '1 month', - :many => '{{count}} months' - }, - :about_x_years => { - :one => 'about 1 year', - :many => 'about {{count}} years' - }, - :over_x_years => { - :one => 'over 1 year', - :many => 'over {{count}} years' - } - } - }, - :number => { - :format => { - :precision => 3, - :separator => '.', - :delimiter => ',' - }, - :currency => { - :format => { - :unit => '$', - :precision => 2, - :format => '%u%n' - } - }, - :human => { - :format => { - :precision => 1, - :delimiter => '' - } - }, - :percentage => { - :format => { - :delimiter => '' - } - }, - :precision => { - :format => { - :delimiter => '' - } - } - }, - :activerecord => { - :errors => { - :template => { - :header => { - :one => "1 error prohibited this {{model}} from being saved", - :many => "{{count}} errors prohibited this {{model}} from being saved" - }, - :body => "There were problems with the following fields:" - } - } - } - } -} diff --git a/actionpack/lib/action_view/locale/en-US.yml b/actionpack/lib/action_view/locale/en-US.yml new file mode 100644 index 0000000000..d4039e9b12 --- /dev/null +++ b/actionpack/lib/action_view/locale/en-US.yml @@ -0,0 +1,89 @@ +"en-US": + number: + # Used in number_with_delimiter() + # These are also the defaults for 'currency', 'percentage', 'precision', and 'human' + format: + # Sets the seperator between the units, for more precision (e.g. 1.0 / 2.0 == 0.5) + seperator: "." + # Delimets thousands (e.g. 1,000,000 is a million) (always in groups of three) + delimeter: "," + # Number of decimals, behind the seperator (the number 1 with a precision of 2 gives: 1.00) + precision: 3 + + # Used in number_to_currency() + currency: + format: + # Where is the currency sign? %u is the currency unit, %n the number (default: $5.00) + format: "%u%n" + unit: "$" + # These three are to override number.format and are optional + seperator: "." + delimiter: "," + precision: 2 + + # Used in number_to_percentage() + percentage: + format: + # These three are to override number.format and are optional + seperator: "." + delimiter: "," + precision: 3 + + # Used in number_to_precision() + precision: + format: + # These three are to override number.format and are optional + seperator: "." + delimiter: "," + precision: 3 + + # Used in number_to_human_size() + human: + format: + # These three are to override number.format and are optional + seperator: "." + delimiter: "," + + # Used in distance_of_time_in_words(), distance_of_time_in_words_to_now(), time_ago_in_words() + datetime: + distance_in_words: + half_a_minute: "half a minute" + less_than_x_seconds: + one: "less than a second" + many: "less than {{count}} seconds" + x_seconds: + one: "1 second" + many: "{{count}} seconds" + less_than_x_minutes: + one: "less than 1 minutes" + many: "less than {{count}} minutes" + x_minutes: + one: "1 minute" + many: "{{count}} minutes" + about_x_hours: + one: "about 1 hour" + many: "about {{count}} hours" + x_days: + one: "1 day" + many: "{{count}} days" + about_x_months: + one: "about a month" + many: "about {{count}} months" + x_months: + one: "1 month" + many: "{{count}} months" + about_x_years: + one: "about 1 year" + many: "about {{count}} years" + over_x_years: + one: "over 1 year" + many: "over {{count}} years" + + activerecord: + errors: + header: + one: "1 error prohibited this {{model}} from being saved" + many: "{{count}} errors prohibited this {{model}} from being saved" + # The variable :count is also available + message: "There were problems with the following fields:" + -- cgit v1.2.3 From 950b9792baae14e42b894f113ae8dfc95df34da9 Mon Sep 17 00:00:00 2001 From: Sven Fuchs Date: Wed, 20 Aug 2008 18:44:18 +0200 Subject: fixing actionpack yml translations --- actionpack/lib/action_view/locale/en-US.yml | 44 +++++++++++++++-------------- 1 file changed, 23 insertions(+), 21 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/locale/en-US.yml b/actionpack/lib/action_view/locale/en-US.yml index d4039e9b12..57987f4e02 100644 --- a/actionpack/lib/action_view/locale/en-US.yml +++ b/actionpack/lib/action_view/locale/en-US.yml @@ -3,11 +3,11 @@ # Used in number_with_delimiter() # These are also the defaults for 'currency', 'percentage', 'precision', and 'human' format: - # Sets the seperator between the units, for more precision (e.g. 1.0 / 2.0 == 0.5) - seperator: "." + # Sets the separator between the units, for more precision (e.g. 1.0 / 2.0 == 0.5) + separator: "." # Delimets thousands (e.g. 1,000,000 is a million) (always in groups of three) - delimeter: "," - # Number of decimals, behind the seperator (the number 1 with a precision of 2 gives: 1.00) + delimiter: "," + # Number of decimals, behind the separator (the number 1 with a precision of 2 gives: 1.00) precision: 3 # Used in number_to_currency() @@ -17,7 +17,7 @@ format: "%u%n" unit: "$" # These three are to override number.format and are optional - seperator: "." + separator: "." delimiter: "," precision: 2 @@ -25,37 +25,38 @@ percentage: format: # These three are to override number.format and are optional - seperator: "." - delimiter: "," - precision: 3 + # separator: + delimiter: "" + # precision: # Used in number_to_precision() precision: format: # These three are to override number.format and are optional - seperator: "." - delimiter: "," - precision: 3 + # separator: + delimiter: "" + # precision: # Used in number_to_human_size() human: format: # These three are to override number.format and are optional - seperator: "." - delimiter: "," + # separator: + delimiter: "" + precision: 1 # Used in distance_of_time_in_words(), distance_of_time_in_words_to_now(), time_ago_in_words() datetime: distance_in_words: half_a_minute: "half a minute" less_than_x_seconds: - one: "less than a second" + one: "less than 1 second" many: "less than {{count}} seconds" x_seconds: one: "1 second" many: "{{count}} seconds" less_than_x_minutes: - one: "less than 1 minutes" + one: "less than a minute" many: "less than {{count}} minutes" x_minutes: one: "1 minute" @@ -67,7 +68,7 @@ one: "1 day" many: "{{count}} days" about_x_months: - one: "about a month" + one: "about 1 month" many: "about {{count}} months" x_months: one: "1 month" @@ -81,9 +82,10 @@ activerecord: errors: - header: - one: "1 error prohibited this {{model}} from being saved" - many: "{{count}} errors prohibited this {{model}} from being saved" - # The variable :count is also available - message: "There were problems with the following fields:" + template: + header: + one: "1 error prohibited this {{model}} from being saved" + many: "{{count}} errors prohibited this {{model}} from being saved" + # The variable :count is also available + body: "There were problems with the following fields:" -- cgit v1.2.3 From a74dbe6c528a46f11e709386c282ead8049840ba Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Wed, 20 Aug 2008 13:22:36 -0500 Subject: Improve test coverage for integration tests cookie header --- actionpack/test/controller/integration_test.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/test/controller/integration_test.rb b/actionpack/test/controller/integration_test.rb index a5373912f5..47ff2dbbd3 100644 --- a/actionpack/test/controller/integration_test.rb +++ b/actionpack/test/controller/integration_test.rb @@ -329,7 +329,10 @@ class IntegrationProcessTest < ActionController::IntegrationTest assert_response :gone assert_equal nil, response.headers["Set-Cookie"] assert_equal ["cookie_1=; path=/", "cookie_3=chocolate; path=/"], headers['set-cookie'] - assert_equal [[], ["chocolate"]], response.headers["cookie"] + assert_equal [ + CGI::Cookie::new("name" => "cookie_1", "value" => ""), + CGI::Cookie::new("name" => "cookie_3", "value" => "chocolate") + ], response.headers["cookie"] assert_equal [], headers["cookie"] assert_equal({"cookie_1"=>"", "cookie_2"=>"oatmeal", "cookie_3"=>"chocolate"}, cookies) assert_equal "Gone", response.body -- cgit v1.2.3 From 47cd8b81cc19345aa68323755c78ab03f8176590 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Wed, 20 Aug 2008 13:37:18 -0500 Subject: Switched integration test runner to use Rack processor instead of CGI --- actionpack/CHANGELOG | 2 + actionpack/lib/action_controller/integration.rb | 76 +++++++++++-------------- actionpack/test/controller/integration_test.rb | 2 +- 3 files changed, 35 insertions(+), 45 deletions(-) (limited to 'actionpack') diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG index db3378d9d9..b471be1df6 100644 --- a/actionpack/CHANGELOG +++ b/actionpack/CHANGELOG @@ -1,5 +1,7 @@ *Edge* +* Switched integration test runner to use Rack processor instead of CGI [Josh Peek] + * Made AbstractRequest.if_modified_sense return nil if the header could not be parsed [Jamis Buck] * Added back ActionController::Base.allow_concurrency flag [Josh Peek] diff --git a/actionpack/lib/action_controller/integration.rb b/actionpack/lib/action_controller/integration.rb index ca5923de2f..198a22e8dc 100644 --- a/actionpack/lib/action_controller/integration.rb +++ b/actionpack/lib/action_controller/integration.rb @@ -228,21 +228,6 @@ module ActionController end private - class StubCGI < CGI #:nodoc: - attr_accessor :stdinput, :stdoutput, :env_table - - def initialize(env, stdinput = nil) - self.env_table = env - self.stdoutput = StringIO.new - - super - - stdinput.set_encoding(Encoding::BINARY) if stdinput.respond_to?(:set_encoding) - stdinput.force_encoding(Encoding::BINARY) if stdinput.respond_to?(:force_encoding) - @stdinput = stdinput.is_a?(IO) ? stdinput : StringIO.new(stdinput || '') - end - end - # Tailors the session based on the given URI, setting the HTTPS value # and the hostname. def interpret_uri(path) @@ -290,9 +275,8 @@ module ActionController ActionController::Base.clear_last_instantiation! - cgi = StubCGI.new(env, data) - ActionController::Dispatcher.dispatch(cgi, ActionController::CgiRequest::DEFAULT_SESSION_OPTIONS, cgi.stdoutput) - @result = cgi.stdoutput.string + env['rack.input'] = data.is_a?(IO) ? data : StringIO.new(data || '') + @status, @headers, result_body = ActionController::Dispatcher.new.call(env) @request_count += 1 @controller = ActionController::Base.last_instantiation @@ -306,32 +290,34 @@ module ActionController @html_document = nil - parse_result - return status - rescue MultiPartNeededException - boundary = "----------XnJLe9ZIbbGUYtzPQJ16u1" - status = process(method, path, multipart_body(parameters, boundary), (headers || {}).merge({"CONTENT_TYPE" => "multipart/form-data; boundary=#{boundary}"})) - return status - end + # Inject status back in for backwords compatibility with CGI + @headers['Status'] = @status - # Parses the result of the response and extracts the various values, - # like cookies, status, headers, etc. - def parse_result - response_headers, result_body = @result.split(/\r\n\r\n/, 2) + @status, @status_message = @status.split(/ /) + @status = @status.to_i - @headers = Hash.new { |h,k| h[k] = [] } - response_headers.to_s.each_line do |line| - key, value = line.strip.split(/:\s*/, 2) - @headers[key.downcase] << value + cgi_headers = Hash.new { |h,k| h[k] = [] } + @headers.each do |key, value| + cgi_headers[key.downcase] << value end + cgi_headers['set-cookie'] = cgi_headers['set-cookie'].first + @headers = cgi_headers - (@headers['set-cookie'] || [] ).each do |string| - name, value = string.match(/^([^=]*)=([^;]*);/)[1,2] + @response.headers['cookie'] ||= [] + (@headers['set-cookie'] || []).each do |cookie| + name, value = cookie.match(/^([^=]*)=([^;]*);/)[1,2] @cookies[name] = value + + # Fake CGI cookie header + # DEPRECATE: Use response.headers["Set-Cookie"] instead + @response.headers['cookie'] << CGI::Cookie::new("name" => name, "value" => value) end - @status, @status_message = @headers["status"].first.to_s.split(/ /) - @status = @status.to_i + return status + rescue MultiPartNeededException + boundary = "----------XnJLe9ZIbbGUYtzPQJ16u1" + status = process(method, path, multipart_body(parameters, boundary), (headers || {}).merge({"CONTENT_TYPE" => "multipart/form-data; boundary=#{boundary}"})) + return status end # Encode the cookies hash in a format suitable for passing to a @@ -344,13 +330,15 @@ module ActionController # Get a temporary URL writer object def generic_url_rewriter - cgi = StubCGI.new('REQUEST_METHOD' => "GET", - 'QUERY_STRING' => "", - "REQUEST_URI" => "/", - "HTTP_HOST" => host, - "SERVER_PORT" => https? ? "443" : "80", - "HTTPS" => https? ? "on" : "off") - ActionController::UrlRewriter.new(ActionController::CgiRequest.new(cgi), {}) + env = { + 'REQUEST_METHOD' => "GET", + 'QUERY_STRING' => "", + "REQUEST_URI" => "/", + "HTTP_HOST" => host, + "SERVER_PORT" => https? ? "443" : "80", + "HTTPS" => https? ? "on" : "off" + } + ActionController::UrlRewriter.new(ActionController::RackRequest.new(env), {}) end def name_with_prefix(prefix, name) diff --git a/actionpack/test/controller/integration_test.rb b/actionpack/test/controller/integration_test.rb index 47ff2dbbd3..c986941140 100644 --- a/actionpack/test/controller/integration_test.rb +++ b/actionpack/test/controller/integration_test.rb @@ -327,7 +327,7 @@ class IntegrationProcessTest < ActionController::IntegrationTest assert_equal ["410 Gone"], headers["status"] assert_response 410 assert_response :gone - assert_equal nil, response.headers["Set-Cookie"] + assert_equal ["cookie_1=; path=/", "cookie_3=chocolate; path=/"], response.headers["Set-Cookie"] assert_equal ["cookie_1=; path=/", "cookie_3=chocolate; path=/"], headers['set-cookie'] assert_equal [ CGI::Cookie::new("name" => "cookie_1", "value" => ""), -- cgit v1.2.3 From f388725bd61d8ae246c0c8e42eaec1a2be4620ac Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Thu, 21 Aug 2008 00:28:25 -0500 Subject: Partial revert of 2681685 premature TypeArray abstraction --- actionpack/lib/action_view/paths.rb | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/paths.rb b/actionpack/lib/action_view/paths.rb index 6a118a1cfa..d6bf2137af 100644 --- a/actionpack/lib/action_view/paths.rb +++ b/actionpack/lib/action_view/paths.rb @@ -1,5 +1,5 @@ module ActionView #:nodoc: - class PathSet < ActiveSupport::TypedArray #:nodoc: + class PathSet < Array #:nodoc: def self.type_cast(obj) if obj.is_a?(String) if Base.warn_cache_misses && defined?(Rails) && Rails.initialized? @@ -15,6 +15,30 @@ module ActionView #:nodoc: 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) }) + end + class Path #:nodoc: def self.eager_load_templates! @eager_load_templates = true -- cgit v1.2.3 From 6be8251ec86b74b92e7bd922fafe9224281d2d26 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Thu, 21 Aug 2008 00:51:06 -0500 Subject: Simplified and renamed CallbackChain union method to replace_or_append! --- actionpack/lib/action_controller/dispatcher.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/dispatcher.rb b/actionpack/lib/action_controller/dispatcher.rb index 7e46f572fe..bdae5f9d86 100644 --- a/actionpack/lib/action_controller/dispatcher.rb +++ b/actionpack/lib/action_controller/dispatcher.rb @@ -44,7 +44,7 @@ module ActionController def to_prepare(identifier = nil, &block) @prepare_dispatch_callbacks ||= ActiveSupport::Callbacks::CallbackChain.new callback = ActiveSupport::Callbacks::Callback.new(:prepare_dispatch, block, :identifier => identifier) - @prepare_dispatch_callbacks | callback + @prepare_dispatch_callbacks.replace_or_append!(callback) end # If the block raises, send status code as a last-ditch response. -- cgit v1.2.3 From 7e4ea5f4a2fd25e06820689688e3db5a4851f8e0 Mon Sep 17 00:00:00 2001 From: Darragh Curran Date: Wed, 25 Jun 2008 11:15:26 +0100 Subject: Allow overriding id for feed and entry with atom_feed_builder. [#485 state:resolved] Signed-off-by: Pratik Naik --- .../lib/action_view/helpers/atom_feed_helper.rb | 24 +++++++------- actionpack/test/template/atom_feed_helper_test.rb | 37 +++++++++++++++++++--- 2 files changed, 45 insertions(+), 16 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/atom_feed_helper.rb b/actionpack/lib/action_view/helpers/atom_feed_helper.rb index ebb1cb34bc..e65d5d1f60 100644 --- a/actionpack/lib/action_view/helpers/atom_feed_helper.rb +++ b/actionpack/lib/action_view/helpers/atom_feed_helper.rb @@ -17,7 +17,7 @@ module ActionView # # GET /posts.atom # def index # @posts = Post.find(:all) - # + # # respond_to do |format| # format.html # format.atom @@ -29,12 +29,12 @@ module ActionView # atom_feed do |feed| # feed.title("My great blog!") # feed.updated((@posts.first.created_at)) - # + # # for post in @posts # feed.entry(post) do |entry| # entry.title(post.title) # entry.content(post.body, :type => 'html') - # + # # entry.author do |author| # author.name("DHH") # end @@ -47,8 +47,9 @@ module ActionView # * :language: Defaults to "en-US". # * :root_url: The HTML alternative that this feed is doubling for. Defaults to / on the current host. # * :url: The URL for this feed. Defaults to the current URL. - # * :schema_date: The date at which the tag scheme for the feed was first used. A good default is the year you - # created the feed. See http://feedvalidator.org/docs/error/InvalidTAG.html for more information. If not specified, + # * :id: The id for this feed. Defaults to "tag:#{request.host},#{options[:schema_date]}:#{request.request_uri.split(".")[0]}" + # * :schema_date: The date at which the tag scheme for the feed was first used. A good default is the year you + # created the feed. See http://feedvalidator.org/docs/error/InvalidTAG.html for more information. If not specified, # 2005 is used (as an "I don't care" value). # # Other namespaces can be added to the root element: @@ -81,7 +82,7 @@ module ActionView else options[:schema_date] = "2005" # The Atom spec copyright date end - + xml = options[:xml] || eval("xml", block.binding) xml.instruct! @@ -89,10 +90,10 @@ module ActionView feed_opts.merge!(options).reject!{|k,v| !k.to_s.match(/^xml/)} xml.feed(feed_opts) do - xml.id("tag:#{request.host},#{options[:schema_date]}:#{request.request_uri.split(".")[0]}") + xml.id(options[:id] || "tag:#{request.host},#{options[:schema_date]}:#{request.request_uri.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) - + yield AtomFeedBuilder.new(xml, self, options) end end @@ -102,7 +103,7 @@ module ActionView def initialize(xml, view, feed_options = {}) @xml, @view, @feed_options = xml, view, feed_options end - + # Accepts a Date or Time object and inserts it in the proper format. If nil is passed, current time in UTC is used. def updated(date_or_time = nil) @xml.updated((date_or_time || Time.now.utc).xmlschema) @@ -115,9 +116,10 @@ module ActionView # * :published: Time first published. Defaults to the created_at attribute on the record if one such exists. # * :updated: Time of update. Defaults to the updated_at attribute on the record if one such exists. # * :url: The URL for this entry. Defaults to the polymorphic_url for the record. + # * :id: The ID for this entry. Defaults to "tag:#{@view.request.host},#{@feed_options[:schema_date]}:#{record.class}/#{record.id}" def entry(record, options = {}) - @xml.entry do - @xml.id("tag:#{@view.request.host},#{@feed_options[:schema_date]}:#{record.class}/#{record.id}") + @xml.entry do + @xml.id(options[:id] || "tag:#{@view.request.host},#{@feed_options[:schema_date]}:#{record.class}/#{record.id}") if options[:published] || (record.respond_to?(:created_at) && record.created_at) @xml.published((options[:published] || record.created_at).xmlschema) diff --git a/actionpack/test/template/atom_feed_helper_test.rb b/actionpack/test/template/atom_feed_helper_test.rb index 9f7e5b4c6c..ef31ab2c76 100644 --- a/actionpack/test/template/atom_feed_helper_test.rb +++ b/actionpack/test/template/atom_feed_helper_test.rb @@ -67,6 +67,24 @@ class ScrollsController < ActionController::Base entry.content(scroll.body, :type => 'html') entry.tag!('app:edited', Time.now) + entry.author do |author| + author.name("DHH") + end + end + end + end + EOT + FEEDS["feed_with_overridden_ids"] = <<-EOT + atom_feed({:id => 'tag:test.rubyonrails.org,2008:test/'}) do |feed| + feed.title("My great blog!") + feed.updated((@scrolls.first.created_at)) + + for scroll in @scrolls + feed.entry(scroll, :id => "tag:test.rubyonrails.org,2008:"+scroll.id.to_s) do |entry| + entry.title(scroll.title) + entry.content(scroll.body, :type => 'html') + entry.tag!('app:edited', Time.now) + entry.author do |author| author.name("DHH") end @@ -79,7 +97,7 @@ class ScrollsController < ActionController::Base Scroll.new(1, "1", "Hello One", "Something COOL!", Time.utc(2007, 12, 12, 15), Time.utc(2007, 12, 12, 15)), Scroll.new(2, "2", "Hello Two", "Something Boring", Time.utc(2007, 12, 12, 15)), ] - + render :inline => FEEDS[params[:id]], :type => :builder end @@ -98,21 +116,21 @@ class AtomFeedTest < Test::Unit::TestCase @request.host = "www.nextangle.com" end - + def test_feed_should_use_default_language_if_none_is_given with_restful_routing(:scrolls) do get :index, :id => "defaults" assert_match %r{xml:lang="en-US"}, @response.body end end - + def test_feed_should_include_two_entries with_restful_routing(:scrolls) do get :index, :id => "defaults" assert_select "entry", 2 end end - + def test_entry_should_only_use_published_if_created_at_is_present with_restful_routing(:scrolls) do get :index, :id => "defaults" @@ -167,7 +185,16 @@ class AtomFeedTest < Test::Unit::TestCase end end - private + def test_feed_should_allow_overriding_ids + with_restful_routing(:scrolls) do + get :index, :id => "feed_with_overridden_ids" + assert_select "id", :text => "tag:test.rubyonrails.org,2008:test/" + assert_select "entry id", :text => "tag:test.rubyonrails.org,2008:1" + assert_select "entry id", :text => "tag:test.rubyonrails.org,2008:2" + end + end + +private def with_restful_routing(resources) with_routing do |set| set.draw do |map| -- cgit v1.2.3 From 98fb161dbb13feb18165468aedf1581d5c2305f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tarmo=20T=C3=A4nav?= Date: Thu, 21 Aug 2008 18:26:05 +0100 Subject: Allow polymorphic_url helper to take url options. [#880 state:resolved] All *_polymorphic_url, *_polymorphic_path helpers can now accept an options hash which will be passed on to the named route making it possible to generate polymorphic routes with additional url parameters. Signed-off-by: Pratik Naik --- actionpack/CHANGELOG | 2 ++ .../lib/action_controller/polymorphic_routes.rb | 16 +++++++++++----- .../test/controller/polymorphic_routes_test.rb | 22 ++++++++++++++++++++-- 3 files changed, 33 insertions(+), 7 deletions(-) (limited to 'actionpack') diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG index b471be1df6..be490093ac 100644 --- a/actionpack/CHANGELOG +++ b/actionpack/CHANGELOG @@ -1,5 +1,7 @@ *Edge* +* Allow polymorphic_url helper to take url options. #880 [Tarmo Tänav] + * Switched integration test runner to use Rack processor instead of CGI [Josh Peek] * Made AbstractRequest.if_modified_sense return nil if the header could not be parsed [Jamis Buck] diff --git a/actionpack/lib/action_controller/polymorphic_routes.rb b/actionpack/lib/action_controller/polymorphic_routes.rb index 7c30bf0778..30564c7bb3 100644 --- a/actionpack/lib/action_controller/polymorphic_routes.rb +++ b/actionpack/lib/action_controller/polymorphic_routes.rb @@ -102,6 +102,12 @@ module ActionController args << format if format named_route = build_named_route_call(record_or_hash_or_array, namespace, inflection, options) + + url_options = options.except(:action, :routing_type, :format) + unless url_options.empty? + args.last.kind_of?(Hash) ? args.last.merge!(url_options) : args << url_options + end + send!(named_route, *args) end @@ -114,19 +120,19 @@ module ActionController %w(edit new formatted).each do |action| module_eval <<-EOT, __FILE__, __LINE__ - def #{action}_polymorphic_url(record_or_hash) - polymorphic_url(record_or_hash, :action => "#{action}") + def #{action}_polymorphic_url(record_or_hash, options = {}) + polymorphic_url(record_or_hash, options.merge(:action => "#{action}")) end - def #{action}_polymorphic_path(record_or_hash) - polymorphic_url(record_or_hash, :action => "#{action}", :routing_type => :path) + def #{action}_polymorphic_path(record_or_hash, options = {}) + polymorphic_url(record_or_hash, options.merge(:action => "#{action}", :routing_type => :path)) end EOT end private def action_prefix(options) - options[:action] ? "#{options[:action]}_" : "" + options[:action] ? "#{options[:action]}_" : options[:format] ? "formatted_" : "" end def routing_type(options) diff --git a/actionpack/test/controller/polymorphic_routes_test.rb b/actionpack/test/controller/polymorphic_routes_test.rb index 3f52526f08..6ddf2826cd 100644 --- a/actionpack/test/controller/polymorphic_routes_test.rb +++ b/actionpack/test/controller/polymorphic_routes_test.rb @@ -60,6 +60,18 @@ uses_mocha 'polymorphic URL helpers' do edit_polymorphic_url(@article) end + def test_url_helper_prefixed_with_edit_with_url_options + @article.save + expects(:edit_article_url).with(@article, :param1 => '10') + edit_polymorphic_url(@article, :param1 => '10') + end + + def test_url_helper_with_url_options + @article.save + expects(:article_url).with(@article, :param1 => '10') + polymorphic_url(@article, :param1 => '10') + end + def test_formatted_url_helper expects(:formatted_article_url).with(@article, :pdf) formatted_polymorphic_url([@article, :pdf]) @@ -67,10 +79,16 @@ uses_mocha 'polymorphic URL helpers' do def test_format_option @article.save - expects(:article_url).with(@article, :pdf) + expects(:formatted_article_url).with(@article, :pdf) polymorphic_url(@article, :format => :pdf) end + def test_format_option_with_url_options + @article.save + expects(:formatted_article_url).with(@article, :pdf, :param1 => '10') + polymorphic_url(@article, :format => :pdf, :param1 => '10') + end + def test_id_and_format_option @article.save expects(:article_url).with(:id => @article, :format => :pdf) @@ -147,7 +165,7 @@ uses_mocha 'polymorphic URL helpers' do def test_nesting_with_array_containing_singleton_resource_and_format_option @tag = Tag.new @tag.save - expects(:article_response_tag_url).with(@article, @tag, :pdf) + expects(:formatted_article_response_tag_url).with(@article, @tag, :pdf) polymorphic_url([@article, :response, @tag], :format => :pdf) end -- cgit v1.2.3 From f8f077945f4d108d676384106a9dfcf5c6f7a33d Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Thu, 21 Aug 2008 18:11:09 -0700 Subject: Move default content type and charset from Base to Response. Handle charset = nil. --- actionpack/lib/action_controller/base.rb | 10 ------- actionpack/lib/action_controller/response.rb | 36 ++++++++++++++++++++----- actionpack/test/controller/content_type_test.rb | 20 ++++++++++++++ 3 files changed, 50 insertions(+), 16 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb index 09414e7702..ea7d336640 100644 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -548,7 +548,6 @@ module ActionController #:nodoc: @@guard.synchronize { send(method, *arguments) } end - assign_default_content_type_and_charset response.prepare! unless component_request? response ensure @@ -1219,15 +1218,6 @@ module ActionController #:nodoc: @action_name = (params['action'] || 'index') end - def assign_default_content_type_and_charset - response.content_type ||= Mime::HTML - response.charset ||= self.class.default_charset unless sending_file? - end - - def sending_file? - response.headers["Content-Transfer-Encoding"] == "binary" - end - def action_methods self.class.action_methods end diff --git a/actionpack/lib/action_controller/response.rb b/actionpack/lib/action_controller/response.rb index 7b57f499bb..5dac4128bb 100644 --- a/actionpack/lib/action_controller/response.rb +++ b/actionpack/lib/action_controller/response.rb @@ -40,6 +40,8 @@ module ActionController # :nodoc: attr_accessor :session, :cookies, :assigns, :template, :layout attr_accessor :redirected_to, :redirected_to_method_params + delegate :default_charset, :to => 'ActionController::Base' + def initialize @body, @headers, @session, @assigns = "", DEFAULT_HEADERS.merge("cookie" => []), [], [] end @@ -60,19 +62,31 @@ module ActionController # :nodoc: # the character set information will also be included in the content type # information. def content_type=(mime_type) - self.headers["Content-Type"] = charset ? "#{mime_type}; charset=#{charset}" : mime_type + self.headers["Content-Type"] = + if mime_type =~ /charset/ || (c = charset).nil? + mime_type.to_s + else + "#{mime_type}; charset=#{c}" + end end - + # Returns the response's content MIME type, or nil if content type has been set. def content_type content_type = String(headers["Content-Type"] || headers["type"]).split(";")[0] content_type.blank? ? nil : content_type end - - def charset=(encoding) - self.headers["Content-Type"] = "#{content_type || Mime::HTML}; charset=#{encoding}" + + # Set the charset of the Content-Type header. Set to nil to remove it. + # If no content type is set, it defaults to HTML. + def charset=(charset) + headers["Content-Type"] = + if charset + "#{content_type || Mime::HTML}; charset=#{charset}" + else + content_type || Mime::HTML.to_s + end end - + def charset charset = String(headers["Content-Type"] || headers["type"]).split(";")[1] charset.blank? ? nil : charset.strip.split("=")[1] @@ -104,7 +118,17 @@ module ActionController # :nodoc: self.body = "You are being redirected." end + def sending_file? + headers["Content-Transfer-Encoding"] == "binary" + end + + def assign_default_content_type_and_charset! + self.content_type ||= Mime::HTML + self.charset ||= default_charset unless sending_file? + end + def prepare! + assign_default_content_type_and_charset! set_content_length! handle_conditional_get! convert_content_type! diff --git a/actionpack/test/controller/content_type_test.rb b/actionpack/test/controller/content_type_test.rb index e1bc46bb56..ae71d62e11 100644 --- a/actionpack/test/controller/content_type_test.rb +++ b/actionpack/test/controller/content_type_test.rb @@ -19,6 +19,11 @@ class ContentTypeController < ActionController::Base render :text => "hello world!" end + def render_nil_charset_from_body + response.charset = nil + render :text => "hello world!" + end + def render_default_for_rhtml end @@ -85,8 +90,23 @@ class ContentTypeTest < Test::Unit::TestCase def test_charset_from_body get :render_charset_from_body + assert_equal Mime::HTML, @response.content_type assert_equal "utf-16", @response.charset + end + + def test_nil_charset_from_body + get :render_nil_charset_from_body assert_equal Mime::HTML, @response.content_type + assert_equal "utf-8", @response.charset, @response.headers.inspect + end + + def test_nil_default_for_rhtml + ContentTypeController.default_charset = nil + get :render_default_for_rhtml + assert_equal Mime::HTML, @response.content_type + assert_nil @response.charset, @response.headers.inspect + ensure + ContentTypeController.default_charset = "utf-8" end def test_default_for_rhtml -- cgit v1.2.3 From b99442933d9a4ffa7793d2cb2f73b2e9f22d2605 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Thu, 21 Aug 2008 18:14:32 -0700 Subject: deprecate Base#assign_default_content_type_and_charset --- actionpack/lib/action_controller/base.rb | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb index ea7d336640..082f09ff16 100644 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -1218,6 +1218,11 @@ module ActionController #:nodoc: @action_name = (params['action'] || 'index') end + def assign_default_content_type_and_charset + response.assign_default_content_type_and_charset! + end + deprecate :assign_default_content_type_and_charset => :'response.assign_default_content_type_and_charset!' + def action_methods self.class.action_methods end -- cgit v1.2.3 From e6a66cbd056f177f7e60341799aa95791fcfa19d Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Thu, 21 Aug 2008 18:16:16 -0700 Subject: update rack tests for default response content_type and charset --- actionpack/test/controller/rack_test.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'actionpack') diff --git a/actionpack/test/controller/rack_test.rb b/actionpack/test/controller/rack_test.rb index 30a1144aad..d5e56b9584 100644 --- a/actionpack/test/controller/rack_test.rb +++ b/actionpack/test/controller/rack_test.rb @@ -241,7 +241,7 @@ class RackResponseTest < BaseRackTest status, headers, body = @response.out(@output) assert_equal "200 OK", status assert_equal({ - "Content-Type" => "text/html", + "Content-Type" => "text/html; charset=utf-8", "Cache-Control" => "private, max-age=0, must-revalidate", "ETag" => '"65a8e27d8879283831b664bd8b7f0ad4"', "Set-Cookie" => [], @@ -261,7 +261,7 @@ class RackResponseTest < BaseRackTest status, headers, body = @response.out(@output) assert_equal "200 OK", status - assert_equal({"Content-Type" => "text/html", "Cache-Control" => "no-cache", "Set-Cookie" => []}, headers) + assert_equal({"Content-Type" => "text/html; charset=utf-8", "Cache-Control" => "no-cache", "Set-Cookie" => []}, headers) parts = [] body.each { |part| parts << part } @@ -278,7 +278,7 @@ class RackResponseTest < BaseRackTest status, headers, body = @response.out(@output) assert_equal "200 OK", status assert_equal({ - "Content-Type" => "text/html", + "Content-Type" => "text/html; charset=utf-8", "Cache-Control" => "private, max-age=0, must-revalidate", "ETag" => '"65a8e27d8879283831b664bd8b7f0ad4"', "Set-Cookie" => ["name=Josh; path="], -- cgit v1.2.3 From 1129a24caff9f1804c2bff6569c0cbd8598dfa86 Mon Sep 17 00:00:00 2001 From: Ryan Bates Date: Thu, 21 Aug 2008 21:02:10 -0500 Subject: Cleanup around partial rendering Signed-off-by: Joshua Peek --- actionpack/lib/action_controller/base.rb | 20 +----- actionpack/lib/action_controller/rescue.rb | 2 +- .../templates/rescues/diagnostics.erb | 4 +- .../templates/rescues/template_error.erb | 4 +- actionpack/lib/action_view/base.rb | 43 +++-------- actionpack/lib/action_view/partials.rb | 83 +++++++++++++--------- 6 files changed, 66 insertions(+), 90 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb index 082f09ff16..5887e1e3b4 100644 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -780,9 +780,6 @@ module ActionController #:nodoc: # render :file => "/path/to/some/template.erb", :layout => true, :status => 404 # render :file => "c:/path/to/some/template.erb", :layout => true, :status => 404 # - # # Renders a template relative to the template root and chooses the proper file extension - # render :file => "some/template", :use_full_path => true - # # === Rendering text # # Rendering of text is usually used for tests or for rendering prepared content, such as a cache. By default, text @@ -913,21 +910,10 @@ module ActionController #:nodoc: response.content_type ||= Mime::JSON render_for_text(json, options[:status]) - elsif partial = options[:partial] - partial = default_template_name if partial == true + elsif options[:partial] + options[:partial] = default_template_name if options[:partial] == true add_variables_to_assigns - - if collection = options[:collection] - render_for_text( - @template.send!(:render_partial_collection, partial, collection, - options[:spacer_template], options[:locals], options[:as]), options[:status] - ) - else - render_for_text( - @template.send!(:render_partial, partial, - options[:object], options[:locals]), options[:status] - ) - end + render_for_text(@template.render(options), options[:status]) elsif options[:update] add_variables_to_assigns diff --git a/actionpack/lib/action_controller/rescue.rb b/actionpack/lib/action_controller/rescue.rb index 482ac7d7a4..a1a9d68a35 100644 --- a/actionpack/lib/action_controller/rescue.rb +++ b/actionpack/lib/action_controller/rescue.rb @@ -182,7 +182,7 @@ module ActionController #:nodoc: @template.instance_variable_set("@rescues_path", File.dirname(rescues_path("stub"))) @template.send!(:assign_variables_from_controller) - @template.instance_variable_set("@contents", @template.render(:file => template_path_for_local_rescue(exception), :use_full_path => false)) + @template.instance_variable_set("@contents", @template.render(:file => template_path_for_local_rescue(exception))) response.content_type = Mime::HTML render_for_file(rescues_path("layout"), response_code_for_rescue(exception)) diff --git a/actionpack/lib/action_controller/templates/rescues/diagnostics.erb b/actionpack/lib/action_controller/templates/rescues/diagnostics.erb index 385c6c1b09..b5483eccae 100644 --- a/actionpack/lib/action_controller/templates/rescues/diagnostics.erb +++ b/actionpack/lib/action_controller/templates/rescues/diagnostics.erb @@ -6,6 +6,6 @@
<%=h @exception.clean_message %>
-<%= render(:file => @rescues_path + "/_trace.erb", :use_full_path => false) %> +<%= render(:file => @rescues_path + "/_trace.erb") %> -<%= render(:file => @rescues_path + "/_request_and_response.erb", :use_full_path => false) %> +<%= render(:file => @rescues_path + "/_request_and_response.erb") %> diff --git a/actionpack/lib/action_controller/templates/rescues/template_error.erb b/actionpack/lib/action_controller/templates/rescues/template_error.erb index 4aecc68d18..76fa3df89d 100644 --- a/actionpack/lib/action_controller/templates/rescues/template_error.erb +++ b/actionpack/lib/action_controller/templates/rescues/template_error.erb @@ -15,7 +15,7 @@ <% @real_exception = @exception @exception = @exception.original_exception || @exception %> -<%= render(:file => @rescues_path + "/_trace.erb", :use_full_path => false) %> +<%= render(:file => @rescues_path + "/_trace.erb") %> <% @exception = @real_exception %> -<%= render(:file => @rescues_path + "/_request_and_response.erb", :use_full_path => false) %> +<%= render(:file => @rescues_path + "/_request_and_response.erb") %> diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index 46bacbcbc1..cdbb71bdaa 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -239,7 +239,7 @@ module ActionView #:nodoc: local_assigns ||= {} if options.is_a?(String) - render_file(options, nil, local_assigns) + render(:file => options, :locals => local_assigns) elsif options == :update update_page(&block) elsif options.is_a?(Hash) @@ -262,13 +262,15 @@ module ActionView #:nodoc: end end elsif options[:file] - render_file(options[:file], nil, options[:locals]) - elsif options[:partial] && options.has_key?(:collection) - render_partial_collection(options[:partial], options[:collection], options[:spacer_template], options[:locals], options[:as]) + if options[:use_full_path] + ActiveSupport::Deprecation.warn("use_full_path option has been deprecated and has no affect.", caller) + end + + pick_template(options[:file]).render_template(self, options[:locals]) elsif options[:partial] - render_partial(options[:partial], options[:object], options[:locals]) + render_partial(options) elsif options[:inline] - render_inline(options[:inline], options[:locals], options[:type]) + InlineTemplate.new(options[:inline], options[:type]).render(self, options[:locals]) end end end @@ -345,35 +347,6 @@ module ActionView #:nodoc: memoize :pick_template private - # Renders the template present at template_path. The hash in local_assigns - # is made available as local variables. - def render_file(template_path, use_full_path = nil, local_assigns = {}) #:nodoc: - unless use_full_path == nil - ActiveSupport::Deprecation.warn("use_full_path option has been deprecated and has no affect.", caller) - end - - if defined?(ActionMailer) && defined?(ActionMailer::Base) && controller.is_a?(ActionMailer::Base) && - template_path.is_a?(String) && !template_path.include?("/") - raise ActionViewError, <<-END_ERROR - Due to changes in ActionMailer, you need to provide the mailer_name along with the template name. - - render "user_mailer/signup" - render :file => "user_mailer/signup" - - If you are rendering a subtemplate, you must now use controller-like partial syntax: - - render :partial => 'signup' # no mailer_name necessary - END_ERROR - end - - template = pick_template(template_path) - template.render_template(self, local_assigns) - end - - def render_inline(text, local_assigns = {}, type = nil) - InlineTemplate.new(text, type).render(self, local_assigns) - end - # Evaluate the local assigns and pushes them to the view. def evaluate_assigns unless @assigns_added diff --git a/actionpack/lib/action_view/partials.rb b/actionpack/lib/action_view/partials.rb index 074ba5a2b5..7f19532bc1 100644 --- a/actionpack/lib/action_view/partials.rb +++ b/actionpack/lib/action_view/partials.rb @@ -1,14 +1,15 @@ module ActionView - # There's also a convenience method for rendering sub templates within the current controller that depends on a single object - # (we call this kind of sub templates for partials). It relies on the fact that partials should follow the naming convention of being - # prefixed with an underscore -- as to separate them from regular templates that could be rendered on their own. + # There's also a convenience method for rendering sub templates within the current controller that depends on a + # single object (we call this kind of sub templates for partials). It relies on the fact that partials should + # follow the naming convention of being prefixed with an underscore -- as to separate them from regular + # templates that could be rendered on their own. # # In a template for Advertiser#account: # # <%= render :partial => "account" %> # - # This would render "advertiser/_account.erb" and pass the instance variable @account in as a local variable +account+ to - # the template for display. + # This would render "advertiser/_account.erb" and pass the instance variable @account in as a local variable + # +account+ to the template for display. # # In another template for Advertiser#buy, we could have: # @@ -18,24 +19,24 @@ module ActionView # <%= render :partial => "ad", :locals => { :ad => ad } %> # <% end %> # - # This would first render "advertiser/_account.erb" with @buyer passed in as the local variable +account+, then render - # "advertiser/_ad.erb" and pass the local variable +ad+ to the template for display. + # This would first render "advertiser/_account.erb" with @buyer passed in as the local variable +account+, then + # render "advertiser/_ad.erb" and pass the local variable +ad+ to the template for display. # # == Rendering a collection of partials # - # The example of partial use describes a familiar pattern where a template needs to iterate over an array and render a sub - # template for each of the elements. This pattern has been implemented as a single method that accepts an array and renders - # a partial by the same name as the elements contained within. So the three-lined example in "Using partials" can be rewritten - # with a single line: + # The example of partial use describes a familiar pattern where a template needs to iterate over an array and + # render a sub template for each of the elements. This pattern has been implemented as a single method that + # accepts an array and renders a partial by the same name as the elements contained within. So the three-lined + # example in "Using partials" can be rewritten with a single line: # # <%= render :partial => "ad", :collection => @advertisements %> # - # This will render "advertiser/_ad.erb" and pass the local variable +ad+ to the template for display. An iteration counter - # will automatically be made available to the template with a name of the form +partial_name_counter+. In the case of the - # example above, the template would be fed +ad_counter+. + # This will render "advertiser/_ad.erb" and pass the local variable +ad+ to the template for display. An + # iteration counter will automatically be made available to the template with a name of the form + # +partial_name_counter+. In the case of the example above, the template would be fed +ad_counter+. # - # NOTE: Due to backwards compatibility concerns, the collection can't be one of hashes. Normally you'd also just keep domain objects, - # like Active Records, in there. + # NOTE: Due to backwards compatibility concerns, the collection can't be one of hashes. Normally you'd also + # just keep domain objects, like Active Records, in there. # # == Rendering shared partials # @@ -47,8 +48,9 @@ module ActionView # # == Rendering partials with layouts # - # Partials can have their own layouts applied to them. These layouts are different than the ones that are specified globally - # for the entire action, but they work in a similar fashion. Imagine a list with two types of users: + # Partials can have their own layouts applied to them. These layouts are different than the ones that are + # specified globally for the entire action, but they work in a similar fashion. Imagine a list with two types + # of users: # # <%# app/views/users/index.html.erb &> # Here's the administrator: @@ -139,36 +141,51 @@ module ActionView extend ActiveSupport::Memoizable private - def render_partial(partial_path, object_assigns = nil, local_assigns = {}) #:nodoc: - local_assigns ||= {} + def render_partial(options = {}) #:nodoc: + local_assigns = options[:locals] || {} - case partial_path + case partial_path = options[:partial] when String, Symbol, NilClass - pick_template(find_partial_path(partial_path)).render_partial(self, object_assigns, local_assigns) + if options.has_key?(:collection) + render_partial_collection(options) + else + pick_template(find_partial_path(partial_path)).render_partial(self, options[:object], local_assigns) + end when ActionView::Helpers::FormBuilder builder_partial_path = partial_path.class.to_s.demodulize.underscore.sub(/_builder$/, '') - render_partial(builder_partial_path, object_assigns, (local_assigns || {}).merge(builder_partial_path.to_sym => partial_path)) + render_partial( + :partial => builder_partial_path, + :object => options[:object], + :locals => local_assigns.merge(builder_partial_path.to_sym => partial_path) + ) when Array, ActiveRecord::Associations::AssociationCollection, ActiveRecord::NamedScope::Scope if partial_path.any? - collection = partial_path - render_partial_collection(nil, collection, nil, local_assigns) + render_partial(:collection => partial_path, :locals => local_assigns) else "" end else - render_partial(ActionController::RecordIdentifier.partial_path(partial_path, controller.class.controller_path), partial_path, local_assigns) + object = partial_path + render_partial( + :partial => ActionController::RecordIdentifier.partial_path(object, controller.class.controller_path), + :object => object, + :locals => local_assigns + ) end end - def render_partial_collection(partial_path, collection, partial_spacer_template = nil, local_assigns = {}, as = nil) #:nodoc: - return nil if collection.blank? + def render_partial_collection(options = {}) #:nodoc: + return nil if options[:collection].blank? - local_assigns = local_assigns ? local_assigns.clone : {} - spacer = partial_spacer_template ? render(:partial => partial_spacer_template) : '' + partial = options[:partial] + spacer = options[:spacer_template] ? render(:partial => options[:spacer_template]) : '' + local_assigns = options[:locals] ? options[:locals].clone : {} + as = options[:as] index = 0 - collection.map do |object| - _partial_path ||= partial_path || ActionController::RecordIdentifier.partial_path(object, controller.class.controller_path) + options[:collection].map do |object| + _partial_path ||= partial || + ActionController::RecordIdentifier.partial_path(object, controller.class.controller_path) path = find_partial_path(_partial_path) template = pick_template(path) local_assigns[template.counter_name] = index @@ -178,7 +195,7 @@ module ActionView end.join(spacer) end - def find_partial_path(partial_path) + def find_partial_path(partial_path) #:nodoc: if partial_path.include?('/') File.join(File.dirname(partial_path), "_#{File.basename(partial_path)}") elsif respond_to?(:controller) -- cgit v1.2.3 From ba516b40f5867a68588c2fa5b6710dbfb97a12c6 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Thu, 21 Aug 2008 21:24:08 -0500 Subject: Tidy up pick partial template logic --- actionpack/lib/action_view/partials.rb | 30 ++++++++++++------------------ 1 file changed, 12 insertions(+), 18 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/partials.rb b/actionpack/lib/action_view/partials.rb index 7f19532bc1..a91417293a 100644 --- a/actionpack/lib/action_view/partials.rb +++ b/actionpack/lib/action_view/partials.rb @@ -149,21 +149,14 @@ module ActionView if options.has_key?(:collection) render_partial_collection(options) else - pick_template(find_partial_path(partial_path)).render_partial(self, options[:object], local_assigns) + _pick_partial_template(partial_path).render_partial(self, options[:object], local_assigns) end when ActionView::Helpers::FormBuilder builder_partial_path = partial_path.class.to_s.demodulize.underscore.sub(/_builder$/, '') - render_partial( - :partial => builder_partial_path, - :object => options[:object], - :locals => local_assigns.merge(builder_partial_path.to_sym => partial_path) - ) + local_assigns.merge!(builder_partial_path.to_sym => partial_path) + render_partial(:partial => builder_partial_path, :object => options[:object], :locals => local_assigns) when Array, ActiveRecord::Associations::AssociationCollection, ActiveRecord::NamedScope::Scope - if partial_path.any? - render_partial(:collection => partial_path, :locals => local_assigns) - else - "" - end + partial_path.any? ? render_partial(:collection => partial_path, :locals => local_assigns) : "" else object = partial_path render_partial( @@ -186,8 +179,7 @@ module ActionView options[:collection].map do |object| _partial_path ||= partial || ActionController::RecordIdentifier.partial_path(object, controller.class.controller_path) - path = find_partial_path(_partial_path) - template = pick_template(path) + template = _pick_partial_template(_partial_path) local_assigns[template.counter_name] = index result = template.render_partial(self, object, local_assigns, as) index += 1 @@ -195,15 +187,17 @@ module ActionView end.join(spacer) end - def find_partial_path(partial_path) #:nodoc: + def _pick_partial_template(partial_path) #:nodoc: if partial_path.include?('/') - File.join(File.dirname(partial_path), "_#{File.basename(partial_path)}") + path = File.join(File.dirname(partial_path), "_#{File.basename(partial_path)}") elsif respond_to?(:controller) - "#{controller.class.controller_path}/_#{partial_path}" + path = "#{controller.class.controller_path}/_#{partial_path}" else - "_#{partial_path}" + path = "_#{partial_path}" end + + pick_template(path) end - memoize :find_partial_path + memoize :_pick_partial_template end end -- cgit v1.2.3 From 0096f5586987b720ca24c09103c9371f64ed26e5 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Thu, 21 Aug 2008 21:34:03 -0500 Subject: Removed template_public? because it will always be true since the default template is never a partial --- actionpack/lib/action_controller/base.rb | 6 +----- actionpack/lib/action_view/base.rb | 5 ----- 2 files changed, 1 insertion(+), 10 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb index 5887e1e3b4..91023cd774 100644 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -1189,7 +1189,7 @@ module ActionController #:nodoc: elsif respond_to? :method_missing method_missing action_name default_render unless performed? - elsif template_exists? && template_public? + elsif template_exists? default_render else raise UnknownAction, "No action responded to #{action_name}. Actions: #{action_methods.sort.to_sentence}", caller @@ -1264,10 +1264,6 @@ module ActionController #:nodoc: @template.file_exists?(template_name) end - def template_public?(template_name = default_template_name) - @template.file_public?(template_name) - end - def template_exempt_from_layout?(template_name = default_template_name) template_name = @template.pick_template(template_name).to_s if @template @@exempt_from_layout.any? { |ext| template_name =~ ext } diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index cdbb71bdaa..a85e698c1f 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -275,11 +275,6 @@ module ActionView #:nodoc: end end - # Returns true is the file may be rendered implicitly. - def file_public?(template_path)#:nodoc: - template_path.split('/').last[0,1] != '_' - end - # The format to be used when choosing between multiple templates with # the same name but differing formats. See +Request#template_format+ # for more details. -- cgit v1.2.3 From 9a5ffaa01e5a13d9ec2209a1a937d46fc12615a1 Mon Sep 17 00:00:00 2001 From: Ryan Bates Date: Fri, 22 Aug 2008 08:04:27 -0700 Subject: Ensure :partial => @collection and :collection => @collection behaves same. [#884 state:resolved] Signed-off-by: Pratik Naik --- actionpack/lib/action_view/partials.rb | 2 +- .../render_partial_with_record_identification_test.rb | 10 ++++++++++ actionpack/test/template/render_test.rb | 4 ++++ 3 files changed, 15 insertions(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/partials.rb b/actionpack/lib/action_view/partials.rb index a91417293a..4d19d992df 100644 --- a/actionpack/lib/action_view/partials.rb +++ b/actionpack/lib/action_view/partials.rb @@ -156,7 +156,7 @@ module ActionView local_assigns.merge!(builder_partial_path.to_sym => partial_path) render_partial(:partial => builder_partial_path, :object => options[:object], :locals => local_assigns) when Array, ActiveRecord::Associations::AssociationCollection, ActiveRecord::NamedScope::Scope - partial_path.any? ? render_partial(:collection => partial_path, :locals => local_assigns) : "" + render_partial_collection(options.except(:partial).merge(:collection => partial_path)) else object = partial_path render_partial( diff --git a/actionpack/test/activerecord/render_partial_with_record_identification_test.rb b/actionpack/test/activerecord/render_partial_with_record_identification_test.rb index a82a1a3023..d75cb2b53a 100644 --- a/actionpack/test/activerecord/render_partial_with_record_identification_test.rb +++ b/actionpack/test/activerecord/render_partial_with_record_identification_test.rb @@ -39,6 +39,11 @@ class RenderPartialWithRecordIdentificationController < ActionController::Base @developers = Developer.find(:all) render :partial => @developers end + + def render_with_record_collection_and_spacer_template + @developer = Developer.find(1) + render :partial => @developer.projects, :spacer_template => 'test/partial_only' + end end class RenderPartialWithRecordIdentificationTest < ActiveRecordTestCase @@ -81,6 +86,11 @@ class RenderPartialWithRecordIdentificationTest < ActiveRecordTestCase assert_equal 'DavidJamisfixture_3fixture_4fixture_5fixture_6fixture_7fixture_8fixture_9fixture_10Jamis', @response.body end + def test_render_with_record_collection_and_spacer_template + get :render_with_record_collection_and_spacer_template + assert_equal 'Active Recordonly partialActive Controller', @response.body + end + def test_rendering_partial_with_has_one_association mascot = Company.find(1).mascot get :render_with_has_one_association diff --git a/actionpack/test/template/render_test.rb b/actionpack/test/template/render_test.rb index 25bbc263dd..f3c8dbcae9 100644 --- a/actionpack/test/template/render_test.rb +++ b/actionpack/test/template/render_test.rb @@ -95,6 +95,10 @@ class ViewRenderTest < Test::Unit::TestCase assert_nil @view.render(:partial => "test/customer", :collection => nil) end + def test_render_partial_with_empty_array_should_return_nil + assert_nil @view.render(:partial => []) + end + # TODO: The reason for this test is unclear, improve documentation def test_render_partial_and_fallback_to_layout assert_equal "Before (Josh)\n\nAfter", @view.render(:partial => "test/layout_for_partial", :locals => { :name => "Josh" }) -- cgit v1.2.3 From 23fb26a0dcbd46d36bdbc2caa267aa3192f77a24 Mon Sep 17 00:00:00 2001 From: Sven Fuchs Date: Sat, 23 Aug 2008 19:43:57 +0200 Subject: I18n: use :other instead of :many as default key for pluralization to better conform w/ cldr pluralization rules --- actionpack/lib/action_view/locale/en-US.yml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/locale/en-US.yml b/actionpack/lib/action_view/locale/en-US.yml index 57987f4e02..eabdbf33d6 100644 --- a/actionpack/lib/action_view/locale/en-US.yml +++ b/actionpack/lib/action_view/locale/en-US.yml @@ -51,41 +51,41 @@ half_a_minute: "half a minute" less_than_x_seconds: one: "less than 1 second" - many: "less than {{count}} seconds" + other: "less than {{count}} seconds" x_seconds: one: "1 second" - many: "{{count}} seconds" + other: "{{count}} seconds" less_than_x_minutes: one: "less than a minute" - many: "less than {{count}} minutes" + other: "less than {{count}} minutes" x_minutes: one: "1 minute" - many: "{{count}} minutes" + other: "{{count}} minutes" about_x_hours: one: "about 1 hour" - many: "about {{count}} hours" + other: "about {{count}} hours" x_days: one: "1 day" - many: "{{count}} days" + other: "{{count}} days" about_x_months: one: "about 1 month" - many: "about {{count}} months" + other: "about {{count}} months" x_months: one: "1 month" - many: "{{count}} months" + other: "{{count}} months" about_x_years: one: "about 1 year" - many: "about {{count}} years" + other: "about {{count}} years" over_x_years: one: "over 1 year" - many: "over {{count}} years" + other: "over {{count}} years" activerecord: errors: template: header: one: "1 error prohibited this {{model}} from being saved" - many: "{{count}} errors prohibited this {{model}} from being saved" + other: "{{count}} errors prohibited this {{model}} from being saved" # The variable :count is also available body: "There were problems with the following fields:" -- cgit v1.2.3 From d6989aa0e1fe5e49fe1fccc3702aa7ff62a63faf Mon Sep 17 00:00:00 2001 From: Sven Fuchs Date: Sat, 23 Aug 2008 19:43:57 +0200 Subject: I18n: use :other instead of :many as default key for pluralization to better conform w/ cldr pluralization rules Signed-off-by: Michael Koziarski --- actionpack/lib/action_view/locale/en-US.yml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/locale/en-US.yml b/actionpack/lib/action_view/locale/en-US.yml index 57987f4e02..eabdbf33d6 100644 --- a/actionpack/lib/action_view/locale/en-US.yml +++ b/actionpack/lib/action_view/locale/en-US.yml @@ -51,41 +51,41 @@ half_a_minute: "half a minute" less_than_x_seconds: one: "less than 1 second" - many: "less than {{count}} seconds" + other: "less than {{count}} seconds" x_seconds: one: "1 second" - many: "{{count}} seconds" + other: "{{count}} seconds" less_than_x_minutes: one: "less than a minute" - many: "less than {{count}} minutes" + other: "less than {{count}} minutes" x_minutes: one: "1 minute" - many: "{{count}} minutes" + other: "{{count}} minutes" about_x_hours: one: "about 1 hour" - many: "about {{count}} hours" + other: "about {{count}} hours" x_days: one: "1 day" - many: "{{count}} days" + other: "{{count}} days" about_x_months: one: "about 1 month" - many: "about {{count}} months" + other: "about {{count}} months" x_months: one: "1 month" - many: "{{count}} months" + other: "{{count}} months" about_x_years: one: "about 1 year" - many: "about {{count}} years" + other: "about {{count}} years" over_x_years: one: "over 1 year" - many: "over {{count}} years" + other: "over {{count}} years" activerecord: errors: template: header: one: "1 error prohibited this {{model}} from being saved" - many: "{{count}} errors prohibited this {{model}} from being saved" + other: "{{count}} errors prohibited this {{model}} from being saved" # The variable :count is also available body: "There were problems with the following fields:" -- cgit v1.2.3 From 2efdeb7a9517b677240e2c821c97941f6b905923 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Sat, 23 Aug 2008 16:06:54 -0700 Subject: Ruby 1.9 compat: set source encoding --- actionpack/test/template/url_helper_test.rb | 1 + 1 file changed, 1 insertion(+) (limited to 'actionpack') diff --git a/actionpack/test/template/url_helper_test.rb b/actionpack/test/template/url_helper_test.rb index 3065d33c1b..85e967ac1c 100644 --- a/actionpack/test/template/url_helper_test.rb +++ b/actionpack/test/template/url_helper_test.rb @@ -1,3 +1,4 @@ +# encoding: utf-8 require 'abstract_unit' RequestMock = Struct.new("Request", :request_uri, :protocol, :host_with_port, :env) -- cgit v1.2.3 From 8a4d7233aafc2f140f859fb02e686303fcac63ba Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Sun, 24 Aug 2008 11:10:15 -0700 Subject: Update translations for pluralization key change from 'other' to 'many' --- actionpack/lib/action_view/locale/en-US.yml | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/locale/en-US.yml b/actionpack/lib/action_view/locale/en-US.yml index eabdbf33d6..57987f4e02 100644 --- a/actionpack/lib/action_view/locale/en-US.yml +++ b/actionpack/lib/action_view/locale/en-US.yml @@ -51,41 +51,41 @@ half_a_minute: "half a minute" less_than_x_seconds: one: "less than 1 second" - other: "less than {{count}} seconds" + many: "less than {{count}} seconds" x_seconds: one: "1 second" - other: "{{count}} seconds" + many: "{{count}} seconds" less_than_x_minutes: one: "less than a minute" - other: "less than {{count}} minutes" + many: "less than {{count}} minutes" x_minutes: one: "1 minute" - other: "{{count}} minutes" + many: "{{count}} minutes" about_x_hours: one: "about 1 hour" - other: "about {{count}} hours" + many: "about {{count}} hours" x_days: one: "1 day" - other: "{{count}} days" + many: "{{count}} days" about_x_months: one: "about 1 month" - other: "about {{count}} months" + many: "about {{count}} months" x_months: one: "1 month" - other: "{{count}} months" + many: "{{count}} months" about_x_years: one: "about 1 year" - other: "about {{count}} years" + many: "about {{count}} years" over_x_years: one: "over 1 year" - other: "over {{count}} years" + many: "over {{count}} years" activerecord: errors: template: header: one: "1 error prohibited this {{model}} from being saved" - other: "{{count}} errors prohibited this {{model}} from being saved" + many: "{{count}} errors prohibited this {{model}} from being saved" # The variable :count is also available body: "There were problems with the following fields:" -- cgit v1.2.3 From 90a9637d41016c0d230ba36657e83a4f8d54cc46 Mon Sep 17 00:00:00 2001 From: Sven Fuchs Date: Mon, 25 Aug 2008 11:06:18 +0200 Subject: I18n: add aliases #t and #l to TranslationHelper#translate and #localize --- actionpack/lib/action_view/helpers/translation_helper.rb | 2 ++ 1 file changed, 2 insertions(+) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/helpers/translation_helper.rb b/actionpack/lib/action_view/helpers/translation_helper.rb index 60ac5c8790..de4c1d7689 100644 --- a/actionpack/lib/action_view/helpers/translation_helper.rb +++ b/actionpack/lib/action_view/helpers/translation_helper.rb @@ -11,10 +11,12 @@ module ActionView keys = I18n.send :normalize_translation_keys, e.locale, e.key, e.options[:scope] content_tag('span', keys.join(', '), :class => 'translation_missing') end + alias :t :translate def localize(*args) I18n.localize *args end + alias :l :localize end end end \ No newline at end of file -- cgit v1.2.3 From d0a4d9b73a27f882e3ff04ec2509e1f0e809b281 Mon Sep 17 00:00:00 2001 From: Sven Fuchs Date: Mon, 25 Aug 2008 11:25:59 +0200 Subject: Update translations for pluralization key change from 'many' to 'other' --- actionpack/lib/action_view/locale/en-US.yml | 44 ++++++++++++++--------------- 1 file changed, 22 insertions(+), 22 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/locale/en-US.yml b/actionpack/lib/action_view/locale/en-US.yml index 57987f4e02..818f2f93bd 100644 --- a/actionpack/lib/action_view/locale/en-US.yml +++ b/actionpack/lib/action_view/locale/en-US.yml @@ -50,42 +50,42 @@ distance_in_words: half_a_minute: "half a minute" less_than_x_seconds: - one: "less than 1 second" - many: "less than {{count}} seconds" + one: "less than 1 second" + other: "less than {{count}} seconds" x_seconds: - one: "1 second" - many: "{{count}} seconds" + one: "1 second" + other: "{{count}} seconds" less_than_x_minutes: - one: "less than a minute" - many: "less than {{count}} minutes" + one: "less than a minute" + other: "less than {{count}} minutes" x_minutes: - one: "1 minute" - many: "{{count}} minutes" + one: "1 minute" + other: "{{count}} minutes" about_x_hours: - one: "about 1 hour" - many: "about {{count}} hours" + one: "about 1 hour" + other: "about {{count}} hours" x_days: - one: "1 day" - many: "{{count}} days" + one: "1 day" + other: "{{count}} days" about_x_months: - one: "about 1 month" - many: "about {{count}} months" + one: "about 1 month" + other: "about {{count}} months" x_months: - one: "1 month" - many: "{{count}} months" + one: "1 month" + other: "{{count}} months" about_x_years: - one: "about 1 year" - many: "about {{count}} years" + one: "about 1 year" + other: "about {{count}} years" over_x_years: - one: "over 1 year" - many: "over {{count}} years" + one: "over 1 year" + other: "over {{count}} years" activerecord: errors: template: header: - one: "1 error prohibited this {{model}} from being saved" - many: "{{count}} errors prohibited this {{model}} from being saved" + one: "1 error prohibited this {{model}} from being saved" + other: "{{count}} errors prohibited this {{model}} from being saved" # The variable :count is also available body: "There were problems with the following fields:" -- cgit v1.2.3 From fe2640549bfc57cd862742494198781fda07ce36 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Mon, 25 Aug 2008 15:26:26 -0500 Subject: Base path may be nil if template is at the root of the view path --- actionpack/lib/action_view/template_error.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/template_error.rb b/actionpack/lib/action_view/template_error.rb index 35fc07bdb2..2368662f31 100644 --- a/actionpack/lib/action_view/template_error.rb +++ b/actionpack/lib/action_view/template_error.rb @@ -7,7 +7,7 @@ module ActionView attr_reader :original_exception def initialize(template, assigns, original_exception) - @base_path = template.base_path + @base_path = template.base_path.to_s @assigns, @source, @original_exception = assigns.dup, template.source, original_exception @file_path = template.filename @backtrace = compute_backtrace -- cgit v1.2.3 From a916c2e3d316c8338fa1d9d15f449403bddddf11 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Mon, 25 Aug 2008 15:34:55 -0500 Subject: The view context always responds to controller, check if controller available instead --- actionpack/lib/action_view/partials.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/partials.rb b/actionpack/lib/action_view/partials.rb index 4d19d992df..443c49b870 100644 --- a/actionpack/lib/action_view/partials.rb +++ b/actionpack/lib/action_view/partials.rb @@ -190,7 +190,7 @@ module ActionView def _pick_partial_template(partial_path) #:nodoc: if partial_path.include?('/') path = File.join(File.dirname(partial_path), "_#{File.basename(partial_path)}") - elsif respond_to?(:controller) + elsif controller path = "#{controller.class.controller_path}/_#{partial_path}" else path = "_#{partial_path}" -- cgit v1.2.3 From ba0d621695c372464383b56d2f33a7b892ed6aa5 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Mon, 25 Aug 2008 21:24:48 -0500 Subject: Include all helpers into ActionView::Helper --- actionpack/lib/action_view.rb | 7 +- actionpack/lib/action_view/base.rb | 13 ---- actionpack/lib/action_view/helpers.rb | 39 ++++++++++ .../lib/action_view/helpers/sanitize_helper.rb | 85 ++++++++++++++-------- actionpack/lib/action_view/test_case.rb | 4 +- actionpack/test/template/sanitize_helper_test.rb | 6 +- 6 files changed, 100 insertions(+), 54 deletions(-) create mode 100644 actionpack/lib/action_view/helpers.rb (limited to 'actionpack') diff --git a/actionpack/lib/action_view.rb b/actionpack/lib/action_view.rb index f13324a9d0..3f35303a51 100644 --- a/actionpack/lib/action_view.rb +++ b/actionpack/lib/action_view.rb @@ -38,10 +38,9 @@ I18n.backend.populate do I18n.load_translations File.dirname(__FILE__) + '/action_view/locale/en-US.yml' end +require 'action_view/helpers' + ActionView::Base.class_eval do include ActionView::Partials - - ActionView::Base.helper_modules.each do |helper_module| - include helper_module - end + include ActionView::Helpers end diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index a85e698c1f..cc89c66a39 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -203,19 +203,6 @@ module ActionView #:nodoc: end include CompiledTemplates - def self.helper_modules #:nodoc: - helpers = [] - Dir.entries(File.expand_path("#{File.dirname(__FILE__)}/helpers")).sort.each do |file| - next unless file =~ /^([a-z][a-z_]*_helper).rb$/ - require "action_view/helpers/#{$1}" - helper_module_name = $1.camelize - if Helpers.const_defined?(helper_module_name) - helpers << Helpers.const_get(helper_module_name) - end - end - return helpers - end - def self.process_view_paths(value) ActionView::PathSet.new(Array(value)) end diff --git a/actionpack/lib/action_view/helpers.rb b/actionpack/lib/action_view/helpers.rb new file mode 100644 index 0000000000..05e1cf990a --- /dev/null +++ b/actionpack/lib/action_view/helpers.rb @@ -0,0 +1,39 @@ +Dir.entries(File.expand_path("#{File.dirname(__FILE__)}/helpers")).sort.each do |file| + next unless file =~ /^([a-z][a-z_]*_helper).rb$/ + require "action_view/helpers/#{$1}" +end + +module ActionView #:nodoc: + module Helpers #:nodoc: + def self.included(base) + base.extend(ClassMethods) + end + + module ClassMethods + include SanitizeHelper::ClassMethods + end + + include ActiveRecordHelper + include AssetTagHelper + include AtomFeedHelper + include BenchmarkHelper + include CacheHelper + include CaptureHelper + include DateHelper + include DebugHelper + include FormCountryHelper + include FormHelper + include FormOptionsHelper + include FormTagHelper + include NumberHelper + include PrototypeHelper + include RecordIdentificationHelper + include RecordTagHelper + include SanitizeHelper + include ScriptaculousHelper + include TagHelper + include TextHelper + include TranslationHelper + include UrlHelper + end +end diff --git a/actionpack/lib/action_view/helpers/sanitize_helper.rb b/actionpack/lib/action_view/helpers/sanitize_helper.rb index c3c03394ee..637caf203b 100644 --- a/actionpack/lib/action_view/helpers/sanitize_helper.rb +++ b/actionpack/lib/action_view/helpers/sanitize_helper.rb @@ -6,17 +6,13 @@ module ActionView # The SanitizeHelper module provides a set of methods for scrubbing text of undesired HTML elements. # These helper methods extend ActionView making them callable within your template files. module SanitizeHelper - def self.included(base) - base.extend(ClassMethods) - end - # This +sanitize+ helper will html encode all tags and strip all attributes that aren't specifically allowed. # It also strips href/src tags with invalid protocols, like javascript: especially. It does its best to counter any # tricks that hackers may use, like throwing in unicode/ascii/hex values to get past the javascript: filters. Check out # the extensive test suite. # # <%= sanitize @article.body %> - # + # # You can add or remove tags/attributes if you want to customize it a bit. See ActionView::Base for full docs on the # available options. You can add tags/attributes for single uses of +sanitize+ by passing either the :attributes or :tags options: # @@ -27,27 +23,27 @@ module ActionView # Custom Use (only the mentioned tags and attributes are allowed, nothing else) # # <%= sanitize @article.body, :tags => %w(table tr td), :attributes => %w(id class style) - # + # # Add table tags to the default allowed tags - # + # # Rails::Initializer.run do |config| # config.action_view.sanitized_allowed_tags = 'table', 'tr', 'td' # end - # + # # Remove tags to the default allowed tags - # + # # Rails::Initializer.run do |config| # config.after_initialize do # ActionView::Base.sanitized_allowed_tags.delete 'div' # end # end - # + # # Change allowed default attributes - # + # # Rails::Initializer.run do |config| # config.action_view.sanitized_allowed_attributes = 'id', 'class', 'style' # end - # + # # Please note that sanitizing user-provided text does not guarantee that the # resulting markup is valid (conforming to a document type) or even well-formed. # The output may still contain e.g. unescaped '<', '>', '&' characters and @@ -62,8 +58,8 @@ module ActionView self.class.white_list_sanitizer.sanitize_css(style) end - # Strips all HTML tags from the +html+, including comments. This uses the - # html-scanner tokenizer and so its HTML parsing ability is limited by + # Strips all HTML tags from the +html+, including comments. This uses the + # html-scanner tokenizer and so its HTML parsing ability is limited by # that of html-scanner. # # ==== Examples @@ -73,10 +69,10 @@ module ActionView # # strip_tags("Bold no more! See more here...") # # => Bold no more! See more here... - # + # # strip_tags("
Welcome to my website!
") # # => Welcome to my website! - def strip_tags(html) + def strip_tags(html) self.class.full_sanitizer.sanitize(html) end @@ -96,21 +92,48 @@ module ActionView end module ClassMethods #:nodoc: - def self.extended(base) - class << base - attr_writer :full_sanitizer, :link_sanitizer, :white_list_sanitizer - - # we want these to be class methods on ActionView::Base, they'll get mattr_readers for these below. - helper_def = [:sanitized_protocol_separator, :sanitized_uri_attributes, :sanitized_bad_tags, :sanitized_allowed_tags, - :sanitized_allowed_attributes, :sanitized_allowed_css_properties, :sanitized_allowed_css_keywords, - :sanitized_shorthand_css_properties, :sanitized_allowed_protocols, :sanitized_protocol_separator=].collect! do |prop| - prop = prop.to_s - "def #{prop}(#{:value if prop =~ /=$/}) white_list_sanitizer.#{prop.sub /sanitized_/, ''} #{:value if prop =~ /=$/} end" - end.join("\n") - eval helper_def - end - end - + attr_writer :full_sanitizer, :link_sanitizer, :white_list_sanitizer + + def sanitized_protocol_separator + white_list_sanitizer.protocol_separator + end + + def sanitized_uri_attributes + white_list_sanitizer.uri_attributes + end + + def sanitized_bad_tags + white_list_sanitizer.bad_tags + end + + def sanitized_allowed_tags + white_list_sanitizer.allowed_tags + end + + def sanitized_allowed_attributes + white_list_sanitizer.allowed_attributes + end + + def sanitized_allowed_css_properties + white_list_sanitizer.allowed_css_properties + end + + def sanitized_allowed_css_keywords + white_list_sanitizer.allowed_css_keywords + end + + def sanitized_shorthand_css_properties + white_list_sanitizer.shorthand_css_properties + end + + def sanitized_allowed_protocols + white_list_sanitizer.allowed_protocols + end + + def sanitized_protocol_separator=(value) + white_list_sanitizer.protocol_separator = value + end + # Gets the HTML::FullSanitizer instance used by +strip_tags+. Replace with # any object that responds to +sanitize+. # diff --git a/actionpack/lib/action_view/test_case.rb b/actionpack/lib/action_view/test_case.rb index 1a3c93c283..adbb37fd09 100644 --- a/actionpack/lib/action_view/test_case.rb +++ b/actionpack/lib/action_view/test_case.rb @@ -25,9 +25,7 @@ module ActionView end end - ActionView::Base.helper_modules.each do |helper_module| - include helper_module - end + include ActionView::Helpers include ActionController::PolymorphicRoutes include ActionController::RecordIdentifier diff --git a/actionpack/test/template/sanitize_helper_test.rb b/actionpack/test/template/sanitize_helper_test.rb index e5427d9dc1..f715071bbc 100644 --- a/actionpack/test/template/sanitize_helper_test.rb +++ b/actionpack/test/template/sanitize_helper_test.rb @@ -11,9 +11,9 @@ class SanitizeHelperTest < ActionView::TestCase assert_equal "Dont touch me", strip_links("Dont touch me") assert_equal "on my mind\nall day long") - assert_equal "0wn3d", strip_links("0wn3d") - assert_equal "Magic", strip_links("Magic") - assert_equal "FrrFox", strip_links("FrrFox") + assert_equal "0wn3d", strip_links("0wn3d") + assert_equal "Magic", strip_links("Magic") + assert_equal "FrrFox", strip_links("FrrFox") assert_equal "My mind\nall day long", strip_links("My mind\nall day long") assert_equal "all day long", strip_links("<a href='hello'>all day long</a>") end -- cgit v1.2.3 From f2d8d13c6495f2a9b3bbf3b50d869c0e5b25c207 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Mon, 25 Aug 2008 21:44:21 -0500 Subject: Performance: Cache modules that extend the view context for JavaScriptGenerator --- actionpack/lib/action_view/base.rb | 8 ++++++-- actionpack/lib/action_view/helpers/prototype_helper.rb | 4 +--- actionpack/test/template/javascript_helper_test.rb | 5 +++++ actionpack/test/template/prototype_helper_test.rb | 4 ++++ 4 files changed, 16 insertions(+), 5 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index cc89c66a39..e1f35b8105 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -158,6 +158,7 @@ module ActionView #:nodoc: # See the ActionView::Helpers::PrototypeHelper::GeneratorMethods documentation for more details. class Base include ERB::Util + extend ActiveSupport::Memoizable attr_accessor :base_path, :assigns, :template_extension attr_accessor :controller @@ -324,11 +325,14 @@ module ActionView #:nodoc: template end end - - extend ActiveSupport::Memoizable memoize :pick_template private + def extended_by_without_helpers #:nodoc: + extended_by.reject { |mod| mod.name =~ /^ActionView::Helpers/ } + end + memoize :extended_by_without_helpers + # Evaluate the local assigns and pushes them to the view. def evaluate_assigns unless @assigns_added diff --git a/actionpack/lib/action_view/helpers/prototype_helper.rb b/actionpack/lib/action_view/helpers/prototype_helper.rb index 4c3a8311a5..09dbb67c0a 100644 --- a/actionpack/lib/action_view/helpers/prototype_helper.rb +++ b/actionpack/lib/action_view/helpers/prototype_helper.rb @@ -588,9 +588,7 @@ module ActionView private def include_helpers_from_context - @context.extended_by.each do |mod| - extend mod unless mod.name =~ /^ActionView::Helpers/ - end + @context.send(:extended_by_without_helpers).each { |mod| extend mod } extend GeneratorMethods end diff --git a/actionpack/test/template/javascript_helper_test.rb b/actionpack/test/template/javascript_helper_test.rb index d41111127b..2e9cdd3fea 100644 --- a/actionpack/test/template/javascript_helper_test.rb +++ b/actionpack/test/template/javascript_helper_test.rb @@ -108,4 +108,9 @@ class JavaScriptHelperTest < ActionView::TestCase def test_javascript_cdata_section assert_dom_equal "\n//\n", javascript_cdata_section("alert('hello')") end + + private + def extended_by_without_helpers + [] + end end diff --git a/actionpack/test/template/prototype_helper_test.rb b/actionpack/test/template/prototype_helper_test.rb index abc9f930dd..5397ae3688 100644 --- a/actionpack/test/template/prototype_helper_test.rb +++ b/actionpack/test/template/prototype_helper_test.rb @@ -53,6 +53,10 @@ class PrototypeHelperBaseTest < ActionView::TestCase false end + def extended_by_without_helpers + [] + end + def create_generator block = Proc.new { |*args| yield *args if block_given? } JavaScriptGenerator.new self, &block -- cgit v1.2.3 From 172606e21f54fea39af68ede5f55a43deaf3ac68 Mon Sep 17 00:00:00 2001 From: Jeremy Kemper Date: Mon, 25 Aug 2008 21:22:34 -0700 Subject: Harmonize framework require strategy. Don't add self to load path since Rails initializer and RubyGems handle it. --- actionpack/lib/action_controller.rb | 15 ++++++--------- actionpack/lib/action_view.rb | 11 ++++++++++- 2 files changed, 16 insertions(+), 10 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller.rb b/actionpack/lib/action_controller.rb index 3c4a339d50..e58071d4af 100644 --- a/actionpack/lib/action_controller.rb +++ b/actionpack/lib/action_controller.rb @@ -21,16 +21,13 @@ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #++ -$:.unshift(File.dirname(__FILE__)) unless - $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__))) - -unless defined?(ActiveSupport) - begin - $:.unshift "#{File.dirname(__FILE__)}/../../activesupport/lib" +begin + require 'active_support' +rescue LoadError + activesupport_path = "#{File.dirname(__FILE__)}/../../activesupport/lib" + if File.directory?(activesupport_path) + $:.unshift activesupport_path require 'active_support' - rescue LoadError - require 'rubygems' - gem 'activesupport' end end diff --git a/actionpack/lib/action_view.rb b/actionpack/lib/action_view.rb index 3f35303a51..3590ab6d49 100644 --- a/actionpack/lib/action_view.rb +++ b/actionpack/lib/action_view.rb @@ -21,6 +21,15 @@ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. #++ +begin + require 'active_support' +rescue LoadError + activesupport_path = "#{File.dirname(__FILE__)}/../../activesupport/lib" + if File.directory?(activesupport_path) + $:.unshift activesupport_path + require 'active_support' + end +end require 'action_view/template_handlers' require 'action_view/renderable' @@ -35,7 +44,7 @@ require 'action_view/partials' require 'action_view/template_error' I18n.backend.populate do - I18n.load_translations File.dirname(__FILE__) + '/action_view/locale/en-US.yml' + I18n.load_translations "#{File.dirname(__FILE__)}/action_view/locale/en-US.yml" end require 'action_view/helpers' -- cgit v1.2.3 From 229eedfda87a7706dbb5e3e51af8707b3adae375 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Tue, 26 Aug 2008 12:14:21 -0500 Subject: Cache JavaScriptGenerator's helper module set on the template --- actionpack/lib/action_view/base.rb | 5 ----- .../lib/action_view/helpers/prototype_helper.rb | 22 ++++++++++++++++++++-- actionpack/test/template/javascript_helper_test.rb | 5 ----- actionpack/test/template/prototype_helper_test.rb | 4 ---- 4 files changed, 20 insertions(+), 16 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index e1f35b8105..d174c784f3 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -328,11 +328,6 @@ module ActionView #:nodoc: memoize :pick_template private - def extended_by_without_helpers #:nodoc: - extended_by.reject { |mod| mod.name =~ /^ActionView::Helpers/ } - end - memoize :extended_by_without_helpers - # Evaluate the local assigns and pushes them to the view. def evaluate_assigns unless @assigns_added diff --git a/actionpack/lib/action_view/helpers/prototype_helper.rb b/actionpack/lib/action_view/helpers/prototype_helper.rb index 09dbb67c0a..ff83494e94 100644 --- a/actionpack/lib/action_view/helpers/prototype_helper.rb +++ b/actionpack/lib/action_view/helpers/prototype_helper.rb @@ -588,8 +588,26 @@ module ActionView private def include_helpers_from_context - @context.send(:extended_by_without_helpers).each { |mod| extend mod } - extend GeneratorMethods + unless generator_methods_module = @context.instance_variable_get(:@__javascript_generator_methods__) + modules = @context.extended_by - ([ActionView::Helpers] + ActionView::Helpers.included_modules) + + generator_methods_module = Module.new do + modules.each do |mod| + begin + include mod + rescue Exception => e + # HACK: Probably not a good idea to suppress these warnings + # AFAIK exceptions are only raised in while testing with mocha + # because the module does not like to be included into other + # non TestUnit classes + end + end + include GeneratorMethods + end + @context.instance_variable_set(:@__javascript_generator_methods__, generator_methods_module) + end + + extend generator_methods_module end # JavaScriptGenerator generates blocks of JavaScript code that allow you diff --git a/actionpack/test/template/javascript_helper_test.rb b/actionpack/test/template/javascript_helper_test.rb index 2e9cdd3fea..d41111127b 100644 --- a/actionpack/test/template/javascript_helper_test.rb +++ b/actionpack/test/template/javascript_helper_test.rb @@ -108,9 +108,4 @@ class JavaScriptHelperTest < ActionView::TestCase def test_javascript_cdata_section assert_dom_equal "\n//\n", javascript_cdata_section("alert('hello')") end - - private - def extended_by_without_helpers - [] - end end diff --git a/actionpack/test/template/prototype_helper_test.rb b/actionpack/test/template/prototype_helper_test.rb index 5397ae3688..abc9f930dd 100644 --- a/actionpack/test/template/prototype_helper_test.rb +++ b/actionpack/test/template/prototype_helper_test.rb @@ -53,10 +53,6 @@ class PrototypeHelperBaseTest < ActionView::TestCase false end - def extended_by_without_helpers - [] - end - def create_generator block = Proc.new { |*args| yield *args if block_given? } JavaScriptGenerator.new self, &block -- cgit v1.2.3 From 9853134b4fec468962260f0e713d2f87046eb8b3 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Tue, 26 Aug 2008 15:13:28 -0500 Subject: Require missing libraries and check for defined ActionController constant so ActionView can be used standalone --- actionpack/lib/action_controller/mime_type.rb | 2 ++ actionpack/lib/action_view/helpers/sanitize_helper.rb | 11 ++++++++++- actionpack/lib/action_view/helpers/text_helper.rb | 11 ++++++++++- actionpack/lib/action_view/renderable.rb | 2 +- actionpack/lib/action_view/renderable_partial.rb | 6 +++++- actionpack/lib/action_view/template.rb | 2 ++ 6 files changed, 30 insertions(+), 4 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/mime_type.rb b/actionpack/lib/action_controller/mime_type.rb index a7215e6ea3..26edca3b69 100644 --- a/actionpack/lib/action_controller/mime_type.rb +++ b/actionpack/lib/action_controller/mime_type.rb @@ -1,3 +1,5 @@ +require 'set' + module Mime SET = [] EXTENSION_LOOKUP = Hash.new { |h, k| h[k] = Type.new(k) unless k.blank? } diff --git a/actionpack/lib/action_view/helpers/sanitize_helper.rb b/actionpack/lib/action_view/helpers/sanitize_helper.rb index 637caf203b..435ba936e1 100644 --- a/actionpack/lib/action_view/helpers/sanitize_helper.rb +++ b/actionpack/lib/action_view/helpers/sanitize_helper.rb @@ -1,5 +1,14 @@ require 'action_view/helpers/tag_helper' -require 'html/document' + +begin + require 'html/document' +rescue LoadError + html_scanner_path = "#{File.dirname(__FILE__)}/../../action_controller/vendor/html-scanner" + if File.directory?(html_scanner_path) + $:.unshift html_scanner_path + require 'html/document' + end +end module ActionView module Helpers #:nodoc: diff --git a/actionpack/lib/action_view/helpers/text_helper.rb b/actionpack/lib/action_view/helpers/text_helper.rb index f9096d0029..ccd6c54cc8 100644 --- a/actionpack/lib/action_view/helpers/text_helper.rb +++ b/actionpack/lib/action_view/helpers/text_helper.rb @@ -1,5 +1,14 @@ require 'action_view/helpers/tag_helper' -require 'html/document' + +begin + require 'html/document' +rescue LoadError + html_scanner_path = "#{File.dirname(__FILE__)}/../../action_controller/vendor/html-scanner" + if File.directory?(html_scanner_path) + $:.unshift html_scanner_path + require 'html/document' + end +end module ActionView module Helpers #:nodoc: diff --git a/actionpack/lib/action_view/renderable.rb b/actionpack/lib/action_view/renderable.rb index c011f21550..3a79b2b01e 100644 --- a/actionpack/lib/action_view/renderable.rb +++ b/actionpack/lib/action_view/renderable.rb @@ -72,7 +72,7 @@ module ActionView end_src begin - logger = Base.logger + logger = defined? ActionController && Base.logger logger.debug "Compiling template #{render_symbol}" if logger ActionView::Base::CompiledTemplates.module_eval(source, filename, 0) diff --git a/actionpack/lib/action_view/renderable_partial.rb b/actionpack/lib/action_view/renderable_partial.rb index 342850f0f0..5203e57ead 100644 --- a/actionpack/lib/action_view/renderable_partial.rb +++ b/actionpack/lib/action_view/renderable_partial.rb @@ -16,7 +16,11 @@ module ActionView memoize :counter_name def render(view, local_assigns = {}) - ActionController::Base.benchmark("Rendered #{path_without_format_and_extension}", Logger::DEBUG, false) do + if defined? ActionController + ActionController::Base.benchmark("Rendered #{path_without_format_and_extension}", Logger::DEBUG, false) do + super + end + else super end end diff --git a/actionpack/lib/action_view/template.rb b/actionpack/lib/action_view/template.rb index 5dc6708431..64597b3d39 100644 --- a/actionpack/lib/action_view/template.rb +++ b/actionpack/lib/action_view/template.rb @@ -1,3 +1,5 @@ +require 'action_controller/mime_type' + module ActionView #:nodoc: class Template extend TemplateHandlers -- cgit v1.2.3 From cd91a8d3adb70e573ab8d0d733a966db5eff1e1d Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Tue, 26 Aug 2008 15:21:06 -0500 Subject: defined? has no bounds --- actionpack/lib/action_view/renderable.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view/renderable.rb b/actionpack/lib/action_view/renderable.rb index 3a79b2b01e..fa45edd436 100644 --- a/actionpack/lib/action_view/renderable.rb +++ b/actionpack/lib/action_view/renderable.rb @@ -72,7 +72,7 @@ module ActionView end_src begin - logger = defined? ActionController && Base.logger + logger = defined?(ActionController) && Base.logger logger.debug "Compiling template #{render_symbol}" if logger ActionView::Base::CompiledTemplates.module_eval(source, filename, 0) -- cgit v1.2.3 From 6ec07e0737c3099056fc11fe43f4f19dde3770a6 Mon Sep 17 00:00:00 2001 From: Joshua Peek Date: Tue, 26 Aug 2008 16:17:58 -0500 Subject: Store application and other context specific helper modules in ActionView::Base#helpers --- actionpack/lib/action_controller/base.rb | 2 +- actionpack/lib/action_view/base.rb | 14 ++++++++++++++ .../lib/action_view/helpers/prototype_helper.rb | 22 ++-------------------- 3 files changed, 17 insertions(+), 21 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/base.rb b/actionpack/lib/action_controller/base.rb index 91023cd774..55e1d48949 100644 --- a/actionpack/lib/action_controller/base.rb +++ b/actionpack/lib/action_controller/base.rb @@ -1148,7 +1148,7 @@ module ActionController #:nodoc: def initialize_template_class(response) response.template = ActionView::Base.new(self.class.view_paths, {}, self) - response.template.extend self.class.master_helper_module + response.template.helpers.send :include, self.class.master_helper_module response.redirected_to = nil @performed_render = @performed_redirect = false end diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index d174c784f3..c65048bfa0 100644 --- a/actionpack/lib/action_view/base.rb +++ b/actionpack/lib/action_view/base.rb @@ -208,10 +208,24 @@ module ActionView #:nodoc: ActionView::PathSet.new(Array(value)) end + attr_reader :helpers + + class ProxyModule < Module + def initialize(receiver) + @receiver = receiver + end + + def include(*args) + super(*args) + @receiver.extend(*args) + end + end + def initialize(view_paths = [], assigns_for_first_render = {}, controller = nil)#:nodoc: @assigns = assigns_for_first_render @assigns_added = nil @controller = controller + @helpers = ProxyModule.new(self) self.view_paths = view_paths end diff --git a/actionpack/lib/action_view/helpers/prototype_helper.rb b/actionpack/lib/action_view/helpers/prototype_helper.rb index ff83494e94..2ce818cd71 100644 --- a/actionpack/lib/action_view/helpers/prototype_helper.rb +++ b/actionpack/lib/action_view/helpers/prototype_helper.rb @@ -588,26 +588,8 @@ module ActionView private def include_helpers_from_context - unless generator_methods_module = @context.instance_variable_get(:@__javascript_generator_methods__) - modules = @context.extended_by - ([ActionView::Helpers] + ActionView::Helpers.included_modules) - - generator_methods_module = Module.new do - modules.each do |mod| - begin - include mod - rescue Exception => e - # HACK: Probably not a good idea to suppress these warnings - # AFAIK exceptions are only raised in while testing with mocha - # because the module does not like to be included into other - # non TestUnit classes - end - end - include GeneratorMethods - end - @context.instance_variable_set(:@__javascript_generator_methods__, generator_methods_module) - end - - extend generator_methods_module + extend @context.helpers if @context.respond_to?(:helpers) + extend GeneratorMethods end # JavaScriptGenerator generates blocks of JavaScript code that allow you -- cgit v1.2.3 From 0fcd5b5466461e44b6f3b007fa2a2fdf43f55681 Mon Sep 17 00:00:00 2001 From: Marko Seppae Date: Wed, 27 Aug 2008 10:36:00 +0200 Subject: I18n: removed call to #populate from main library files --- actionpack/lib/action_view.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_view.rb b/actionpack/lib/action_view.rb index 3590ab6d49..0ed69f29bf 100644 --- a/actionpack/lib/action_view.rb +++ b/actionpack/lib/action_view.rb @@ -43,9 +43,7 @@ require 'action_view/base' require 'action_view/partials' require 'action_view/template_error' -I18n.backend.populate do - I18n.load_translations "#{File.dirname(__FILE__)}/action_view/locale/en-US.yml" -end +I18n.load_translations "#{File.dirname(__FILE__)}/action_view/locale/en-US.yml" require 'action_view/helpers' -- cgit v1.2.3 From 82778351a8b1036ac4bdc8e72a3f011151fefa31 Mon Sep 17 00:00:00 2001 From: Tim Haines Date: Thu, 28 Aug 2008 12:57:25 +1200 Subject: Add TestUploadFile.content_type= to match Request.UploadedFile [#920 state:resolved] Signed-off-by: Jeremy Kemper --- actionpack/lib/action_controller/test_process.rb | 2 +- actionpack/test/controller/test_test.rb | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/test_process.rb b/actionpack/lib/action_controller/test_process.rb index c6b1470070..a11fa7cd10 100644 --- a/actionpack/lib/action_controller/test_process.rb +++ b/actionpack/lib/action_controller/test_process.rb @@ -331,7 +331,7 @@ module ActionController #:nodoc: attr_reader :original_filename # The content type of the "uploaded" file - attr_reader :content_type + attr_accessor :content_type def initialize(path, content_type = Mime::TEXT, binary = false) raise "#{path} file does not exist" unless File.exist?(path) diff --git a/actionpack/test/controller/test_test.rb b/actionpack/test/controller/test_test.rb index 58d9ca537f..9eff34a542 100644 --- a/actionpack/test/controller/test_test.rb +++ b/actionpack/test/controller/test_test.rb @@ -531,6 +531,11 @@ XML assert_equal content_type, file.content_type assert_equal file.path, file.local_path assert_equal expected, file.read + + new_content_type = "new content_type" + file.content_type = new_content_type + assert_equal new_content_type, file.content_type + end def test_test_uploaded_file_with_binary -- cgit v1.2.3 From e42a235dd18a39ccc83382365088de96f24fa236 Mon Sep 17 00:00:00 2001 From: "Michael S. Klishin" Date: Tue, 1 Jul 2008 11:52:20 +0300 Subject: Request#remote_ip handles the uncommon case that REMOTE_ADDR is a comma-separated list. [#523 state:resolved] Signed-off-by: Jeremy Kemper --- actionpack/lib/action_controller/request.rb | 8 +++++--- actionpack/test/controller/request_test.rb | 3 +++ 2 files changed, 8 insertions(+), 3 deletions(-) mode change 100644 => 100755 actionpack/lib/action_controller/request.rb (limited to 'actionpack') diff --git a/actionpack/lib/action_controller/request.rb b/actionpack/lib/action_controller/request.rb old mode 100644 new mode 100755 index 364e6201cc..d793ade702 --- a/actionpack/lib/action_controller/request.rb +++ b/actionpack/lib/action_controller/request.rb @@ -197,10 +197,12 @@ module ActionController # delimited list in the case of multiple chained proxies; the last # address which is not trusted is the originating IP. def remote_ip - if TRUSTED_PROXIES !~ @env['REMOTE_ADDR'] - return @env['REMOTE_ADDR'] - end + remote_addr_list = @env['REMOTE_ADDR'] && @env['REMOTE_ADDR'].split(',').collect(&:strip) + unless remote_addr_list.blank? + not_trusted_addrs = remote_addr_list.reject {|addr| addr =~ 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' diff --git a/actionpack/test/controller/request_test.rb b/actionpack/test/controller/request_test.rb index 045dab4141..e79a0ea76b 100644 --- a/actionpack/test/controller/request_test.rb +++ b/actionpack/test/controller/request_test.rb @@ -17,6 +17,9 @@ class RequestTest < Test::Unit::TestCase @request.remote_addr = '1.2.3.4' assert_equal '1.2.3.4', @request.remote_ip(true) + @request.remote_addr = '1.2.3.4,3.4.5.6' + assert_equal '1.2.3.4', @request.remote_ip(true) + @request.env['HTTP_CLIENT_IP'] = '2.3.4.5' assert_equal '1.2.3.4', @request.remote_ip(true) -- cgit v1.2.3 From f277e1d8fddfa417104c6fe095c15559f0c8713d Mon Sep 17 00:00:00 2001 From: Ken Collins Date: Sat, 14 Jun 2008 14:06:27 -0400 Subject: Added TextHelper#current_cycle to return the current cycle for better design options. [#417 state:resolved] Signed-off-by: Jeremy Kemper --- actionpack/CHANGELOG | 2 ++ actionpack/lib/action_view/helpers/text_helper.rb | 43 +++++++++++++++++++++-- actionpack/test/template/text_helper_test.rb | 34 ++++++++++++++++++ 3 files changed, 76 insertions(+), 3 deletions(-) (limited to 'actionpack') diff --git a/actionpack/CHANGELOG b/actionpack/CHANGELOG index be490093ac..f6942b43f1 100644 --- a/actionpack/CHANGELOG +++ b/actionpack/CHANGELOG @@ -1,5 +1,7 @@ *Edge* +* Introduce current_cycle helper method to return the current value without bumping the cycle. #417 [Ken Collins] + * Allow polymorphic_url helper to take url options. #880 [Tarmo Tänav] * Switched integration test runner to use Rack processor instead of CGI [Josh Peek] diff --git a/actionpack/lib/action_view/helpers/text_helper.rb b/actionpack/lib/action_view/helpers/text_helper.rb index ccd6c54cc8..a5d43b90f4 100644 --- a/actionpack/lib/action_view/helpers/text_helper.rb +++ b/actionpack/lib/action_view/helpers/text_helper.rb @@ -448,8 +448,10 @@ module ActionView # array every time it is called. This can be used for example, to alternate # classes for table rows. You can use named cycles to allow nesting in loops. # Passing a Hash as the last parameter with a :name key will create a - # named cycle. You can manually reset a cycle by calling reset_cycle and passing the - # name of the cycle. + # named cycle. The default name for a cycle without a +:name+ key is + # "default". You can manually reset a cycle by calling reset_cycle + # and passing the name of the cycle. The current cycle string can be obtained + # anytime using the current_cycle method. # # ==== Examples # # Alternate CSS classes for even and odd numbers... @@ -496,6 +498,23 @@ module ActionView return cycle.to_s end + # Returns the current cycle string after a cycle has been started. Useful + # for complex table highlighing or any other design need which requires + # the current cycle string in more than one place. + # + # ==== Example + # # Alternate background colors + # @items = [1,2,3,4] + # <% @items.each do |item| %> + #
"> + # "colors")) end + def test_current_cycle_with_default_name + cycle("even","odd") + assert_equal "even", current_cycle + cycle("even","odd") + assert_equal "odd", current_cycle + cycle("even","odd") + assert_equal "even", current_cycle + end + + def test_current_cycle_with_named_cycles + cycle("red", "blue", :name => "colors") + assert_equal "red", current_cycle("colors") + cycle("red", "blue", :name => "colors") + assert_equal "blue", current_cycle("colors") + cycle("red", "blue", :name => "colors") + assert_equal "red", current_cycle("colors") + end + + def test_current_cycle_safe_call + assert_nothing_raised { current_cycle } + assert_nothing_raised { current_cycle("colors") } + end + + def test_current_cycle_with_more_than_two_names + cycle(1,2,3) + assert_equal "1", current_cycle + cycle(1,2,3) + assert_equal "2", current_cycle + cycle(1,2,3) + assert_equal "3", current_cycle + cycle(1,2,3) + assert_equal "1", current_cycle + end + def test_default_named_cycle assert_equal("1", cycle(1, 2, 3)) assert_equal("2", cycle(1, 2, 3, :name => "default")) -- cgit v1.2.3