actionpack 2.1.2 → 2.2.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 +223 -7
- data/README +6 -12
- data/Rakefile +11 -11
- data/lib/action_controller.rb +9 -9
- data/lib/action_controller/assertions/response_assertions.rb +29 -78
- data/lib/action_controller/assertions/routing_assertions.rb +33 -33
- data/lib/action_controller/assertions/selector_assertions.rb +9 -5
- data/lib/action_controller/base.rb +227 -161
- data/lib/action_controller/benchmarking.rb +37 -24
- data/lib/action_controller/caching/actions.rb +53 -21
- data/lib/action_controller/caching/fragments.rb +10 -36
- data/lib/action_controller/caching/sweeping.rb +3 -3
- data/lib/action_controller/cgi_ext/session.rb +2 -22
- data/lib/action_controller/cgi_process.rb +8 -46
- data/lib/action_controller/components.rb +4 -1
- data/lib/action_controller/cookies.rb +10 -0
- data/lib/action_controller/dispatcher.rb +49 -15
- data/lib/action_controller/filters.rb +48 -10
- data/lib/action_controller/headers.rb +16 -14
- data/lib/action_controller/helpers.rb +2 -2
- data/lib/action_controller/http_authentication.rb +1 -1
- data/lib/action_controller/integration.rb +57 -60
- data/lib/action_controller/layout.rb +27 -53
- data/lib/action_controller/mime_responds.rb +5 -1
- data/lib/action_controller/mime_type.rb +64 -42
- data/lib/action_controller/mime_types.rb +2 -1
- data/lib/action_controller/performance_test.rb +16 -0
- data/lib/action_controller/polymorphic_routes.rb +16 -9
- data/lib/action_controller/rack_process.rb +303 -0
- data/lib/action_controller/request.rb +205 -97
- data/lib/action_controller/request_forgery_protection.rb +2 -2
- data/lib/action_controller/request_profiler.rb +0 -0
- data/lib/action_controller/rescue.rb +20 -115
- data/lib/action_controller/resources.rb +186 -83
- data/lib/action_controller/response.rb +140 -26
- data/lib/action_controller/routing.rb +28 -30
- data/lib/action_controller/routing/builder.rb +45 -54
- data/lib/action_controller/routing/optimisations.rb +31 -21
- data/lib/action_controller/routing/recognition_optimisation.rb +33 -27
- data/lib/action_controller/routing/route.rb +162 -147
- data/lib/action_controller/routing/route_set.rb +8 -7
- data/lib/action_controller/routing/routing_ext.rb +4 -1
- data/lib/action_controller/routing/segments.rb +50 -21
- data/lib/action_controller/session/cookie_store.rb +3 -2
- data/lib/action_controller/session/drb_server.rb +7 -7
- data/lib/action_controller/session_management.rb +6 -2
- data/lib/action_controller/streaming.rb +15 -8
- 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 +66 -2
- data/lib/action_controller/test_process.rb +71 -66
- data/lib/action_controller/translation.rb +13 -0
- data/lib/action_controller/url_rewriter.rb +90 -13
- data/lib/action_controller/vendor/html-scanner/html/node.rb +9 -2
- data/lib/action_controller/vendor/html-scanner/html/sanitizer.rb +1 -1
- data/lib/action_controller/vendor/html-scanner/html/selector.rb +2 -2
- data/lib/action_controller/verification.rb +2 -2
- data/lib/action_pack/version.rb +1 -1
- data/lib/action_view.rb +19 -11
- data/lib/action_view/base.rb +184 -150
- data/lib/action_view/helpers.rb +38 -0
- data/lib/action_view/helpers/active_record_helper.rb +56 -27
- data/lib/action_view/helpers/asset_tag_helper.rb +356 -153
- data/lib/action_view/helpers/atom_feed_helper.rb +74 -19
- data/lib/action_view/helpers/benchmark_helper.rb +3 -3
- data/lib/action_view/helpers/cache_helper.rb +1 -2
- data/lib/action_view/helpers/capture_helper.rb +19 -44
- data/lib/action_view/helpers/date_helper.rb +486 -296
- data/lib/action_view/helpers/debug_helper.rb +20 -13
- data/lib/action_view/helpers/form_helper.rb +71 -30
- data/lib/action_view/helpers/form_options_helper.rb +15 -85
- data/lib/action_view/helpers/form_tag_helper.rb +61 -38
- data/lib/action_view/helpers/javascript_helper.rb +80 -89
- data/lib/action_view/helpers/number_helper.rb +179 -74
- data/lib/action_view/helpers/prototype_helper.rb +216 -201
- data/lib/action_view/helpers/record_tag_helper.rb +4 -5
- data/lib/action_view/helpers/sanitize_helper.rb +65 -33
- data/lib/action_view/helpers/scriptaculous_helper.rb +2 -2
- data/lib/action_view/helpers/tag_helper.rb +39 -22
- data/lib/action_view/helpers/text_helper.rb +212 -118
- data/lib/action_view/helpers/translation_helper.rb +21 -0
- data/lib/action_view/helpers/url_helper.rb +100 -58
- data/lib/action_view/inline_template.rb +13 -14
- data/lib/action_view/locale/en.yml +91 -0
- data/lib/action_view/partials.rb +100 -55
- data/lib/action_view/paths.rb +125 -0
- data/lib/action_view/renderable.rb +102 -0
- data/lib/action_view/renderable_partial.rb +48 -0
- data/lib/action_view/template.rb +90 -101
- data/lib/action_view/template_error.rb +11 -21
- data/lib/action_view/template_handler.rb +8 -28
- data/lib/action_view/template_handlers.rb +45 -0
- data/lib/action_view/template_handlers/builder.rb +5 -15
- data/lib/action_view/template_handlers/erb.rb +9 -6
- data/lib/action_view/template_handlers/rjs.rb +2 -17
- data/lib/action_view/test_case.rb +7 -4
- data/test/abstract_unit.rb +4 -1
- data/test/active_record_unit.rb +28 -30
- data/test/activerecord/render_partial_with_record_identification_test.rb +25 -12
- data/test/controller/action_pack_assertions_test.rb +8 -37
- data/test/controller/addresses_render_test.rb +0 -3
- data/test/controller/assert_select_test.rb +51 -24
- data/test/controller/base_test.rb +4 -4
- data/test/controller/caching_test.rb +136 -66
- data/test/controller/capture_test.rb +1 -21
- data/test/controller/cgi_test.rb +157 -10
- data/test/controller/components_test.rb +41 -25
- data/test/controller/content_type_test.rb +49 -17
- data/test/controller/cookie_test.rb +1 -1
- data/test/controller/deprecation/deprecated_base_methods_test.rb +0 -3
- data/test/controller/dispatcher_test.rb +9 -1
- data/test/controller/filter_params_test.rb +2 -2
- data/test/controller/filters_test.rb +13 -13
- data/test/controller/html-scanner/cdata_node_test.rb +15 -0
- data/test/controller/html-scanner/node_test.rb +21 -0
- data/test/controller/html-scanner/sanitizer_test.rb +14 -0
- data/test/controller/integration_test.rb +167 -6
- data/test/controller/layout_test.rb +11 -68
- data/test/controller/logging_test.rb +46 -0
- data/test/controller/mime_responds_test.rb +61 -59
- data/test/controller/mime_type_test.rb +6 -6
- data/test/controller/polymorphic_routes_test.rb +37 -2
- data/test/controller/rack_test.rb +323 -0
- data/test/controller/redirect_test.rb +72 -71
- data/test/controller/render_test.rb +1120 -108
- data/test/controller/request_forgery_protection_test.rb +66 -52
- data/test/controller/request_test.rb +103 -146
- data/test/controller/rescue_test.rb +20 -24
- data/test/controller/resources_test.rb +408 -25
- data/test/controller/routing_test.rb +1774 -1774
- data/test/controller/send_file_test.rb +0 -4
- data/test/controller/session/cookie_store_test.rb +53 -1
- data/test/controller/test_test.rb +15 -37
- data/test/controller/translation_test.rb +26 -0
- data/test/controller/url_rewriter_test.rb +27 -28
- data/test/controller/view_paths_test.rb +48 -47
- data/test/fixtures/_top_level_partial.html.erb +1 -0
- data/test/fixtures/_top_level_partial_only.erb +1 -0
- data/test/fixtures/developers/_developer.erb +1 -0
- data/test/fixtures/fun/games/_game.erb +1 -0
- data/test/fixtures/fun/serious/games/_game.erb +1 -0
- data/test/fixtures/functional_caching/formatted_fragment_cached.html.erb +3 -0
- data/test/fixtures/functional_caching/formatted_fragment_cached.js.rjs +6 -0
- data/test/fixtures/functional_caching/formatted_fragment_cached.xml.builder +5 -0
- data/test/fixtures/functional_caching/inline_fragment_cached.html.erb +2 -0
- data/test/fixtures/layouts/_column.html.erb +2 -0
- data/test/fixtures/projects/_project.erb +1 -0
- data/test/fixtures/public/javascripts/subdir/subdir.js +1 -0
- data/test/fixtures/public/stylesheets/subdir/subdir.css +1 -0
- data/test/fixtures/replies/_reply.erb +1 -0
- data/test/fixtures/test/_counter.html.erb +1 -0
- data/test/fixtures/test/_customer.erb +1 -1
- data/test/fixtures/test/_customer_with_var.erb +1 -0
- data/test/fixtures/test/_layout_for_block_with_args.html.erb +3 -0
- data/test/fixtures/test/_local_inspector.html.erb +1 -0
- data/test/fixtures/test/_partial_with_only_html_version.html.erb +1 -0
- data/test/fixtures/test/hello.builder +1 -1
- data/test/fixtures/test/hyphen-ated.erb +1 -0
- data/test/fixtures/test/implicit_content_type.atom.builder +2 -0
- data/test/fixtures/test/nested_layout.erb +3 -0
- data/test/fixtures/test/non_erb_block_content_for.builder +1 -1
- data/test/fixtures/test/sub_template_raise.html.erb +1 -0
- data/test/fixtures/test/template.erb +1 -0
- data/test/fixtures/test/using_layout_around_block_with_args.html.erb +1 -0
- data/test/template/active_record_helper_i18n_test.rb +46 -0
- data/test/template/active_record_helper_test.rb +24 -24
- data/test/template/asset_tag_helper_test.rb +161 -29
- data/test/template/atom_feed_helper_test.rb +114 -5
- data/test/template/compiled_templates_test.rb +59 -0
- data/test/template/date_helper_i18n_test.rb +113 -0
- data/test/template/date_helper_test.rb +403 -109
- data/test/template/form_helper_test.rb +213 -154
- data/test/template/form_options_helper_test.rb +249 -897
- data/test/template/form_tag_helper_test.rb +80 -32
- data/test/template/javascript_helper_test.rb +17 -18
- data/test/template/number_helper_i18n_test.rb +54 -0
- data/test/template/number_helper_test.rb +43 -13
- data/test/template/prototype_helper_test.rb +101 -84
- data/test/template/record_tag_helper_test.rb +24 -20
- data/test/template/render_test.rb +193 -0
- data/test/template/sanitize_helper_test.rb +3 -3
- data/test/template/tag_helper_test.rb +34 -14
- data/test/template/text_helper_test.rb +83 -9
- data/test/template/translation_helper_test.rb +28 -0
- data/test/template/url_helper_test.rb +55 -18
- metadata +57 -18
- data/lib/action_view/helpers/javascripts/controls.js +0 -963
- data/lib/action_view/helpers/javascripts/dragdrop.js +0 -972
- data/lib/action_view/helpers/javascripts/effects.js +0 -1120
- data/lib/action_view/helpers/javascripts/prototype.js +0 -4225
- data/lib/action_view/partial_template.rb +0 -70
- data/lib/action_view/template_finder.rb +0 -177
- data/lib/action_view/template_handlers/compilable.rb +0 -128
- data/test/controller/custom_handler_test.rb +0 -45
- data/test/controller/new_render_test.rb +0 -945
- data/test/fixtures/test/block_content_for.erb +0 -2
- data/test/fixtures/test/erb_content_for.erb +0 -2
- data/test/template/deprecated_erb_variable_test.rb +0 -9
- data/test/template/template_finder_test.rb +0 -73
- data/test/template/template_object_test.rb +0 -95
@@ -150,7 +150,14 @@ module HTML #:nodoc:
|
|
150
150
|
end
|
151
151
|
|
152
152
|
if scanner.skip(/!\[CDATA\[/)
|
153
|
-
scanner.
|
153
|
+
unless scanner.skip_until(/\]\]>/)
|
154
|
+
if strict
|
155
|
+
raise "expected ]]> (got #{scanner.rest.inspect} for #{content})"
|
156
|
+
else
|
157
|
+
scanner.skip_until(/\Z/)
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
154
161
|
return CDATA.new(parent, line, pos, scanner.pre_match.gsub(/<!\[CDATA\[/, ''))
|
155
162
|
end
|
156
163
|
|
@@ -265,7 +272,7 @@ module HTML #:nodoc:
|
|
265
272
|
# itself.
|
266
273
|
class CDATA < Text #:nodoc:
|
267
274
|
def to_s
|
268
|
-
"<![CDATA[#{super}]>"
|
275
|
+
"<![CDATA[#{super}]]>"
|
269
276
|
end
|
270
277
|
end
|
271
278
|
|
@@ -160,7 +160,7 @@ module HTML
|
|
160
160
|
if !options[:attributes].include?(attr_name) || contains_bad_protocols?(attr_name, value)
|
161
161
|
node.attributes.delete(attr_name)
|
162
162
|
else
|
163
|
-
node.attributes[attr_name] = attr_name == 'style' ? sanitize_css(value) : CGI::escapeHTML(value)
|
163
|
+
node.attributes[attr_name] = attr_name == 'style' ? sanitize_css(value) : CGI::escapeHTML(CGI::unescapeHTML(value))
|
164
164
|
end
|
165
165
|
end
|
166
166
|
end
|
@@ -64,7 +64,7 @@ module HTML
|
|
64
64
|
#
|
65
65
|
# When using a combination of the above, the element name comes first
|
66
66
|
# followed by identifier, class names, attributes, pseudo classes and
|
67
|
-
# negation in any order. Do not
|
67
|
+
# negation in any order. Do not separate these parts with spaces!
|
68
68
|
# Space separation is used for descendant selectors.
|
69
69
|
#
|
70
70
|
# For example:
|
@@ -158,7 +158,7 @@ module HTML
|
|
158
158
|
# * <tt>:not(selector)</tt> -- Match the element only if the element does not
|
159
159
|
# match the simple selector.
|
160
160
|
#
|
161
|
-
# As you can see, <tt>:nth-child<tt> pseudo class and its
|
161
|
+
# As you can see, <tt>:nth-child<tt> pseudo class and its variant can get quite
|
162
162
|
# tricky and the CSS specification doesn't do a much better job explaining it.
|
163
163
|
# But after reading the examples and trying a few combinations, it's easy to
|
164
164
|
# figure out.
|
@@ -80,7 +80,7 @@ module ActionController #:nodoc:
|
|
80
80
|
# array (may also be a single value).
|
81
81
|
def verify(options={})
|
82
82
|
before_filter :only => options[:only], :except => options[:except] do |c|
|
83
|
-
c.
|
83
|
+
c.__send__ :verify_action, options
|
84
84
|
end
|
85
85
|
end
|
86
86
|
end
|
@@ -116,7 +116,7 @@ module ActionController #:nodoc:
|
|
116
116
|
end
|
117
117
|
|
118
118
|
def apply_redirect_to(redirect_to_option) # :nodoc:
|
119
|
-
(redirect_to_option.is_a?(Symbol) && redirect_to_option != :back) ? self.
|
119
|
+
(redirect_to_option.is_a?(Symbol) && redirect_to_option != :back) ? self.__send__(redirect_to_option) : redirect_to_option
|
120
120
|
end
|
121
121
|
|
122
122
|
def apply_remaining_actions(options) # :nodoc:
|
data/lib/action_pack/version.rb
CHANGED
data/lib/action_view.rb
CHANGED
@@ -21,25 +21,33 @@
|
|
21
21
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
22
|
#++
|
23
23
|
|
24
|
-
|
25
|
-
require '
|
26
|
-
|
27
|
-
|
28
|
-
|
24
|
+
begin
|
25
|
+
require 'active_support'
|
26
|
+
rescue LoadError
|
27
|
+
activesupport_path = "#{File.dirname(__FILE__)}/../../activesupport/lib"
|
28
|
+
if File.directory?(activesupport_path)
|
29
|
+
$:.unshift activesupport_path
|
30
|
+
require 'active_support'
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
require 'action_view/template_handlers'
|
35
|
+
require 'action_view/renderable'
|
36
|
+
require 'action_view/renderable_partial'
|
29
37
|
|
30
|
-
require 'action_view/template_finder'
|
31
38
|
require 'action_view/template'
|
32
|
-
require 'action_view/partial_template'
|
33
39
|
require 'action_view/inline_template'
|
40
|
+
require 'action_view/paths'
|
34
41
|
|
35
42
|
require 'action_view/base'
|
36
43
|
require 'action_view/partials'
|
37
44
|
require 'action_view/template_error'
|
38
45
|
|
46
|
+
I18n.load_path << "#{File.dirname(__FILE__)}/action_view/locale/en.yml"
|
47
|
+
|
48
|
+
require 'action_view/helpers'
|
49
|
+
|
39
50
|
ActionView::Base.class_eval do
|
40
51
|
include ActionView::Partials
|
41
|
-
|
42
|
-
ActionView::Base.helper_modules.each do |helper_module|
|
43
|
-
include helper_module
|
44
|
-
end
|
52
|
+
include ActionView::Helpers
|
45
53
|
end
|
data/lib/action_view/base.rb
CHANGED
@@ -1,17 +1,23 @@
|
|
1
1
|
module ActionView #:nodoc:
|
2
2
|
class ActionViewError < StandardError #:nodoc:
|
3
3
|
end
|
4
|
-
|
4
|
+
|
5
5
|
class MissingTemplate < ActionViewError #:nodoc:
|
6
|
+
def initialize(paths, path, template_format = nil)
|
7
|
+
full_template_path = path.include?('.') ? path : "#{path}.erb"
|
8
|
+
display_paths = paths.join(':')
|
9
|
+
template_type = (path =~ /layouts/i) ? 'layout' : 'template'
|
10
|
+
super("Missing #{template_type} #{full_template_path} in view path #{display_paths}")
|
11
|
+
end
|
6
12
|
end
|
7
13
|
|
8
|
-
# Action View templates can be written in three ways. If the template file has a <tt>.erb</tt> (or <tt>.rhtml</tt>) extension then it uses a mixture of ERb
|
9
|
-
# (included in Ruby) and HTML. If the template file has a <tt>.builder</tt> (or <tt>.rxml</tt>) extension then Jim Weirich's Builder::XmlMarkup library is used.
|
14
|
+
# Action View templates can be written in three ways. If the template file has a <tt>.erb</tt> (or <tt>.rhtml</tt>) extension then it uses a mixture of ERb
|
15
|
+
# (included in Ruby) and HTML. If the template file has a <tt>.builder</tt> (or <tt>.rxml</tt>) extension then Jim Weirich's Builder::XmlMarkup library is used.
|
10
16
|
# If the template file has a <tt>.rjs</tt> extension then it will use ActionView::Helpers::PrototypeHelper::JavaScriptGenerator.
|
11
|
-
#
|
17
|
+
#
|
12
18
|
# = ERb
|
13
|
-
#
|
14
|
-
# You trigger ERb by using embeddings such as <% %>, <% -%>, and <%= %>. The <%= %> tag set is used when you want output. Consider the
|
19
|
+
#
|
20
|
+
# You trigger ERb by using embeddings such as <% %>, <% -%>, and <%= %>. The <%= %> tag set is used when you want output. Consider the
|
15
21
|
# following loop for names:
|
16
22
|
#
|
17
23
|
# <b>Names of all the people</b>
|
@@ -51,7 +57,7 @@ module ActionView #:nodoc:
|
|
51
57
|
# <title><%= @page_title %></title>
|
52
58
|
#
|
53
59
|
# == Passing local variables to sub templates
|
54
|
-
#
|
60
|
+
#
|
55
61
|
# You can pass local variables to sub templates by using a hash with the variable names as keys and the objects as values:
|
56
62
|
#
|
57
63
|
# <%= render "shared/header", { :headline => "Welcome", :person => person } %>
|
@@ -77,8 +83,8 @@ module ActionView #:nodoc:
|
|
77
83
|
#
|
78
84
|
# == Builder
|
79
85
|
#
|
80
|
-
# Builder templates are a more programmatic alternative to ERb. They are especially useful for generating XML content. An XmlMarkup object
|
81
|
-
# named +xml+ is automatically made available to templates with a <tt>.builder</tt> extension.
|
86
|
+
# Builder templates are a more programmatic alternative to ERb. They are especially useful for generating XML content. An XmlMarkup object
|
87
|
+
# named +xml+ is automatically made available to templates with a <tt>.builder</tt> extension.
|
82
88
|
#
|
83
89
|
# Here are some basic examples:
|
84
90
|
#
|
@@ -87,7 +93,7 @@ module ActionView #:nodoc:
|
|
87
93
|
# xml.a("A Link", "href"=>"http://onestepback.org") # => <a href="http://onestepback.org">A Link</a>
|
88
94
|
# xml.target("name"=>"compile", "option"=>"fast") # => <target option="fast" name="compile"\>
|
89
95
|
# # NOTE: order of attributes is not specified.
|
90
|
-
#
|
96
|
+
#
|
91
97
|
# Any method with a block will be treated as an XML markup tag with nested markup in the block. For example, the following:
|
92
98
|
#
|
93
99
|
# xml.div {
|
@@ -111,7 +117,7 @@ module ActionView #:nodoc:
|
|
111
117
|
# xml.description "Basecamp: Recent items"
|
112
118
|
# xml.language "en-us"
|
113
119
|
# xml.ttl "40"
|
114
|
-
#
|
120
|
+
#
|
115
121
|
# for item in @recent_items
|
116
122
|
# xml.item do
|
117
123
|
# xml.title(item_title(item))
|
@@ -119,7 +125,7 @@ module ActionView #:nodoc:
|
|
119
125
|
# xml.pubDate(item_pubDate(item))
|
120
126
|
# xml.guid(@person.firm.account.url + @recent_items.url(item))
|
121
127
|
# xml.link(@person.firm.account.url + @recent_items.url(item))
|
122
|
-
#
|
128
|
+
#
|
123
129
|
# xml.tag!("dc:creator", item.author_name) if item_has_creator?(item)
|
124
130
|
# end
|
125
131
|
# end
|
@@ -130,12 +136,12 @@ module ActionView #:nodoc:
|
|
130
136
|
#
|
131
137
|
# == JavaScriptGenerator
|
132
138
|
#
|
133
|
-
# JavaScriptGenerator templates end in <tt>.rjs</tt>. Unlike conventional templates which are used to
|
134
|
-
# render the results of an action, these templates generate instructions on how to modify an already rendered page. This makes it easy to
|
135
|
-
# modify multiple elements on your page in one declarative Ajax response. Actions with these templates are called in the background with Ajax
|
139
|
+
# JavaScriptGenerator templates end in <tt>.rjs</tt>. Unlike conventional templates which are used to
|
140
|
+
# render the results of an action, these templates generate instructions on how to modify an already rendered page. This makes it easy to
|
141
|
+
# modify multiple elements on your page in one declarative Ajax response. Actions with these templates are called in the background with Ajax
|
136
142
|
# and make updates to the page where the request originated from.
|
137
|
-
#
|
138
|
-
# An instance of the JavaScriptGenerator object named +page+ is automatically made available to your template, which is implicitly wrapped in an ActionView::Helpers::PrototypeHelper#update_page block.
|
143
|
+
#
|
144
|
+
# An instance of the JavaScriptGenerator object named +page+ is automatically made available to your template, which is implicitly wrapped in an ActionView::Helpers::PrototypeHelper#update_page block.
|
139
145
|
#
|
140
146
|
# When an <tt>.rjs</tt> action is called with +link_to_remote+, the generated JavaScript is automatically evaluated. Example:
|
141
147
|
#
|
@@ -145,203 +151,231 @@ module ActionView #:nodoc:
|
|
145
151
|
#
|
146
152
|
# page.replace_html 'sidebar', :partial => 'sidebar'
|
147
153
|
# page.remove "person-#{@person.id}"
|
148
|
-
# page.visual_effect :highlight, 'user-list'
|
154
|
+
# page.visual_effect :highlight, 'user-list'
|
149
155
|
#
|
150
156
|
# This refreshes the sidebar, removes a person element and highlights the user list.
|
151
|
-
#
|
157
|
+
#
|
152
158
|
# See the ActionView::Helpers::PrototypeHelper::GeneratorMethods documentation for more details.
|
153
159
|
class Base
|
154
160
|
include ERB::Util
|
161
|
+
extend ActiveSupport::Memoizable
|
155
162
|
|
156
|
-
|
157
|
-
attr_accessor :base_path, :assigns, :template_extension, :first_render
|
163
|
+
attr_accessor :base_path, :assigns, :template_extension
|
158
164
|
attr_accessor :controller
|
159
|
-
|
165
|
+
|
160
166
|
attr_writer :template_format
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
167
|
+
|
168
|
+
attr_accessor :output_buffer
|
169
|
+
|
170
|
+
class << self
|
171
|
+
delegate :erb_trim_mode=, :to => 'ActionView::TemplateHandlers::ERB'
|
172
|
+
delegate :logger, :to => 'ActionController::Base'
|
173
|
+
end
|
174
|
+
|
175
|
+
# Templates that are exempt from layouts
|
176
|
+
@@exempt_from_layout = Set.new([/\.rjs$/])
|
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)
|
175
184
|
end
|
176
185
|
|
177
186
|
# Specify whether RJS responses should be wrapped in a try/catch block
|
178
|
-
# that alert()s the caught exception (and then re-raises it).
|
187
|
+
# that alert()s the caught exception (and then re-raises it).
|
179
188
|
@@debug_rjs = false
|
180
189
|
cattr_accessor :debug_rjs
|
181
190
|
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
deprecate :erb_variable= => 'The erb variable will no longer be configurable. Use the concat helper method instead of appending to it directly.'
|
186
|
-
end
|
191
|
+
# A warning will be displayed whenever an action results in a cache miss on your view paths.
|
192
|
+
@@warn_cache_misses = false
|
193
|
+
cattr_accessor :warn_cache_misses
|
187
194
|
|
188
195
|
attr_internal :request
|
189
196
|
|
190
197
|
delegate :request_forgery_protection_token, :template, :params, :session, :cookies, :response, :headers,
|
191
|
-
:flash, :logger, :action_name, :to => :controller
|
192
|
-
|
198
|
+
:flash, :logger, :action_name, :controller_name, :to => :controller
|
199
|
+
|
193
200
|
module CompiledTemplates #:nodoc:
|
194
201
|
# holds compiled template code
|
195
202
|
end
|
196
203
|
include CompiledTemplates
|
197
204
|
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
# Map method names to the names passed in local assigns so far
|
202
|
-
@@template_args = {}
|
205
|
+
def self.process_view_paths(value)
|
206
|
+
ActionView::PathSet.new(Array(value))
|
207
|
+
end
|
203
208
|
|
204
|
-
|
205
|
-
cattr_reader :computed_public_paths
|
206
|
-
@@computed_public_paths = {}
|
209
|
+
attr_reader :helpers
|
207
210
|
|
208
|
-
class
|
209
|
-
|
211
|
+
class ProxyModule < Module
|
212
|
+
def initialize(receiver)
|
213
|
+
@receiver = receiver
|
214
|
+
end
|
210
215
|
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
next unless file =~ /^([a-z][a-z_]*_helper).rb$/
|
215
|
-
require "action_view/helpers/#{$1}"
|
216
|
-
helper_module_name = $1.camelize
|
217
|
-
if Helpers.const_defined?(helper_module_name)
|
218
|
-
helpers << Helpers.const_get(helper_module_name)
|
219
|
-
end
|
216
|
+
def include(*args)
|
217
|
+
super(*args)
|
218
|
+
@receiver.extend(*args)
|
220
219
|
end
|
221
|
-
return helpers
|
222
220
|
end
|
223
221
|
|
224
222
|
def initialize(view_paths = [], assigns_for_first_render = {}, controller = nil)#:nodoc:
|
225
223
|
@assigns = assigns_for_first_render
|
226
224
|
@assigns_added = nil
|
225
|
+
@_render_stack = []
|
227
226
|
@controller = controller
|
228
|
-
@
|
227
|
+
@helpers = ProxyModule.new(self)
|
228
|
+
self.view_paths = view_paths
|
229
229
|
end
|
230
230
|
|
231
|
-
|
232
|
-
# it's relative to the view_paths array, otherwise it's absolute. The hash in <tt>local_assigns</tt>
|
233
|
-
# is made available as local variables.
|
234
|
-
def render_file(template_path, use_full_path = true, local_assigns = {}) #:nodoc:
|
235
|
-
if defined?(ActionMailer) && defined?(ActionMailer::Base) && controller.is_a?(ActionMailer::Base) && !template_path.include?("/")
|
236
|
-
raise ActionViewError, <<-END_ERROR
|
237
|
-
Due to changes in ActionMailer, you need to provide the mailer_name along with the template name.
|
238
|
-
|
239
|
-
render "user_mailer/signup"
|
240
|
-
render :file => "user_mailer/signup"
|
231
|
+
attr_reader :view_paths
|
241
232
|
|
242
|
-
|
243
|
-
|
244
|
-
render :partial => 'signup' # no mailer_name necessary
|
245
|
-
END_ERROR
|
246
|
-
end
|
247
|
-
|
248
|
-
Template.new(self, template_path, use_full_path, local_assigns).render_template
|
233
|
+
def view_paths=(paths)
|
234
|
+
@view_paths = self.class.process_view_paths(paths)
|
249
235
|
end
|
250
|
-
|
251
|
-
# Renders the template present at <tt>template_path</tt> (relative to the view_paths array).
|
236
|
+
|
237
|
+
# Renders the template present at <tt>template_path</tt> (relative to the view_paths array).
|
252
238
|
# The hash in <tt>local_assigns</tt> is made available as local variables.
|
253
239
|
def render(options = {}, local_assigns = {}, &block) #:nodoc:
|
240
|
+
local_assigns ||= {}
|
241
|
+
|
254
242
|
if options.is_a?(String)
|
255
|
-
|
243
|
+
ActiveSupport::Deprecation.warn(
|
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)
|
256
249
|
elsif options == :update
|
257
250
|
update_page(&block)
|
258
251
|
elsif options.is_a?(Hash)
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
if partial_layout = options.delete(:layout)
|
263
|
-
if block_given?
|
264
|
-
wrap_content_for_layout capture(&block) do
|
265
|
-
concat(render(options.merge(:partial => partial_layout)), block.binding)
|
266
|
-
end
|
267
|
-
else
|
268
|
-
wrap_content_for_layout render(options) do
|
269
|
-
render(options.merge(:partial => partial_layout))
|
270
|
-
end
|
271
|
-
end
|
252
|
+
options = options.reverse_merge(:locals => {})
|
253
|
+
if options[:layout]
|
254
|
+
_render_with_layout(options, local_assigns, &block)
|
272
255
|
elsif options[:file]
|
273
|
-
|
274
|
-
elsif options[:partial] && options[:collection]
|
275
|
-
render_partial_collection(options[:partial], options[:collection], options[:spacer_template], options[:locals])
|
256
|
+
_pick_template(options[:file]).render_template(self, options[:locals])
|
276
257
|
elsif options[:partial]
|
277
|
-
render_partial(options
|
258
|
+
render_partial(options)
|
278
259
|
elsif options[:inline]
|
279
|
-
|
280
|
-
|
260
|
+
InlineTemplate.new(options[:inline], options[:type]).render(self, options[:locals])
|
261
|
+
elsif options[:text]
|
262
|
+
options[:text]
|
281
263
|
end
|
282
264
|
end
|
283
265
|
end
|
284
266
|
|
285
|
-
|
286
|
-
|
267
|
+
# The format to be used when choosing between multiple templates with
|
268
|
+
# the same name but differing formats. See +Request#template_format+
|
269
|
+
# for more details.
|
270
|
+
def template_format
|
271
|
+
if defined? @template_format
|
272
|
+
@template_format
|
273
|
+
elsif controller && controller.respond_to?(:request)
|
274
|
+
@template_format = controller.request.template_format
|
275
|
+
else
|
276
|
+
@template_format = :html
|
277
|
+
end
|
287
278
|
end
|
288
279
|
|
289
|
-
#
|
290
|
-
|
291
|
-
|
280
|
+
# Access the current template being rendered.
|
281
|
+
# Returns a ActionView::Template object.
|
282
|
+
def template
|
283
|
+
@_render_stack.last
|
292
284
|
end
|
293
285
|
|
294
|
-
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
|
304
|
-
if controller && controller.respond_to?(:request)
|
305
|
-
parameter_format = controller.request.parameters[:format]
|
306
|
-
accept_format = controller.request.accepts.first
|
286
|
+
private
|
287
|
+
# Evaluates the local assigns and controller ivars, pushes them to the view.
|
288
|
+
def _evaluate_assigns_and_ivars #:nodoc:
|
289
|
+
unless @assigns_added
|
290
|
+
@assigns.each { |key, value| instance_variable_set("@#{key}", value) }
|
291
|
+
_copy_ivars_from_controller
|
292
|
+
@assigns_added = true
|
293
|
+
end
|
294
|
+
end
|
307
295
|
|
308
|
-
|
309
|
-
|
310
|
-
|
311
|
-
|
312
|
-
@
|
313
|
-
else
|
314
|
-
@template_format = parameter_format.to_sym
|
296
|
+
def _copy_ivars_from_controller #:nodoc:
|
297
|
+
if @controller
|
298
|
+
variables = @controller.instance_variable_names
|
299
|
+
variables -= @controller.protected_instance_variables if @controller.respond_to?(:protected_instance_variables)
|
300
|
+
variables.each { |name| instance_variable_set(name, @controller.instance_variable_get(name)) }
|
315
301
|
end
|
316
|
-
else
|
317
|
-
@template_format = :html
|
318
302
|
end
|
319
|
-
end
|
320
303
|
|
321
|
-
|
322
|
-
|
323
|
-
|
324
|
-
|
325
|
-
returning(yield) { @content_for_layout = original_content_for_layout }
|
304
|
+
def _set_controller_content_type(content_type) #:nodoc:
|
305
|
+
if controller.respond_to?(:response)
|
306
|
+
controller.response.content_type ||= content_type
|
307
|
+
end
|
326
308
|
end
|
327
309
|
|
328
|
-
|
329
|
-
|
330
|
-
|
331
|
-
|
332
|
-
|
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 = self.view_paths[template_file_name]
|
324
|
+
template
|
325
|
+
elsif (first_render = @_render_stack.first) && first_render.respond_to?(:format_and_extension) &&
|
326
|
+
(template = self.view_paths["#{template_file_name}.#{first_render.format_and_extension}"])
|
327
|
+
template
|
328
|
+
elsif template_format == :js && template = self.view_paths["#{template_file_name}.html"]
|
329
|
+
@template_format = :html
|
330
|
+
template
|
331
|
+
else
|
332
|
+
template = Template.new(template_path, view_paths)
|
333
|
+
|
334
|
+
if self.class.warn_cache_misses && logger
|
335
|
+
logger.debug "[PERFORMANCE] Rendering a template that was " +
|
336
|
+
"not found in view path. Templates outside the view path are " +
|
337
|
+
"not cached and result in expensive disk operations. Move this " +
|
338
|
+
"file into #{view_paths.join(':')} or add the folder to your " +
|
339
|
+
"view path list"
|
340
|
+
end
|
341
|
+
|
342
|
+
template
|
333
343
|
end
|
334
344
|
end
|
345
|
+
memoize :_pick_template
|
335
346
|
|
336
|
-
|
337
|
-
|
338
|
-
|
347
|
+
def _exempt_from_layout?(template_path) #:nodoc:
|
348
|
+
template = _pick_template(template_path).to_s
|
349
|
+
@@exempt_from_layout.any? { |ext| template =~ ext }
|
350
|
+
rescue ActionView::MissingTemplate
|
351
|
+
return false
|
339
352
|
end
|
340
|
-
|
341
|
-
def
|
342
|
-
|
343
|
-
|
344
|
-
|
353
|
+
|
354
|
+
def _render_with_layout(options, local_assigns, &block) #:nodoc:
|
355
|
+
partial_layout = options.delete(:layout)
|
356
|
+
|
357
|
+
if block_given?
|
358
|
+
begin
|
359
|
+
@_proc_for_layout = block
|
360
|
+
concat(render(options.merge(:partial => partial_layout)))
|
361
|
+
ensure
|
362
|
+
@_proc_for_layout = nil
|
363
|
+
end
|
364
|
+
else
|
365
|
+
begin
|
366
|
+
original_content_for_layout = @content_for_layout if defined?(@content_for_layout)
|
367
|
+
@content_for_layout = render(options)
|
368
|
+
|
369
|
+
if (options[:inline] || options[:file] || options[:text])
|
370
|
+
@cached_content_for_layout = @content_for_layout
|
371
|
+
render(:file => partial_layout, :locals => local_assigns)
|
372
|
+
else
|
373
|
+
render(options.merge(:partial => partial_layout))
|
374
|
+
end
|
375
|
+
ensure
|
376
|
+
@content_for_layout = original_content_for_layout
|
377
|
+
end
|
378
|
+
end
|
345
379
|
end
|
346
380
|
end
|
347
381
|
end
|