actionpack 2.2.3 → 2.3.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of actionpack might be problematic. Click here for more details.
- data/CHANGELOG +433 -375
- data/MIT-LICENSE +1 -1
- data/README +21 -75
- data/Rakefile +1 -1
- data/lib/action_controller.rb +80 -43
- data/lib/action_controller/assertions/model_assertions.rb +1 -0
- data/lib/action_controller/assertions/response_assertions.rb +43 -16
- data/lib/action_controller/assertions/routing_assertions.rb +1 -1
- data/lib/action_controller/assertions/selector_assertions.rb +17 -12
- data/lib/action_controller/assertions/tag_assertions.rb +1 -4
- data/lib/action_controller/base.rb +153 -82
- data/lib/action_controller/benchmarking.rb +9 -9
- data/lib/action_controller/caching.rb +9 -11
- data/lib/action_controller/caching/actions.rb +11 -18
- data/lib/action_controller/caching/fragments.rb +28 -20
- data/lib/action_controller/caching/pages.rb +13 -15
- data/lib/action_controller/caching/sweeping.rb +2 -2
- data/lib/action_controller/cgi_ext.rb +0 -1
- data/lib/action_controller/cgi_ext/cookie.rb +2 -0
- data/lib/action_controller/cgi_process.rb +54 -162
- data/lib/action_controller/cookies.rb +13 -25
- data/lib/action_controller/dispatcher.rb +43 -122
- data/lib/action_controller/failsafe.rb +52 -0
- data/lib/action_controller/flash.rb +38 -47
- data/lib/action_controller/helpers.rb +13 -9
- data/lib/action_controller/http_authentication.rb +203 -23
- data/lib/action_controller/integration.rb +126 -70
- data/lib/action_controller/layout.rb +36 -39
- data/lib/action_controller/middleware_stack.rb +119 -0
- data/lib/action_controller/middlewares.rb +13 -0
- data/lib/action_controller/mime_responds.rb +19 -4
- data/lib/action_controller/mime_type.rb +8 -0
- data/lib/action_controller/params_parser.rb +71 -0
- data/lib/action_controller/performance_test.rb +0 -1
- data/lib/action_controller/polymorphic_routes.rb +36 -30
- data/lib/action_controller/reloader.rb +14 -0
- data/lib/action_controller/request.rb +107 -499
- data/lib/action_controller/request_forgery_protection.rb +7 -39
- data/lib/action_controller/rescue.rb +55 -35
- data/lib/action_controller/resources.rb +34 -31
- data/lib/action_controller/response.rb +99 -57
- data/lib/action_controller/rewindable_input.rb +28 -0
- data/lib/action_controller/routing.rb +7 -7
- data/lib/action_controller/routing/builder.rb +4 -1
- data/lib/action_controller/routing/optimisations.rb +1 -1
- data/lib/action_controller/routing/recognition_optimisation.rb +1 -2
- data/lib/action_controller/routing/route.rb +15 -5
- data/lib/action_controller/routing/route_set.rb +82 -35
- data/lib/action_controller/routing/segments.rb +35 -0
- data/lib/action_controller/session/abstract_store.rb +181 -0
- data/lib/action_controller/session/cookie_store.rb +197 -175
- data/lib/action_controller/session/mem_cache_store.rb +36 -83
- data/lib/action_controller/session_management.rb +26 -134
- data/lib/action_controller/streaming.rb +24 -7
- data/lib/action_controller/templates/rescues/diagnostics.erb +2 -2
- data/lib/action_controller/templates/rescues/template_error.erb +2 -2
- data/lib/action_controller/test_case.rb +87 -30
- data/lib/action_controller/test_process.rb +145 -104
- data/lib/action_controller/uploaded_file.rb +44 -0
- data/lib/action_controller/url_rewriter.rb +3 -6
- data/lib/action_controller/vendor/html-scanner.rb +16 -0
- data/lib/action_controller/vendor/html-scanner/html/selector.rb +1 -1
- data/lib/action_controller/vendor/rack-1.0/rack.rb +89 -0
- data/lib/action_controller/vendor/rack-1.0/rack/adapter/camping.rb +22 -0
- data/lib/action_controller/vendor/rack-1.0/rack/auth/abstract/handler.rb +37 -0
- data/lib/action_controller/vendor/rack-1.0/rack/auth/abstract/request.rb +37 -0
- data/lib/action_controller/vendor/rack-1.0/rack/auth/basic.rb +58 -0
- data/lib/action_controller/vendor/rack-1.0/rack/auth/digest/md5.rb +124 -0
- data/lib/action_controller/vendor/rack-1.0/rack/auth/digest/nonce.rb +51 -0
- data/lib/action_controller/vendor/rack-1.0/rack/auth/digest/params.rb +55 -0
- data/lib/action_controller/vendor/rack-1.0/rack/auth/digest/request.rb +40 -0
- data/lib/action_controller/vendor/rack-1.0/rack/auth/openid.rb +480 -0
- data/lib/action_controller/vendor/rack-1.0/rack/builder.rb +63 -0
- data/lib/action_controller/vendor/rack-1.0/rack/cascade.rb +36 -0
- data/lib/action_controller/vendor/rack-1.0/rack/chunked.rb +49 -0
- data/lib/action_controller/vendor/rack-1.0/rack/commonlogger.rb +61 -0
- data/lib/action_controller/vendor/rack-1.0/rack/conditionalget.rb +45 -0
- data/lib/action_controller/vendor/rack-1.0/rack/content_length.rb +29 -0
- data/lib/action_controller/vendor/rack-1.0/rack/content_type.rb +23 -0
- data/lib/action_controller/vendor/rack-1.0/rack/deflater.rb +85 -0
- data/lib/action_controller/vendor/rack-1.0/rack/directory.rb +153 -0
- data/lib/action_controller/vendor/rack-1.0/rack/file.rb +88 -0
- data/lib/action_controller/vendor/rack-1.0/rack/handler.rb +48 -0
- data/lib/action_controller/vendor/rack-1.0/rack/handler/cgi.rb +61 -0
- data/lib/action_controller/vendor/rack-1.0/rack/handler/evented_mongrel.rb +8 -0
- data/lib/action_controller/vendor/rack-1.0/rack/handler/fastcgi.rb +89 -0
- data/lib/action_controller/vendor/rack-1.0/rack/handler/lsws.rb +55 -0
- data/lib/action_controller/vendor/rack-1.0/rack/handler/mongrel.rb +84 -0
- data/lib/action_controller/vendor/rack-1.0/rack/handler/scgi.rb +59 -0
- data/lib/action_controller/vendor/rack-1.0/rack/handler/swiftiplied_mongrel.rb +8 -0
- data/lib/action_controller/vendor/rack-1.0/rack/handler/thin.rb +18 -0
- data/lib/action_controller/vendor/rack-1.0/rack/handler/webrick.rb +67 -0
- data/lib/action_controller/vendor/rack-1.0/rack/head.rb +19 -0
- data/lib/action_controller/vendor/rack-1.0/rack/lint.rb +462 -0
- data/lib/action_controller/vendor/rack-1.0/rack/lobster.rb +65 -0
- data/lib/action_controller/vendor/rack-1.0/rack/lock.rb +16 -0
- data/lib/action_controller/vendor/rack-1.0/rack/methodoverride.rb +27 -0
- data/lib/action_controller/vendor/rack-1.0/rack/mime.rb +204 -0
- data/lib/action_controller/vendor/rack-1.0/rack/mock.rb +160 -0
- data/lib/action_controller/vendor/rack-1.0/rack/recursive.rb +57 -0
- data/lib/action_controller/vendor/rack-1.0/rack/reloader.rb +64 -0
- data/lib/action_controller/vendor/rack-1.0/rack/request.rb +241 -0
- data/lib/action_controller/vendor/rack-1.0/rack/response.rb +179 -0
- data/lib/action_controller/vendor/rack-1.0/rack/session/abstract/id.rb +142 -0
- data/lib/action_controller/vendor/rack-1.0/rack/session/cookie.rb +91 -0
- data/lib/action_controller/vendor/rack-1.0/rack/session/memcache.rb +109 -0
- data/lib/action_controller/vendor/rack-1.0/rack/session/pool.rb +100 -0
- data/lib/action_controller/vendor/rack-1.0/rack/showexceptions.rb +349 -0
- data/lib/action_controller/vendor/rack-1.0/rack/showstatus.rb +106 -0
- data/lib/action_controller/vendor/rack-1.0/rack/static.rb +38 -0
- data/lib/action_controller/vendor/rack-1.0/rack/urlmap.rb +55 -0
- data/lib/action_controller/vendor/rack-1.0/rack/utils.rb +392 -0
- data/lib/action_controller/verification.rb +1 -1
- data/lib/action_pack.rb +1 -1
- data/lib/action_pack/version.rb +2 -2
- data/lib/action_view.rb +22 -17
- data/lib/action_view/base.rb +53 -79
- data/lib/action_view/erb/util.rb +38 -0
- data/lib/action_view/helpers.rb +24 -5
- data/lib/action_view/helpers/active_record_helper.rb +2 -2
- data/lib/action_view/helpers/asset_tag_helper.rb +81 -50
- data/lib/action_view/helpers/atom_feed_helper.rb +1 -1
- data/lib/action_view/helpers/benchmark_helper.rb +26 -5
- data/lib/action_view/helpers/date_helper.rb +82 -7
- data/lib/action_view/helpers/form_helper.rb +295 -64
- data/lib/action_view/helpers/form_options_helper.rb +160 -18
- data/lib/action_view/helpers/form_tag_helper.rb +2 -2
- data/lib/action_view/helpers/number_helper.rb +31 -18
- data/lib/action_view/helpers/prototype_helper.rb +2 -12
- data/lib/action_view/helpers/sanitize_helper.rb +0 -10
- data/lib/action_view/helpers/scriptaculous_helper.rb +1 -0
- data/lib/action_view/helpers/tag_helper.rb +3 -4
- data/lib/action_view/helpers/text_helper.rb +99 -122
- data/lib/action_view/helpers/translation_helper.rb +19 -1
- data/lib/action_view/helpers/url_helper.rb +25 -2
- data/lib/action_view/inline_template.rb +1 -1
- data/lib/action_view/locale/en.yml +19 -1
- data/lib/action_view/partials.rb +46 -9
- data/lib/action_view/paths.rb +28 -84
- data/lib/action_view/reloadable_template.rb +117 -0
- data/lib/action_view/renderable.rb +28 -35
- data/lib/action_view/renderable_partial.rb +3 -4
- data/lib/action_view/template.rb +172 -31
- data/lib/action_view/template_error.rb +8 -9
- data/lib/action_view/template_handler.rb +1 -1
- data/lib/action_view/template_handlers.rb +9 -6
- data/lib/action_view/template_handlers/erb.rb +2 -39
- data/lib/action_view/template_handlers/rjs.rb +1 -0
- data/lib/action_view/test_case.rb +27 -1
- data/test/abstract_unit.rb +23 -17
- data/test/active_record_unit.rb +5 -4
- data/test/activerecord/active_record_store_test.rb +139 -106
- data/test/activerecord/render_partial_with_record_identification_test.rb +5 -21
- data/test/controller/action_pack_assertions_test.rb +25 -23
- data/test/controller/addresses_render_test.rb +3 -6
- data/test/controller/assert_select_test.rb +83 -70
- data/test/controller/base_test.rb +11 -13
- data/test/controller/benchmark_test.rb +3 -3
- data/test/controller/caching_test.rb +34 -24
- data/test/controller/capture_test.rb +3 -6
- data/test/controller/content_type_test.rb +3 -6
- data/test/controller/cookie_test.rb +31 -66
- data/test/controller/deprecation/deprecated_base_methods_test.rb +9 -11
- data/test/controller/dispatcher_test.rb +23 -28
- data/test/controller/fake_models.rb +8 -0
- data/test/controller/filters_test.rb +6 -2
- data/test/controller/flash_test.rb +2 -6
- data/test/controller/helper_test.rb +15 -1
- data/test/controller/html-scanner/document_test.rb +1 -1
- data/test/controller/html-scanner/sanitizer_test.rb +1 -1
- data/test/controller/http_basic_authentication_test.rb +88 -0
- data/test/controller/http_digest_authentication_test.rb +178 -0
- data/test/controller/integration_test.rb +56 -52
- data/test/controller/layout_test.rb +46 -44
- data/test/controller/middleware_stack_test.rb +90 -0
- data/test/controller/mime_responds_test.rb +7 -11
- data/test/controller/mime_type_test.rb +9 -0
- data/test/controller/polymorphic_routes_test.rb +235 -151
- data/test/controller/rack_test.rb +52 -81
- data/test/controller/redirect_test.rb +6 -14
- data/test/controller/render_test.rb +273 -60
- data/test/controller/request/json_params_parsing_test.rb +45 -0
- data/test/controller/request/multipart_params_parsing_test.rb +223 -0
- data/test/controller/request/query_string_parsing_test.rb +120 -0
- data/test/controller/request/url_encoded_params_parsing_test.rb +184 -0
- data/test/controller/request/xml_params_parsing_test.rb +88 -0
- data/test/controller/request_forgery_protection_test.rb +17 -98
- data/test/controller/request_test.rb +45 -530
- data/test/controller/rescue_test.rb +45 -22
- data/test/controller/resources_test.rb +112 -37
- data/test/controller/routing_test.rb +1442 -1384
- data/test/controller/selector_test.rb +3 -3
- data/test/controller/send_file_test.rb +30 -3
- data/test/controller/session/cookie_store_test.rb +169 -240
- data/test/controller/session/mem_cache_store_test.rb +94 -148
- data/test/controller/session/test_session_test.rb +58 -0
- data/test/controller/test_test.rb +32 -13
- data/test/controller/url_rewriter_test.rb +54 -4
- data/test/controller/verification_test.rb +1 -1
- data/test/controller/view_paths_test.rb +15 -15
- data/test/controller/webservice_test.rb +178 -147
- data/test/fixtures/alternate_helpers/foo_helper.rb +3 -0
- data/test/fixtures/layout_tests/alt/layouts/alt.rhtml +0 -0
- data/test/fixtures/layouts/default_html.html.erb +1 -0
- data/test/fixtures/layouts/xhr.html.erb +2 -0
- data/test/fixtures/multipart/empty +10 -0
- data/test/fixtures/multipart/hello.txt +1 -0
- data/test/fixtures/multipart/none +9 -0
- data/test/fixtures/public/500.da.html +1 -0
- data/test/fixtures/quiz/questions/_question.html.erb +1 -0
- data/test/fixtures/replies.yml +1 -1
- data/test/fixtures/test/_one.html.erb +1 -0
- data/test/fixtures/test/_two.html.erb +1 -0
- data/test/fixtures/test/dont_pick_me +1 -0
- data/test/fixtures/test/hello.builder +1 -1
- data/test/fixtures/test/hello_world.da.html.erb +1 -0
- data/test/fixtures/test/hello_world.erb~ +1 -0
- data/test/fixtures/test/hello_world.pt-BR.html.erb +1 -0
- data/test/fixtures/test/malformed/malformed.en.html.erb~ +1 -0
- data/test/fixtures/test/malformed/malformed.erb~ +1 -0
- data/test/fixtures/test/malformed/malformed.html.erb~ +1 -0
- data/test/fixtures/test/render_explicit_html_template.js.rjs +1 -0
- data/test/fixtures/test/render_implicit_html_template.js.rjs +1 -0
- data/test/fixtures/test/render_implicit_html_template_from_xhr_request.da.html.erb +1 -0
- data/test/fixtures/test/render_implicit_html_template_from_xhr_request.html.erb +1 -0
- data/test/fixtures/test/render_implicit_js_template_without_layout.js.erb +1 -0
- data/test/fixtures/test/utf8.html.erb +2 -0
- data/test/template/active_record_helper_i18n_test.rb +31 -33
- data/test/template/active_record_helper_test.rb +34 -0
- data/test/template/asset_tag_helper_test.rb +52 -14
- data/test/template/atom_feed_helper_test.rb +3 -5
- data/test/template/benchmark_helper_test.rb +50 -24
- data/test/template/compiled_templates_test.rb +177 -33
- data/test/template/date_helper_i18n_test.rb +88 -81
- data/test/template/date_helper_test.rb +427 -43
- data/test/template/form_helper_test.rb +243 -44
- data/test/template/form_options_helper_test.rb +631 -565
- data/test/template/form_tag_helper_test.rb +9 -2
- data/test/template/javascript_helper_test.rb +0 -5
- data/test/template/number_helper_i18n_test.rb +60 -48
- data/test/template/number_helper_test.rb +1 -0
- data/test/template/render_test.rb +117 -35
- data/test/template/test_test.rb +4 -6
- data/test/template/text_helper_test.rb +129 -50
- data/test/template/translation_helper_test.rb +23 -19
- data/test/template/url_helper_test.rb +35 -2
- data/test/view/test_case_test.rb +8 -0
- metadata +197 -23
- data/lib/action_controller/assertions.rb +0 -69
- data/lib/action_controller/caching/sql_cache.rb +0 -18
- data/lib/action_controller/cgi_ext/session.rb +0 -53
- data/lib/action_controller/components.rb +0 -169
- data/lib/action_controller/rack_process.rb +0 -297
- data/lib/action_controller/request_profiler.rb +0 -169
- data/lib/action_controller/session/active_record_store.rb +0 -340
- data/lib/action_controller/session/drb_server.rb +0 -32
- data/lib/action_controller/session/drb_store.rb +0 -35
- data/test/controller/cgi_test.rb +0 -269
- data/test/controller/components_test.rb +0 -156
- data/test/controller/http_authentication_test.rb +0 -54
- data/test/controller/integration_upload_test.rb +0 -43
- data/test/controller/session_fixation_test.rb +0 -89
- data/test/controller/session_management_test.rb +0 -178
- data/test/fixtures/test/hello_world.js +0 -1
@@ -90,7 +90,7 @@ module ActionController #:nodoc:
|
|
90
90
|
def verify_action(options) #:nodoc:
|
91
91
|
if prereqs_invalid?(options)
|
92
92
|
flash.update(options[:add_flash]) if options[:add_flash]
|
93
|
-
response.headers.
|
93
|
+
response.headers.merge!(options[:add_headers]) if options[:add_headers]
|
94
94
|
apply_remaining_actions(options) unless performed?
|
95
95
|
end
|
96
96
|
end
|
data/lib/action_pack.rb
CHANGED
data/lib/action_pack/version.rb
CHANGED
data/lib/action_view.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
#--
|
2
|
-
# Copyright (c) 2004-
|
2
|
+
# Copyright (c) 2004-2009 David Heinemeier Hansson
|
3
3
|
#
|
4
4
|
# Permission is hereby granted, free of charge, to any person obtaining
|
5
5
|
# a copy of this software and associated documentation files (the
|
@@ -31,23 +31,28 @@ rescue LoadError
|
|
31
31
|
end
|
32
32
|
end
|
33
33
|
|
34
|
-
|
35
|
-
|
36
|
-
|
34
|
+
module ActionView
|
35
|
+
def self.load_all!
|
36
|
+
[Base, InlineTemplate, TemplateError]
|
37
|
+
end
|
37
38
|
|
38
|
-
|
39
|
-
|
40
|
-
|
39
|
+
autoload :Base, 'action_view/base'
|
40
|
+
autoload :Helpers, 'action_view/helpers'
|
41
|
+
autoload :InlineTemplate, 'action_view/inline_template'
|
42
|
+
autoload :Partials, 'action_view/partials'
|
43
|
+
autoload :PathSet, 'action_view/paths'
|
44
|
+
autoload :Renderable, 'action_view/renderable'
|
45
|
+
autoload :RenderablePartial, 'action_view/renderable_partial'
|
46
|
+
autoload :Template, 'action_view/template'
|
47
|
+
autoload :ReloadableTemplate, 'action_view/reloadable_template'
|
48
|
+
autoload :TemplateError, 'action_view/template_error'
|
49
|
+
autoload :TemplateHandler, 'action_view/template_handler'
|
50
|
+
autoload :TemplateHandlers, 'action_view/template_handlers'
|
51
|
+
autoload :Helpers, 'action_view/helpers'
|
52
|
+
end
|
41
53
|
|
42
|
-
|
43
|
-
|
44
|
-
|
54
|
+
class ERB
|
55
|
+
autoload :Util, 'action_view/erb/util'
|
56
|
+
end
|
45
57
|
|
46
58
|
I18n.load_path << "#{File.dirname(__FILE__)}/action_view/locale/en.yml"
|
47
|
-
|
48
|
-
require 'action_view/helpers'
|
49
|
-
|
50
|
-
ActionView::Base.class_eval do
|
51
|
-
include ActionView::Partials
|
52
|
-
include ActionView::Helpers
|
53
|
-
end
|
data/lib/action_view/base.rb
CHANGED
@@ -3,9 +3,12 @@ module ActionView #:nodoc:
|
|
3
3
|
end
|
4
4
|
|
5
5
|
class MissingTemplate < ActionViewError #:nodoc:
|
6
|
+
attr_reader :path
|
7
|
+
|
6
8
|
def initialize(paths, path, template_format = nil)
|
9
|
+
@path = path
|
7
10
|
full_template_path = path.include?('.') ? path : "#{path}.erb"
|
8
|
-
display_paths = paths.join(
|
11
|
+
display_paths = paths.compact.join(":")
|
9
12
|
template_type = (path =~ /layouts/i) ? 'layout' : 'template'
|
10
13
|
super("Missing #{template_type} #{full_template_path} in view path #{display_paths}")
|
11
14
|
end
|
@@ -157,7 +160,7 @@ module ActionView #:nodoc:
|
|
157
160
|
#
|
158
161
|
# See the ActionView::Helpers::PrototypeHelper::GeneratorMethods documentation for more details.
|
159
162
|
class Base
|
160
|
-
include ERB::Util
|
163
|
+
include Helpers, Partials, ::ERB::Util
|
161
164
|
extend ActiveSupport::Memoizable
|
162
165
|
|
163
166
|
attr_accessor :base_path, :assigns, :template_extension
|
@@ -172,25 +175,21 @@ module ActionView #:nodoc:
|
|
172
175
|
delegate :logger, :to => 'ActionController::Base'
|
173
176
|
end
|
174
177
|
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
# Don't render layouts for templates with the given extensions.
|
179
|
-
def self.exempt_from_layout(*extensions)
|
180
|
-
regexps = extensions.collect do |extension|
|
181
|
-
extension.is_a?(Regexp) ? extension : /\.#{Regexp.escape(extension.to_s)}$/
|
182
|
-
end
|
183
|
-
@@exempt_from_layout.merge(regexps)
|
184
|
-
end
|
185
|
-
|
178
|
+
@@debug_rjs = false
|
179
|
+
##
|
180
|
+
# :singleton-method:
|
186
181
|
# Specify whether RJS responses should be wrapped in a try/catch block
|
187
182
|
# that alert()s the caught exception (and then re-raises it).
|
188
|
-
@@debug_rjs = false
|
189
183
|
cattr_accessor :debug_rjs
|
190
184
|
|
191
|
-
#
|
192
|
-
|
193
|
-
|
185
|
+
# Specify whether templates should be cached. Otherwise the file we be read everytime it is accessed.
|
186
|
+
# Automatically reloading templates are not thread safe and should only be used in development mode.
|
187
|
+
@@cache_template_loading = nil
|
188
|
+
cattr_accessor :cache_template_loading
|
189
|
+
|
190
|
+
def self.cache_template_loading?
|
191
|
+
ActionController::Base.allow_concurrency || (cache_template_loading.nil? ? !ActiveSupport::Dependencies.load? : cache_template_loading)
|
192
|
+
end
|
194
193
|
|
195
194
|
attr_internal :request
|
196
195
|
|
@@ -222,38 +221,43 @@ module ActionView #:nodoc:
|
|
222
221
|
def initialize(view_paths = [], assigns_for_first_render = {}, controller = nil)#:nodoc:
|
223
222
|
@assigns = assigns_for_first_render
|
224
223
|
@assigns_added = nil
|
225
|
-
@_render_stack = []
|
226
224
|
@controller = controller
|
227
225
|
@helpers = ProxyModule.new(self)
|
228
226
|
self.view_paths = view_paths
|
227
|
+
|
228
|
+
@_first_render = nil
|
229
|
+
@_current_render = nil
|
229
230
|
end
|
230
231
|
|
231
232
|
attr_reader :view_paths
|
232
233
|
|
233
234
|
def view_paths=(paths)
|
234
235
|
@view_paths = self.class.process_view_paths(paths)
|
236
|
+
# we might be using ReloadableTemplates, so we need to let them know this a new request
|
237
|
+
@view_paths.load!
|
235
238
|
end
|
236
239
|
|
237
|
-
#
|
238
|
-
#
|
240
|
+
# Returns the result of a render that's dictated by the options hash. The primary options are:
|
241
|
+
#
|
242
|
+
# * <tt>:partial</tt> - See ActionView::Partials.
|
243
|
+
# * <tt>:update</tt> - Calls update_page with the block given.
|
244
|
+
# * <tt>:file</tt> - Renders an explicit template file (this used to be the old default), add :locals to pass in those.
|
245
|
+
# * <tt>:inline</tt> - Renders an inline template similar to how it's done in the controller.
|
246
|
+
# * <tt>:text</tt> - Renders the text passed in out.
|
247
|
+
#
|
248
|
+
# If no options hash is passed or :update specified, the default is to render a partial and use the second parameter
|
249
|
+
# as the locals hash.
|
239
250
|
def render(options = {}, local_assigns = {}, &block) #:nodoc:
|
240
251
|
local_assigns ||= {}
|
241
252
|
|
242
|
-
|
243
|
-
|
244
|
-
"Calling render with a string will render a partial from Rails 2.3. " +
|
245
|
-
"Change this call to render(:file => '#{options}', :locals => locals_hash)."
|
246
|
-
)
|
247
|
-
|
248
|
-
render(:file => options, :locals => local_assigns)
|
249
|
-
elsif options == :update
|
250
|
-
update_page(&block)
|
251
|
-
elsif options.is_a?(Hash)
|
253
|
+
case options
|
254
|
+
when Hash
|
252
255
|
options = options.reverse_merge(:locals => {})
|
253
256
|
if options[:layout]
|
254
257
|
_render_with_layout(options, local_assigns, &block)
|
255
258
|
elsif options[:file]
|
256
|
-
|
259
|
+
template = self.view_paths.find_template(options[:file], template_format)
|
260
|
+
template.render_template(self, options[:locals])
|
257
261
|
elsif options[:partial]
|
258
262
|
render_partial(options)
|
259
263
|
elsif options[:inline]
|
@@ -261,6 +265,10 @@ module ActionView #:nodoc:
|
|
261
265
|
elsif options[:text]
|
262
266
|
options[:text]
|
263
267
|
end
|
268
|
+
when :update
|
269
|
+
update_page(&block)
|
270
|
+
else
|
271
|
+
render_partial(:partial => options, :locals => local_assigns)
|
264
272
|
end
|
265
273
|
end
|
266
274
|
|
@@ -271,7 +279,7 @@ module ActionView #:nodoc:
|
|
271
279
|
if defined? @template_format
|
272
280
|
@template_format
|
273
281
|
elsif controller && controller.respond_to?(:request)
|
274
|
-
@template_format = controller.request.template_format
|
282
|
+
@template_format = controller.request.template_format.to_sym
|
275
283
|
else
|
276
284
|
@template_format = :html
|
277
285
|
end
|
@@ -280,7 +288,19 @@ module ActionView #:nodoc:
|
|
280
288
|
# Access the current template being rendered.
|
281
289
|
# Returns a ActionView::Template object.
|
282
290
|
def template
|
283
|
-
@
|
291
|
+
@_current_render
|
292
|
+
end
|
293
|
+
|
294
|
+
def template=(template) #:nodoc:
|
295
|
+
@_first_render ||= template
|
296
|
+
@_current_render = template
|
297
|
+
end
|
298
|
+
|
299
|
+
def with_template(current_template)
|
300
|
+
last_template, self.template = template, current_template
|
301
|
+
yield
|
302
|
+
ensure
|
303
|
+
self.template = last_template
|
284
304
|
end
|
285
305
|
|
286
306
|
private
|
@@ -307,52 +327,6 @@ module ActionView #:nodoc:
|
|
307
327
|
end
|
308
328
|
end
|
309
329
|
|
310
|
-
def _pick_template(template_path)
|
311
|
-
return template_path if template_path.respond_to?(:render)
|
312
|
-
|
313
|
-
path = template_path.sub(/^\//, '')
|
314
|
-
if m = path.match(/(.*)\.(\w+)$/)
|
315
|
-
template_file_name, template_file_extension = m[1], m[2]
|
316
|
-
else
|
317
|
-
template_file_name = path
|
318
|
-
end
|
319
|
-
|
320
|
-
# OPTIMIZE: Checks to lookup template in view path
|
321
|
-
if template = self.view_paths["#{template_file_name}.#{template_format}"]
|
322
|
-
template
|
323
|
-
elsif template_file_extension && template = self.view_paths["#{template_file_name}.#{template_file_extension}"]
|
324
|
-
template
|
325
|
-
elsif template = self.view_paths[template_file_name]
|
326
|
-
template
|
327
|
-
elsif (first_render = @_render_stack.first) && first_render.respond_to?(:format_and_extension) &&
|
328
|
-
(template = self.view_paths["#{template_file_name}.#{first_render.format_and_extension}"])
|
329
|
-
template
|
330
|
-
elsif template_format == :js && template = self.view_paths["#{template_file_name}.html"]
|
331
|
-
@template_format = :html
|
332
|
-
template
|
333
|
-
else
|
334
|
-
template = Template.new(template_path, view_paths)
|
335
|
-
|
336
|
-
if self.class.warn_cache_misses && logger
|
337
|
-
logger.debug "[PERFORMANCE] Rendering a template that was " +
|
338
|
-
"not found in view path. Templates outside the view path are " +
|
339
|
-
"not cached and result in expensive disk operations. Move this " +
|
340
|
-
"file into #{view_paths.join(':')} or add the folder to your " +
|
341
|
-
"view path list"
|
342
|
-
end
|
343
|
-
|
344
|
-
template
|
345
|
-
end
|
346
|
-
end
|
347
|
-
memoize :_pick_template
|
348
|
-
|
349
|
-
def _exempt_from_layout?(template_path) #:nodoc:
|
350
|
-
template = _pick_template(template_path).to_s
|
351
|
-
@@exempt_from_layout.any? { |ext| template =~ ext }
|
352
|
-
rescue ActionView::MissingTemplate
|
353
|
-
return false
|
354
|
-
end
|
355
|
-
|
356
330
|
def _render_with_layout(options, local_assigns, &block) #:nodoc:
|
357
331
|
partial_layout = options.delete(:layout)
|
358
332
|
|
@@ -0,0 +1,38 @@
|
|
1
|
+
require 'erb'
|
2
|
+
|
3
|
+
class ERB
|
4
|
+
module Util
|
5
|
+
HTML_ESCAPE = { '&' => '&', '>' => '>', '<' => '<', '"' => '"' }
|
6
|
+
JSON_ESCAPE = { '&' => '\u0026', '>' => '\u003E', '<' => '\u003C' }
|
7
|
+
|
8
|
+
# A utility method for escaping HTML tag characters.
|
9
|
+
# This method is also aliased as <tt>h</tt>.
|
10
|
+
#
|
11
|
+
# In your ERb templates, use this method to escape any unsafe content. For example:
|
12
|
+
# <%=h @person.name %>
|
13
|
+
#
|
14
|
+
# ==== Example:
|
15
|
+
# puts html_escape("is a > 0 & a < 10?")
|
16
|
+
# # => is a > 0 & a < 10?
|
17
|
+
def html_escape(s)
|
18
|
+
s.to_s.gsub(/[&"><]/) { |special| HTML_ESCAPE[special] }
|
19
|
+
end
|
20
|
+
|
21
|
+
# A utility method for escaping HTML entities in JSON strings.
|
22
|
+
# This method is also aliased as <tt>j</tt>.
|
23
|
+
#
|
24
|
+
# In your ERb templates, use this method to escape any HTML entities:
|
25
|
+
# <%=j @person.to_json %>
|
26
|
+
#
|
27
|
+
# ==== Example:
|
28
|
+
# puts json_escape("is a > 0 & a < 10?")
|
29
|
+
# # => is a \u003E 0 \u0026 a \u003C 10?
|
30
|
+
def json_escape(s)
|
31
|
+
s.to_s.gsub(/[&"><]/) { |special| JSON_ESCAPE[special] }
|
32
|
+
end
|
33
|
+
|
34
|
+
alias j json_escape
|
35
|
+
module_function :j
|
36
|
+
module_function :json_escape
|
37
|
+
end
|
38
|
+
end
|
data/lib/action_view/helpers.rb
CHANGED
@@ -1,10 +1,28 @@
|
|
1
|
-
Dir.entries(File.expand_path("#{File.dirname(__FILE__)}/helpers")).sort.each do |file|
|
2
|
-
next unless file =~ /^([a-z][a-z_]*_helper).rb$/
|
3
|
-
require "action_view/helpers/#{$1}"
|
4
|
-
end
|
5
|
-
|
6
1
|
module ActionView #:nodoc:
|
7
2
|
module Helpers #:nodoc:
|
3
|
+
autoload :ActiveRecordHelper, 'action_view/helpers/active_record_helper'
|
4
|
+
autoload :AssetTagHelper, 'action_view/helpers/asset_tag_helper'
|
5
|
+
autoload :AtomFeedHelper, 'action_view/helpers/atom_feed_helper'
|
6
|
+
autoload :BenchmarkHelper, 'action_view/helpers/benchmark_helper'
|
7
|
+
autoload :CacheHelper, 'action_view/helpers/cache_helper'
|
8
|
+
autoload :CaptureHelper, 'action_view/helpers/capture_helper'
|
9
|
+
autoload :DateHelper, 'action_view/helpers/date_helper'
|
10
|
+
autoload :DebugHelper, 'action_view/helpers/debug_helper'
|
11
|
+
autoload :FormHelper, 'action_view/helpers/form_helper'
|
12
|
+
autoload :FormOptionsHelper, 'action_view/helpers/form_options_helper'
|
13
|
+
autoload :FormTagHelper, 'action_view/helpers/form_tag_helper'
|
14
|
+
autoload :JavascriptHelper, 'action_view/helpers/javascript_helper'
|
15
|
+
autoload :NumberHelper, 'action_view/helpers/number_helper'
|
16
|
+
autoload :PrototypeHelper, 'action_view/helpers/prototype_helper'
|
17
|
+
autoload :RecordIdentificationHelper, 'action_view/helpers/record_identification_helper'
|
18
|
+
autoload :RecordTagHelper, 'action_view/helpers/record_tag_helper'
|
19
|
+
autoload :SanitizeHelper, 'action_view/helpers/sanitize_helper'
|
20
|
+
autoload :ScriptaculousHelper, 'action_view/helpers/scriptaculous_helper'
|
21
|
+
autoload :TagHelper, 'action_view/helpers/tag_helper'
|
22
|
+
autoload :TextHelper, 'action_view/helpers/text_helper'
|
23
|
+
autoload :TranslationHelper, 'action_view/helpers/translation_helper'
|
24
|
+
autoload :UrlHelper, 'action_view/helpers/url_helper'
|
25
|
+
|
8
26
|
def self.included(base)
|
9
27
|
base.extend(ClassMethods)
|
10
28
|
end
|
@@ -24,6 +42,7 @@ module ActionView #:nodoc:
|
|
24
42
|
include FormHelper
|
25
43
|
include FormOptionsHelper
|
26
44
|
include FormTagHelper
|
45
|
+
include JavaScriptHelper
|
27
46
|
include NumberHelper
|
28
47
|
include PrototypeHelper
|
29
48
|
include RecordIdentificationHelper
|
@@ -121,7 +121,7 @@ module ActionView
|
|
121
121
|
if (obj = (object.respond_to?(:errors) ? object : instance_variable_get("@#{object}"))) &&
|
122
122
|
(errors = obj.errors.on(method))
|
123
123
|
content_tag("div",
|
124
|
-
"#{options[:prepend_text]}#{errors.is_a?(Array) ? errors.first : errors}#{options[:append_text]}",
|
124
|
+
"#{options[:prepend_text]}#{ERB::Util.html_escape(errors.is_a?(Array) ? errors.first : errors)}#{options[:append_text]}",
|
125
125
|
:class => options[:css_class]
|
126
126
|
)
|
127
127
|
else
|
@@ -198,7 +198,7 @@ module ActionView
|
|
198
198
|
locale.t :header, :count => count, :model => object_name
|
199
199
|
end
|
200
200
|
message = options.include?(:message) ? options[:message] : locale.t(:body)
|
201
|
-
error_messages = objects.sum {|object| object.errors.full_messages.map {|msg| content_tag(:li, msg) } }.join
|
201
|
+
error_messages = objects.sum {|object| object.errors.full_messages.map {|msg| content_tag(:li, ERB::Util.html_escape(msg)) } }.join
|
202
202
|
|
203
203
|
contents = ''
|
204
204
|
contents << content_tag(options[:header_tag] || :h2, header_message) unless header_message.blank?
|
@@ -6,54 +6,70 @@ module ActionView
|
|
6
6
|
module Helpers #:nodoc:
|
7
7
|
# This module provides methods for generating HTML that links views to assets such
|
8
8
|
# as images, javascripts, stylesheets, and feeds. These methods do not verify
|
9
|
-
# the assets exist before linking to them
|
9
|
+
# the assets exist before linking to them:
|
10
|
+
#
|
11
|
+
# image_tag("rails.png")
|
12
|
+
# # => <img alt="Rails src="/images/rails.png?1230601161" />
|
13
|
+
# stylesheet_link_tag("application")
|
14
|
+
# # => <link href="/stylesheets/application.css?1232285206" media="screen" rel="stylesheet" type="text/css" />
|
10
15
|
#
|
11
16
|
# === Using asset hosts
|
17
|
+
#
|
12
18
|
# By default, Rails links to these assets on the current host in the public
|
13
|
-
# folder, but you can direct Rails to link to assets from a dedicated
|
14
|
-
# setting ActionController::Base.asset_host in
|
15
|
-
#
|
19
|
+
# folder, but you can direct Rails to link to assets from a dedicated asset
|
20
|
+
# server by setting ActionController::Base.asset_host in the application
|
21
|
+
# configuration, typically in <tt>config/environments/production.rb</tt>.
|
22
|
+
# For example, you'd define <tt>assets.example.com</tt> to be your asset
|
23
|
+
# host this way:
|
16
24
|
#
|
17
25
|
# ActionController::Base.asset_host = "assets.example.com"
|
26
|
+
#
|
27
|
+
# Helpers take that into account:
|
28
|
+
#
|
18
29
|
# image_tag("rails.png")
|
19
|
-
#
|
30
|
+
# # => <img alt="Rails" src="http://assets.example.com/images/rails.png?1230601161" />
|
20
31
|
# stylesheet_link_tag("application")
|
21
|
-
#
|
32
|
+
# # => <link href="http://assets.example.com/stylesheets/application.css?1232285206" media="screen" rel="stylesheet" type="text/css" />
|
22
33
|
#
|
23
|
-
#
|
24
|
-
# which means your assets often
|
25
|
-
# alleviate this by using a <tt>%d</tt> wildcard in
|
26
|
-
#
|
27
|
-
#
|
34
|
+
# Browsers typically open at most two simultaneous connections to a single
|
35
|
+
# host, which means your assets often have to wait for other assets to finish
|
36
|
+
# downloading. You can alleviate this by using a <tt>%d</tt> wildcard in the
|
37
|
+
# +asset_host+. For example, "assets%d.example.com". If that wildcard is
|
38
|
+
# present Rails distributes asset requests among the corresponding four hosts
|
39
|
+
# "assets0.example.com", ..., "assets3.example.com". With this trick browsers
|
40
|
+
# will open eight simultaneous connections rather than two.
|
28
41
|
#
|
29
42
|
# image_tag("rails.png")
|
30
|
-
#
|
43
|
+
# # => <img alt="Rails" src="http://assets0.example.com/images/rails.png?1230601161" />
|
31
44
|
# stylesheet_link_tag("application")
|
32
|
-
#
|
45
|
+
# # => <link href="http://assets2.example.com/stylesheets/application.css?1232285206" media="screen" rel="stylesheet" type="text/css" />
|
33
46
|
#
|
34
|
-
# To do this, you can either setup
|
35
|
-
# the wildcard to a single asset host.
|
36
|
-
# your ISP.
|
47
|
+
# To do this, you can either setup four actual hosts, or you can use wildcard
|
48
|
+
# DNS to CNAME the wildcard to a single asset host. You can read more about
|
49
|
+
# setting up your DNS CNAME records from your ISP.
|
37
50
|
#
|
38
51
|
# Note: This is purely a browser performance optimization and is not meant
|
39
52
|
# for server load balancing. See http://www.die.net/musings/page_load_time/
|
40
53
|
# for background.
|
41
54
|
#
|
42
|
-
# Alternatively, you can exert more control over the asset host by setting
|
43
|
-
#
|
44
|
-
# fewer/more than 4 hosts. The example proc below generates http://assets1.example.com and
|
45
|
-
# http://assets2.example.com randomly.
|
55
|
+
# Alternatively, you can exert more control over the asset host by setting
|
56
|
+
# +asset_host+ to a proc like this:
|
46
57
|
#
|
47
|
-
# ActionController::Base.asset_host = Proc.new { |source|
|
58
|
+
# ActionController::Base.asset_host = Proc.new { |source|
|
59
|
+
# "http://assets#{rand(2) + 1}.example.com"
|
60
|
+
# }
|
48
61
|
# image_tag("rails.png")
|
49
|
-
#
|
62
|
+
# # => <img alt="Rails" src="http://assets0.example.com/images/rails.png?1230601161" />
|
50
63
|
# stylesheet_link_tag("application")
|
51
|
-
#
|
64
|
+
# # => <link href="http://assets1.example.com/stylesheets/application.css?1232285206" media="screen" rel="stylesheet" type="text/css" />
|
65
|
+
#
|
66
|
+
# The example above generates "http://assets1.example.com" and
|
67
|
+
# "http://assets2.example.com" randomly. This option is useful for example if
|
68
|
+
# you need fewer/more than four hosts, custom host names, etc.
|
52
69
|
#
|
53
|
-
#
|
54
|
-
#
|
55
|
-
#
|
56
|
-
# request.
|
70
|
+
# As you see the proc takes a +source+ parameter. That's a string with the
|
71
|
+
# absolute path of the asset with any extensions and timestamps in place,
|
72
|
+
# for example "/images/rails.png?1230601161".
|
57
73
|
#
|
58
74
|
# ActionController::Base.asset_host = Proc.new { |source|
|
59
75
|
# if source.starts_with?('/images')
|
@@ -63,14 +79,16 @@ module ActionView
|
|
63
79
|
# end
|
64
80
|
# }
|
65
81
|
# image_tag("rails.png")
|
66
|
-
#
|
82
|
+
# # => <img alt="Rails" src="http://images.example.com/images/rails.png?1230601161" />
|
67
83
|
# stylesheet_link_tag("application")
|
68
|
-
#
|
84
|
+
# # => <link href="http://assets.example.com/stylesheets/application.css?1232285206" media="screen" rel="stylesheet" type="text/css" />
|
69
85
|
#
|
70
|
-
#
|
71
|
-
#
|
72
|
-
#
|
73
|
-
#
|
86
|
+
# Alternatively you may ask for a second parameter +request+. That one is
|
87
|
+
# particularly useful for serving assets from an SSL-protected page. The
|
88
|
+
# example proc below disables asset hosting for HTTPS connections, while
|
89
|
+
# still sending assets for plain HTTP requests from asset hosts. If you don't
|
90
|
+
# have SSL certificates for each of the asset hosts this technique allows you
|
91
|
+
# to avoid warnings in the client about mixed media.
|
74
92
|
#
|
75
93
|
# ActionController::Base.asset_host = Proc.new { |source, request|
|
76
94
|
# if request.ssl?
|
@@ -80,26 +98,38 @@ module ActionView
|
|
80
98
|
# end
|
81
99
|
# }
|
82
100
|
#
|
101
|
+
# You can also implement a custom asset host object that responds to +call+
|
102
|
+
# and takes either one or two parameters just like the proc.
|
103
|
+
#
|
104
|
+
# config.action_controller.asset_host = AssetHostingWithMinimumSsl.new(
|
105
|
+
# "http://asset%d.example.com", "https://asset1.example.com"
|
106
|
+
# )
|
107
|
+
#
|
83
108
|
# === Using asset timestamps
|
84
109
|
#
|
85
|
-
# By default, Rails
|
86
|
-
#
|
87
|
-
#
|
110
|
+
# By default, Rails appends asset's timestamps to all asset paths. This allows
|
111
|
+
# you to set a cache-expiration date for the asset far into the future, but
|
112
|
+
# still be able to instantly invalidate it by simply updating the file (and
|
113
|
+
# hence updating the timestamp, which then updates the URL as the timestamp
|
114
|
+
# is part of that, which in turn busts the cache).
|
88
115
|
#
|
89
|
-
# It's the responsibility of the web server you use to set the far-future
|
90
|
-
#
|
116
|
+
# It's the responsibility of the web server you use to set the far-future
|
117
|
+
# expiration date on cache assets that you need to take advantage of this
|
118
|
+
# feature. Here's an example for Apache:
|
91
119
|
#
|
92
|
-
#
|
93
|
-
#
|
94
|
-
#
|
95
|
-
#
|
96
|
-
#
|
120
|
+
# # Asset Expiration
|
121
|
+
# ExpiresActive On
|
122
|
+
# <FilesMatch "\.(ico|gif|jpe?g|png|js|css)$">
|
123
|
+
# ExpiresDefault "access plus 1 year"
|
124
|
+
# </FilesMatch>
|
97
125
|
#
|
98
|
-
# Also note that in order for this to work, all your application servers must
|
99
|
-
#
|
100
|
-
#
|
101
|
-
#
|
102
|
-
#
|
126
|
+
# Also note that in order for this to work, all your application servers must
|
127
|
+
# return the same timestamps. This means that they must have their clocks
|
128
|
+
# synchronized. If one of them drifts out of sync, you'll see different
|
129
|
+
# timestamps at random and the cache won't work. In that case the browser
|
130
|
+
# will request the same assets over and over again even thought they didn't
|
131
|
+
# change. You can use something like Live HTTP Headers for Firefox to verify
|
132
|
+
# that the cache is indeed working.
|
103
133
|
module AssetTagHelper
|
104
134
|
ASSETS_DIR = defined?(Rails.public_path) ? Rails.public_path : "public"
|
105
135
|
JAVASCRIPTS_DIR = "#{ASSETS_DIR}/javascripts"
|
@@ -111,7 +141,7 @@ module ActionView
|
|
111
141
|
# <tt>:atom</tt>. Control the link options in url_for format using the
|
112
142
|
# +url_options+. You can modify the LINK tag itself in +tag_options+.
|
113
143
|
#
|
114
|
-
# ==== Options
|
144
|
+
# ==== Options
|
115
145
|
# * <tt>:rel</tt> - Specify the relation of this link, defaults to "alternate"
|
116
146
|
# * <tt>:type</tt> - Override the auto-generated mime type
|
117
147
|
# * <tt>:title</tt> - Specify the title of the link, defaults to the +type+
|
@@ -486,7 +516,8 @@ module ActionView
|
|
486
516
|
def compute_public_path(source, dir, ext = nil, include_host = true)
|
487
517
|
has_request = @controller.respond_to?(:request)
|
488
518
|
|
489
|
-
|
519
|
+
source_ext = File.extname(source)[1..-1]
|
520
|
+
if ext && (source_ext.blank? || (ext != source_ext && File.exist?(File.join(ASSETS_DIR, dir, "#{source}.#{ext}"))))
|
490
521
|
source += ".#{ext}"
|
491
522
|
end
|
492
523
|
|