actionpack 1.11.2 → 1.12.0
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 +392 -5
- data/lib/action_controller.rb +8 -4
- data/lib/action_controller/assertions.rb +9 -10
- data/lib/action_controller/base.rb +177 -88
- data/lib/action_controller/benchmarking.rb +5 -5
- data/lib/action_controller/caching.rb +44 -36
- data/lib/action_controller/cgi_ext/cgi_methods.rb +71 -6
- data/lib/action_controller/cgi_ext/cookie_performance_fix.rb +1 -1
- data/lib/action_controller/cgi_process.rb +36 -24
- data/lib/action_controller/components.rb +152 -52
- data/lib/action_controller/dependencies.rb +1 -1
- data/lib/action_controller/deprecated_redirects.rb +2 -2
- data/lib/action_controller/deprecated_request_methods.rb +34 -0
- data/lib/action_controller/filters.rb +59 -19
- data/lib/action_controller/flash.rb +53 -47
- data/lib/action_controller/helpers.rb +2 -2
- data/lib/action_controller/integration.rb +524 -0
- data/lib/action_controller/layout.rb +58 -23
- data/lib/action_controller/mime_responds.rb +163 -0
- data/lib/action_controller/mime_type.rb +142 -0
- data/lib/action_controller/pagination.rb +13 -7
- data/lib/action_controller/request.rb +59 -56
- data/lib/action_controller/rescue.rb +1 -1
- data/lib/action_controller/routing.rb +29 -10
- data/lib/action_controller/scaffolding.rb +8 -0
- data/lib/action_controller/session/active_record_store.rb +21 -10
- data/lib/action_controller/session/mem_cache_store.rb +18 -12
- data/lib/action_controller/session_management.rb +30 -11
- data/lib/action_controller/templates/rescues/_trace.rhtml +1 -1
- data/lib/action_controller/templates/scaffolds/layout.rhtml +4 -4
- data/lib/action_controller/templates/scaffolds/list.rhtml +1 -1
- data/lib/action_controller/test_process.rb +189 -118
- data/lib/action_controller/vendor/html-scanner/html/node.rb +20 -1
- data/lib/action_controller/vendor/html-scanner/html/tokenizer.rb +3 -0
- data/lib/action_controller/vendor/html-scanner/html/version.rb +1 -1
- data/lib/action_controller/vendor/xml_node.rb +97 -0
- data/lib/action_controller/verification.rb +2 -0
- data/lib/action_pack/version.rb +3 -3
- data/lib/action_view.rb +0 -2
- data/lib/action_view/base.rb +109 -36
- data/lib/action_view/compiled_templates.rb +1 -1
- data/lib/action_view/helpers/active_record_helper.rb +4 -2
- data/lib/action_view/helpers/asset_tag_helper.rb +6 -7
- data/lib/action_view/helpers/capture_helper.rb +49 -12
- data/lib/action_view/helpers/date_helper.rb +14 -4
- data/lib/action_view/helpers/form_helper.rb +136 -20
- data/lib/action_view/helpers/form_options_helper.rb +29 -7
- data/lib/action_view/helpers/form_tag_helper.rb +22 -20
- data/lib/action_view/helpers/java_script_macros_helper.rb +29 -9
- data/lib/action_view/helpers/javascript_helper.rb +50 -446
- data/lib/action_view/helpers/javascripts/controls.js +95 -30
- data/lib/action_view/helpers/javascripts/dragdrop.js +161 -21
- data/lib/action_view/helpers/javascripts/effects.js +310 -211
- data/lib/action_view/helpers/javascripts/prototype.js +228 -28
- data/lib/action_view/helpers/number_helper.rb +9 -9
- data/lib/action_view/helpers/pagination_helper.rb +1 -1
- data/lib/action_view/helpers/prototype_helper.rb +900 -0
- data/lib/action_view/helpers/scriptaculous_helper.rb +135 -0
- data/lib/action_view/helpers/text_helper.rb +7 -6
- data/lib/action_view/helpers/url_helper.rb +23 -14
- data/lib/action_view/partials.rb +12 -4
- data/rakefile +13 -5
- data/test/abstract_unit.rb +4 -3
- data/test/active_record_unit.rb +88 -0
- data/test/{controller → activerecord}/active_record_assertions_test.rb +7 -50
- data/test/{controller → activerecord}/active_record_store_test.rb +27 -4
- data/test/activerecord/pagination_test.rb +161 -0
- data/test/controller/action_pack_assertions_test.rb +18 -15
- data/test/controller/base_test.rb +31 -42
- data/test/controller/benchmark_test.rb +8 -11
- data/test/controller/capture_test.rb +33 -1
- data/test/controller/cgi_test.rb +33 -0
- data/test/controller/custom_handler_test.rb +8 -0
- data/test/controller/fake_controllers.rb +9 -17
- data/test/controller/filters_test.rb +32 -3
- data/test/controller/flash_test.rb +26 -41
- data/test/controller/fragment_store_setting_test.rb +1 -1
- data/test/controller/layout_test.rb +73 -0
- data/test/controller/mime_responds_test.rb +257 -0
- data/test/controller/mime_type_test.rb +24 -0
- data/test/controller/new_render_test.rb +157 -1
- data/test/controller/redirect_test.rb +23 -0
- data/test/controller/render_test.rb +54 -56
- data/test/controller/request_test.rb +25 -0
- data/test/controller/routing_test.rb +74 -66
- data/test/controller/test_test.rb +66 -1
- data/test/controller/verification_test.rb +3 -1
- data/test/controller/webservice_test.rb +255 -0
- data/test/fixtures/companies.yml +24 -0
- data/test/fixtures/company.rb +9 -0
- data/test/fixtures/db_definitions/sqlite.sql +42 -0
- data/test/fixtures/developer.rb +7 -0
- data/test/fixtures/developers.yml +21 -0
- data/test/fixtures/developers_projects.yml +13 -0
- data/test/fixtures/layout_tests/layouts/controller_name_space/nested.rhtml +1 -0
- data/test/fixtures/layout_tests/layouts/item.rhtml +1 -0
- data/test/fixtures/layout_tests/layouts/layout_test.rhtml +1 -0
- data/test/fixtures/layout_tests/layouts/third_party_template_library.mab +1 -0
- data/test/fixtures/layout_tests/views/hello.rhtml +1 -0
- data/test/fixtures/multipart/mona_lisa.jpg +0 -0
- data/test/fixtures/project.rb +3 -0
- data/test/fixtures/projects.yml +7 -0
- data/test/fixtures/replies.yml +13 -0
- data/test/fixtures/reply.rb +5 -0
- data/test/fixtures/respond_to/all_types_with_layout.rhtml +1 -0
- data/test/fixtures/respond_to/all_types_with_layout.rjs +1 -0
- data/test/fixtures/respond_to/layouts/standard.rhtml +1 -0
- data/test/fixtures/respond_to/using_defaults.rhtml +1 -0
- data/test/fixtures/respond_to/using_defaults.rjs +1 -0
- data/test/fixtures/respond_to/using_defaults.rxml +1 -0
- data/test/fixtures/respond_to/using_defaults_with_type_list.rhtml +1 -0
- data/test/fixtures/respond_to/using_defaults_with_type_list.rjs +1 -0
- data/test/fixtures/respond_to/using_defaults_with_type_list.rxml +1 -0
- data/test/fixtures/test/block_content_for.rhtml +2 -0
- data/test/fixtures/test/delete_with_js.rjs +2 -0
- data/test/fixtures/test/dot.directory/render_file_with_ivar.rhtml +1 -0
- data/test/fixtures/test/enum_rjs_test.rjs +6 -0
- data/test/fixtures/test/erb_content_for.rhtml +2 -0
- data/test/fixtures/test/hello_world.rxml +3 -0
- data/test/fixtures/test/hello_world_with_layout_false.rhtml +1 -0
- data/test/fixtures/test/non_erb_block_content_for.rxml +4 -0
- data/test/fixtures/topic.rb +3 -0
- data/test/fixtures/topics.yml +22 -0
- data/test/template/active_record_helper_test.rb +4 -0
- data/test/template/asset_tag_helper_test.rb +7 -2
- data/test/template/date_helper_test.rb +39 -2
- data/test/template/form_helper_test.rb +238 -5
- data/test/template/form_options_helper_test.rb +78 -0
- data/test/template/form_tag_helper_test.rb +11 -0
- data/test/template/java_script_macros_helper_test.rb +51 -6
- data/test/template/javascript_helper_test.rb +7 -153
- data/test/template/number_helper_test.rb +14 -13
- data/test/template/prototype_helper_test.rb +423 -0
- data/test/template/scriptaculous_helper_test.rb +90 -0
- data/test/template/text_helper_test.rb +12 -9
- data/test/template/url_helper_test.rb +31 -15
- metadata +291 -246
- data/lib/action_controller/cgi_ext/multipart_progress.rb +0 -169
- data/lib/action_controller/upload_progress.rb +0 -473
- data/lib/action_controller/vendor/html-scanner/html/node.rb.rej +0 -17
- data/lib/action_view/helpers/upload_progress_helper.rb +0 -433
- data/lib/action_view/vendor/builder.rb +0 -13
- data/lib/action_view/vendor/builder/blankslate.rb +0 -53
- data/lib/action_view/vendor/builder/xmlbase.rb +0 -143
- data/lib/action_view/vendor/builder/xmlevents.rb +0 -63
- data/lib/action_view/vendor/builder/xmlmarkup.rb +0 -308
- data/test/controller/multipart_progress_testx.rb +0 -365
- data/test/controller/upload_progress_testx.rb +0 -89
- data/test/template/upload_progress_helper_testx.rb +0 -136
@@ -150,6 +150,11 @@ module HTML #:nodoc:
|
|
150
150
|
end
|
151
151
|
end
|
152
152
|
|
153
|
+
if scanner.skip(/!\[CDATA\[/)
|
154
|
+
scanner.scan_until(/\]\]>/)
|
155
|
+
return CDATA.new(parent, line, pos, scanner.pre_match)
|
156
|
+
end
|
157
|
+
|
153
158
|
closing = ( scanner.scan(/\//) ? :close : nil )
|
154
159
|
return Text.new(parent, line, pos, content) unless name = scanner.scan(/[\w:]+/)
|
155
160
|
name.downcase!
|
@@ -256,6 +261,14 @@ module HTML #:nodoc:
|
|
256
261
|
content == node.content
|
257
262
|
end
|
258
263
|
end
|
264
|
+
|
265
|
+
# A CDATA node is simply a text node with a specialized way of displaying
|
266
|
+
# itself.
|
267
|
+
class CDATA < Text #:nodoc:
|
268
|
+
def to_s
|
269
|
+
"<![CDATA[#{super}]>"
|
270
|
+
end
|
271
|
+
end
|
259
272
|
|
260
273
|
# A Tag is any node that represents markup. It may be an opening tag, a
|
261
274
|
# closing tag, or a self-closing tag. It has a name, and may have a hash of
|
@@ -399,7 +412,13 @@ module HTML #:nodoc:
|
|
399
412
|
conditions = validate_conditions(conditions)
|
400
413
|
|
401
414
|
# check content of child nodes
|
402
|
-
|
415
|
+
if conditions[:content]
|
416
|
+
if children.empty?
|
417
|
+
return false unless match_condition("", conditions[:content])
|
418
|
+
else
|
419
|
+
return false unless children.find { |child| child.match(conditions[:content]) }
|
420
|
+
end
|
421
|
+
end
|
403
422
|
|
404
423
|
# test the name
|
405
424
|
return false unless match_condition(@name, conditions[:tag]) if conditions[:tag]
|
@@ -52,6 +52,9 @@ module HTML #:nodoc:
|
|
52
52
|
if @scanner.scan(/!--/) # comment
|
53
53
|
tag << @scanner.matched
|
54
54
|
tag << (@scanner.scan_until(/--\s*>/) || @scanner.scan_until(/\Z/))
|
55
|
+
elsif @scanner.scan(/!\[CDATA\[/)
|
56
|
+
tag << @scanner.matched
|
57
|
+
tag << @scanner.scan_until(/\]\]>/)
|
55
58
|
elsif @scanner.scan(/!/) # doctype
|
56
59
|
tag << @scanner.matched
|
57
60
|
tag << consume_quoted_regions
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require 'rexml/document'
|
2
|
+
|
3
|
+
# SimpleXML like xml parser. Written by leon breet from the ruby on rails Mailing list
|
4
|
+
class XmlNode #:nodoc:
|
5
|
+
attr :node
|
6
|
+
|
7
|
+
def initialize(node, options = {})
|
8
|
+
@node = node
|
9
|
+
@children = {}
|
10
|
+
@raise_errors = options[:raise_errors]
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.from_xml(xml_or_io)
|
14
|
+
document = REXML::Document.new(xml_or_io)
|
15
|
+
if document.root
|
16
|
+
XmlNode.new(document.root)
|
17
|
+
else
|
18
|
+
XmlNode.new(document)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def node_encoding
|
23
|
+
@node.encoding
|
24
|
+
end
|
25
|
+
|
26
|
+
def node_name
|
27
|
+
@node.name
|
28
|
+
end
|
29
|
+
|
30
|
+
def node_value
|
31
|
+
@node.text
|
32
|
+
end
|
33
|
+
|
34
|
+
def node_value=(value)
|
35
|
+
@node.text = value
|
36
|
+
end
|
37
|
+
|
38
|
+
def xpath(expr)
|
39
|
+
matches = nil
|
40
|
+
REXML::XPath.each(@node, expr) do |element|
|
41
|
+
matches ||= XmlNodeList.new
|
42
|
+
matches << (@children[element] ||= XmlNode.new(element))
|
43
|
+
end
|
44
|
+
matches
|
45
|
+
end
|
46
|
+
|
47
|
+
def method_missing(name, *args)
|
48
|
+
name = name.to_s
|
49
|
+
nodes = nil
|
50
|
+
@node.each_element(name) do |element|
|
51
|
+
nodes ||= XmlNodeList.new
|
52
|
+
nodes << (@children[element] ||= XmlNode.new(element))
|
53
|
+
end
|
54
|
+
nodes
|
55
|
+
end
|
56
|
+
|
57
|
+
def <<(node)
|
58
|
+
if node.is_a? REXML::Node
|
59
|
+
child = node
|
60
|
+
elsif node.respond_to? :node
|
61
|
+
child = node.node
|
62
|
+
end
|
63
|
+
@node.add_element child
|
64
|
+
@children[child] ||= XmlNode.new(child)
|
65
|
+
end
|
66
|
+
|
67
|
+
def [](name)
|
68
|
+
@node.attributes[name.to_s]
|
69
|
+
end
|
70
|
+
|
71
|
+
def []=(name, value)
|
72
|
+
@node.attributes[name.to_s] = value
|
73
|
+
end
|
74
|
+
|
75
|
+
def to_s
|
76
|
+
@node.to_s
|
77
|
+
end
|
78
|
+
|
79
|
+
def to_i
|
80
|
+
to_s.to_i
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
class XmlNodeList < Array #:nodoc:
|
85
|
+
def [](i)
|
86
|
+
i.is_a?(String) ? super(0)[i] : super(i)
|
87
|
+
end
|
88
|
+
|
89
|
+
def []=(i, value)
|
90
|
+
i.is_a?(String) ? self[0][i] = value : super(i, value)
|
91
|
+
end
|
92
|
+
|
93
|
+
def method_missing(name, *args)
|
94
|
+
name = name.to_s
|
95
|
+
self[0].__send__(name, *args)
|
96
|
+
end
|
97
|
+
end
|
@@ -47,6 +47,8 @@ module ActionController #:nodoc:
|
|
47
47
|
# must match the current request method in order for the action(s) to
|
48
48
|
# be safely called. (The key should be a symbol: <tt>:get</tt> or
|
49
49
|
# <tt>:post</tt>, for example.)
|
50
|
+
# * <tt>:xhr</tt>: true/false option to ensure that the request is coming
|
51
|
+
# from an Ajax call or not.
|
50
52
|
# * <tt>:add_flash</tt>: a hash of name/value pairs that should be merged
|
51
53
|
# into the session's flash if the prerequisites cannot be satisfied.
|
52
54
|
# * <tt>:redirect_to</tt>: the redirection parameters to be used when
|
data/lib/action_pack/version.rb
CHANGED
data/lib/action_view.rb
CHANGED
data/lib/action_view/base.rb
CHANGED
@@ -5,8 +5,9 @@ module ActionView #:nodoc:
|
|
5
5
|
class ActionViewError < StandardError #:nodoc:
|
6
6
|
end
|
7
7
|
|
8
|
-
# Action View templates can be written in
|
9
|
-
# (included in Ruby) and HTML. If the template file has a +.rxml+ extension then Jim Weirich's Builder::XmlMarkup library is used.
|
8
|
+
# Action View templates can be written in three ways. If the template file has a +.rhtml+ extension then it uses a mixture of ERb
|
9
|
+
# (included in Ruby) and HTML. If the template file has a +.rxml+ extension then Jim Weirich's Builder::XmlMarkup library is used.
|
10
|
+
# If the template file has a +.rjs+ extension then it will use ActionView::Helpers::PrototypeHelper::JavaScriptGenerator.
|
10
11
|
#
|
11
12
|
# = ERb
|
12
13
|
#
|
@@ -73,7 +74,7 @@ module ActionView #:nodoc:
|
|
73
74
|
# xml.em("emphasized") # => <em>emphasized</em>
|
74
75
|
# xml.em { xml.b("emp & bold") } # => <em><b>emph & bold</b></em>
|
75
76
|
# xml.a("A Link", "href"=>"http://onestepback.org") # => <a href="http://onestepback.org">A Link</a>
|
76
|
-
#
|
77
|
+
# xml.target("name"=>"compile", "option"=>"fast") # => <target option="fast" name="compile"\>
|
77
78
|
# # NOTE: order of attributes is not specified.
|
78
79
|
#
|
79
80
|
# Any method with a block will be treated as an XML markup tag with nested markup in the block. For example, the following:
|
@@ -115,6 +116,29 @@ module ActionView #:nodoc:
|
|
115
116
|
# end
|
116
117
|
#
|
117
118
|
# More builder documentation can be found at http://builder.rubyforge.org.
|
119
|
+
#
|
120
|
+
# == JavaScriptGenerator
|
121
|
+
#
|
122
|
+
# JavaScriptGenerator templates end in +.rjs+. Unlike conventional templates which are used to
|
123
|
+
# render the results of an action, these templates generate instructions on how to modify an already rendered page. This makes it easy to
|
124
|
+
# modify multiple elements on your page in one declarative Ajax response. Actions with these templates are called in the background with Ajax
|
125
|
+
# and make updates to the page where the request originated from.
|
126
|
+
#
|
127
|
+
# 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.
|
128
|
+
#
|
129
|
+
# When an .rjs action is called with +link_to_remote+, the generated JavaScript is automatically evaluated. Example:
|
130
|
+
#
|
131
|
+
# link_to_remote :url => {:action => 'delete'}
|
132
|
+
#
|
133
|
+
# The subsequently rendered +delete.rjs+ might look like:
|
134
|
+
#
|
135
|
+
# page.replace_html 'sidebar', :partial => 'sidebar'
|
136
|
+
# page.remove "person-#{@person.id}"
|
137
|
+
# page.visual_effect :highlight, 'user-list'
|
138
|
+
#
|
139
|
+
# This refreshes the sidebar, removes a person element and highlights the user list.
|
140
|
+
#
|
141
|
+
# See the ActionView::Helpers::PrototypeHelper::JavaScriptGenerator documentation for more details.
|
118
142
|
class Base
|
119
143
|
include ERB::Util
|
120
144
|
|
@@ -138,8 +162,13 @@ module ActionView #:nodoc:
|
|
138
162
|
# shortly.
|
139
163
|
@@local_assigns_support_string_keys = true
|
140
164
|
cattr_accessor :local_assigns_support_string_keys
|
165
|
+
|
166
|
+
# Specify whether RJS responses should be wrapped in a try/catch block
|
167
|
+
# that alert()s the caught exception (and then re-raises it).
|
168
|
+
@@debug_rjs = false
|
169
|
+
cattr_accessor :debug_rjs
|
141
170
|
|
142
|
-
@@template_handlers =
|
171
|
+
@@template_handlers = HashWithIndifferentAccess.new
|
143
172
|
|
144
173
|
module CompiledTemplates #:nodoc:
|
145
174
|
# holds compiled template code
|
@@ -153,7 +182,11 @@ module ActionView #:nodoc:
|
|
153
182
|
# map method names to the names passed in local assigns so far
|
154
183
|
@@template_args = {}
|
155
184
|
# count the number of inline templates
|
156
|
-
@@inline_template_count = 0
|
185
|
+
@@inline_template_count = 0
|
186
|
+
# maps template paths without extension to their file extension returned by pick_template_extension.
|
187
|
+
# if for a given path, path.ext1 and path.ext2 exist on the file system, the order of extensions
|
188
|
+
# used by pick_template_extension determines whether ext1 or ext2 will be stored
|
189
|
+
@@cached_template_extension = {}
|
157
190
|
|
158
191
|
class ObjectWrapper < Struct.new(:value) #:nodoc:
|
159
192
|
end
|
@@ -188,12 +221,18 @@ module ActionView #:nodoc:
|
|
188
221
|
# Renders the template present at <tt>template_path</tt>. If <tt>use_full_path</tt> is set to true,
|
189
222
|
# it's relative to the template_root, otherwise it's absolute. The hash in <tt>local_assigns</tt>
|
190
223
|
# is made available as local variables.
|
191
|
-
def render_file(template_path, use_full_path = true, local_assigns = {})
|
192
|
-
@first_render
|
224
|
+
def render_file(template_path, use_full_path = true, local_assigns = {}) #:nodoc:
|
225
|
+
@first_render ||= template_path
|
193
226
|
|
194
227
|
if use_full_path
|
195
|
-
template_extension =
|
196
|
-
|
228
|
+
template_path_without_extension, template_extension = path_and_extension(template_path)
|
229
|
+
|
230
|
+
if template_extension
|
231
|
+
template_file_name = full_template_path(template_path_without_extension, template_extension)
|
232
|
+
else
|
233
|
+
template_extension = pick_template_extension(template_path).to_s
|
234
|
+
template_file_name = full_template_path(template_path, template_extension)
|
235
|
+
end
|
197
236
|
else
|
198
237
|
template_file_name = template_path
|
199
238
|
template_extension = template_path.split('.').last
|
@@ -215,9 +254,11 @@ module ActionView #:nodoc:
|
|
215
254
|
|
216
255
|
# Renders the template present at <tt>template_path</tt> (relative to the template_root).
|
217
256
|
# The hash in <tt>local_assigns</tt> is made available as local variables.
|
218
|
-
def render(options = {}, old_local_assigns = {})
|
257
|
+
def render(options = {}, old_local_assigns = {}, &block) #:nodoc:
|
219
258
|
if options.is_a?(String)
|
220
259
|
render_file(options, true, old_local_assigns)
|
260
|
+
elsif options == :update
|
261
|
+
update_page(&block)
|
221
262
|
elsif options.is_a?(Hash)
|
222
263
|
options[:locals] ||= {}
|
223
264
|
options[:use_full_path] = options[:use_full_path].nil? ? true : options[:use_full_path]
|
@@ -236,7 +277,7 @@ module ActionView #:nodoc:
|
|
236
277
|
|
237
278
|
# Renders the +template+ which is given as a string as either rhtml or rxml depending on <tt>template_extension</tt>.
|
238
279
|
# The hash in <tt>local_assigns</tt> is made available as local variables.
|
239
|
-
def render_template(template_extension, template, file_path = nil, local_assigns = {})
|
280
|
+
def render_template(template_extension, template, file_path = nil, local_assigns = {}) #:nodoc:
|
240
281
|
if handler = @@template_handlers[template_extension]
|
241
282
|
template ||= read_template_file(file_path, template_extension) # Make sure that a lazyily-read template is loaded.
|
242
283
|
delegate_render(handler, template, local_assigns)
|
@@ -252,7 +293,7 @@ module ActionView #:nodoc:
|
|
252
293
|
# Either, but not both, of template and file_path may be nil. If file_path is given, the template
|
253
294
|
# will only be read if it has to be compiled.
|
254
295
|
#
|
255
|
-
def compile_and_render_template(extension, template = nil, file_path = nil, local_assigns = {})
|
296
|
+
def compile_and_render_template(extension, template = nil, file_path = nil, local_assigns = {}) #:nodoc:
|
256
297
|
# compile the given template, if necessary
|
257
298
|
if compile_template?(template, file_path, local_assigns)
|
258
299
|
template ||= read_template_file(file_path, extension)
|
@@ -271,15 +312,15 @@ module ActionView #:nodoc:
|
|
271
312
|
end
|
272
313
|
|
273
314
|
def pick_template_extension(template_path)#:nodoc:
|
274
|
-
|
275
|
-
match
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
|
315
|
+
@@cached_template_extension[template_path] ||=
|
316
|
+
if match = delegate_template_exists?(template_path)
|
317
|
+
match.first.to_sym
|
318
|
+
elsif erb_template_exists?(template_path): :rhtml
|
319
|
+
elsif builder_template_exists?(template_path): :rxml
|
320
|
+
elsif javascript_template_exists?(template_path): :rjs
|
321
|
+
else
|
322
|
+
raise ActionViewError, "No rhtml, rxml, rjs or delegate template found for #{template_path}"
|
323
|
+
end
|
283
324
|
end
|
284
325
|
|
285
326
|
def delegate_template_exists?(template_path)#:nodoc:
|
@@ -293,9 +334,22 @@ module ActionView #:nodoc:
|
|
293
334
|
def builder_template_exists?(template_path)#:nodoc:
|
294
335
|
template_exists?(template_path, :rxml)
|
295
336
|
end
|
337
|
+
|
338
|
+
def javascript_template_exists?(template_path)#:nodoc:
|
339
|
+
template_exists?(template_path, :rjs)
|
340
|
+
end
|
296
341
|
|
297
342
|
def file_exists?(template_path)#:nodoc:
|
298
|
-
|
343
|
+
template_file_name, template_file_extension = path_and_extension(template_path)
|
344
|
+
|
345
|
+
if template_file_extension
|
346
|
+
template_exists?(template_file_name, template_file_extension)
|
347
|
+
else
|
348
|
+
@@cached_template_extension[template_path] ||
|
349
|
+
%w(erb builder javascript delegate).any? do |template_type|
|
350
|
+
send("#{template_type}_template_exists?", template_path)
|
351
|
+
end
|
352
|
+
end
|
299
353
|
end
|
300
354
|
|
301
355
|
# Returns true is the file may be rendered implicitly.
|
@@ -313,6 +367,11 @@ module ActionView #:nodoc:
|
|
313
367
|
@@method_names.has_key?(file_path) || FileTest.exists?(file_path)
|
314
368
|
end
|
315
369
|
|
370
|
+
def path_and_extension(template_path)
|
371
|
+
template_path_without_extension = template_path.sub(/\.(\w+)$/, '')
|
372
|
+
[ template_path_without_extension, $1 ]
|
373
|
+
end
|
374
|
+
|
316
375
|
# This method reads a template file.
|
317
376
|
def read_template_file(template_path, extension)
|
318
377
|
File.read(template_path)
|
@@ -345,7 +404,7 @@ module ActionView #:nodoc:
|
|
345
404
|
# Or if local_assigns has a new key, which isn't supported by the compiled code yet.
|
346
405
|
# Or if the file has changed on disk and checking file mods hasn't been disabled.
|
347
406
|
def compile_template?(template, file_name, local_assigns)
|
348
|
-
method_key
|
407
|
+
method_key = file_name || template
|
349
408
|
render_symbol = @@method_names[method_key]
|
350
409
|
|
351
410
|
if @@compile_time[render_symbol] && supports_local_assigns?(render_symbol, local_assigns)
|
@@ -359,10 +418,16 @@ module ActionView #:nodoc:
|
|
359
418
|
|
360
419
|
# Create source code for given template
|
361
420
|
def create_template_source(extension, template, render_symbol, locals)
|
362
|
-
if
|
363
|
-
body =
|
364
|
-
|
365
|
-
|
421
|
+
if template_requires_setup?(extension)
|
422
|
+
body = case extension.to_sym
|
423
|
+
when :rxml
|
424
|
+
"xml = Builder::XmlMarkup.new(:indent => 2)\n" +
|
425
|
+
"@controller.headers['Content-Type'] ||= 'application/xml'\n" +
|
426
|
+
template
|
427
|
+
when :rjs
|
428
|
+
"@controller.headers['Content-Type'] ||= 'text/javascript'\n" +
|
429
|
+
"update_page do |page|\n#{template}\nend"
|
430
|
+
end
|
366
431
|
else
|
367
432
|
body = ERB.new(template, nil, @@erb_trim_mode).src
|
368
433
|
end
|
@@ -379,14 +444,17 @@ module ActionView #:nodoc:
|
|
379
444
|
"def #{render_symbol}(local_assigns)\n#{locals_code}#{body}\nend"
|
380
445
|
end
|
381
446
|
|
447
|
+
def template_requires_setup?(extension)
|
448
|
+
templates_requiring_setup.include? extension.to_s
|
449
|
+
end
|
450
|
+
|
451
|
+
def templates_requiring_setup
|
452
|
+
%w(rxml rjs)
|
453
|
+
end
|
454
|
+
|
382
455
|
def assign_method_name(extension, template, file_name)
|
383
456
|
method_name = '_run_'
|
384
|
-
|
385
|
-
if extension && (extension.to_sym == :rxml)
|
386
|
-
method_name << 'xml_'
|
387
|
-
else
|
388
|
-
method_name << 'html_'
|
389
|
-
end
|
457
|
+
method_name << "#{extension}_" if extension
|
390
458
|
|
391
459
|
if file_name
|
392
460
|
file_path = File.expand_path(file_name)
|
@@ -396,7 +464,7 @@ module ActionView #:nodoc:
|
|
396
464
|
l = base_path.length
|
397
465
|
|
398
466
|
method_name_file_part = i ? file_path[i+l+1,file_path.length-l-1] : file_path.clone
|
399
|
-
method_name_file_part.sub!(/\.r(
|
467
|
+
method_name_file_part.sub!(/\.r(html|xml|js)$/,'')
|
400
468
|
method_name_file_part.tr!('/:-', '_')
|
401
469
|
method_name_file_part.gsub!(/[^a-zA-Z0-9_]/){|s| s[0].to_s}
|
402
470
|
|
@@ -416,8 +484,13 @@ module ActionView #:nodoc:
|
|
416
484
|
render_source = create_template_source(extension, template, render_symbol, local_assigns.keys)
|
417
485
|
|
418
486
|
line_offset = @@template_args[render_symbol].size
|
419
|
-
|
420
|
-
|
487
|
+
if extension
|
488
|
+
case extension.to_sym
|
489
|
+
when :rxml, :rjs
|
490
|
+
line_offset += 2
|
491
|
+
end
|
492
|
+
end
|
493
|
+
|
421
494
|
begin
|
422
495
|
unless file_name.blank?
|
423
496
|
CompiledTemplates.module_eval(render_source, file_name, -line_offset)
|