actionpack 2.0.1 → 2.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of actionpack might be problematic. Click here for more details.
- data/CHANGELOG +59 -26
- data/Rakefile +1 -1
- data/lib/action_controller/base.rb +6 -16
- data/lib/action_controller/benchmarking.rb +5 -4
- data/lib/action_controller/caching.rb +2 -2
- data/lib/action_controller/cgi_ext/cookie.rb +1 -5
- data/lib/action_controller/cookies.rb +3 -3
- data/lib/action_controller/dispatcher.rb +1 -1
- data/lib/action_controller/helpers.rb +2 -3
- data/lib/action_controller/integration.rb +29 -14
- data/lib/action_controller/layout.rb +2 -1
- data/lib/action_controller/request.rb +1 -1
- data/lib/action_controller/request_forgery_protection.rb +7 -1
- data/lib/action_controller/rescue.rb +1 -1
- data/lib/action_controller/routing.rb +12 -9
- data/lib/action_controller/session/cookie_store.rb +3 -0
- data/lib/action_pack/version.rb +1 -1
- data/lib/action_view.rb +6 -0
- data/lib/action_view/base.rb +83 -140
- data/lib/action_view/helpers/asset_tag_helper.rb +68 -46
- data/lib/action_view/helpers/text_helper.rb +2 -2
- data/lib/action_view/template_handler.rb +17 -0
- data/lib/action_view/template_handlers/builder.rb +19 -0
- data/lib/action_view/template_handlers/erb.rb +21 -0
- data/lib/action_view/template_handlers/rjs.rb +14 -0
- data/test/action_view_test.rb +18 -0
- data/test/controller/cgi_test.rb +4 -4
- data/test/controller/cookie_test.rb +1 -1
- data/test/controller/filters_test.rb +1 -0
- data/test/controller/helper_test.rb +8 -6
- data/test/controller/integration_test.rb +41 -11
- data/test/controller/new_render_test.rb +2 -2
- data/test/controller/render_test.rb +31 -10
- data/test/controller/request_test.rb +2 -1
- data/test/controller/routing_test.rb +9 -3
- data/test/fixtures/test/{hello_world.builder → hello_world_from_rxml.builder} +0 -0
- data/test/template/asset_tag_helper_test.rb +45 -12
- data/test/template/compiled_templates_test.rb +14 -12
- data/test/template/erb_util_test.rb +56 -0
- metadata +56 -43
@@ -124,7 +124,8 @@ module ActionController #:nodoc:
|
|
124
124
|
# class WeblogController < ActionController::Base
|
125
125
|
# layout "weblog_standard"
|
126
126
|
#
|
127
|
-
# If no directory is specified for the template name, the template will by default
|
127
|
+
# If no directory is specified for the template name, the template will by default be looked for in +app/views/layouts/+.
|
128
|
+
# Otherwise, it will be looked up relative to the template root.
|
128
129
|
#
|
129
130
|
# == Conditional layouts
|
130
131
|
#
|
@@ -4,7 +4,7 @@ require 'strscan'
|
|
4
4
|
|
5
5
|
module ActionController
|
6
6
|
# HTTP methods which are accepted by default.
|
7
|
-
ACCEPTED_HTTP_METHODS = Set.new(%w( get head put post delete ))
|
7
|
+
ACCEPTED_HTTP_METHODS = Set.new(%w( get head put post delete options ))
|
8
8
|
|
9
9
|
# CgiRequest and TestRequest provide concrete implementations.
|
10
10
|
class AbstractRequest
|
@@ -54,6 +54,12 @@ module ActionController #:nodoc:
|
|
54
54
|
# skip_before_filter :verify_authenticity_token
|
55
55
|
# end
|
56
56
|
#
|
57
|
+
# If you are upgrading from Rails 1.x, disable forgery protection to
|
58
|
+
# simplify your tests. Add this to config/environments/test.rb:
|
59
|
+
#
|
60
|
+
# # Disable request forgery protection in test environment
|
61
|
+
# config.action_controller.allow_forgery_protection = false
|
62
|
+
#
|
57
63
|
# Valid Options:
|
58
64
|
#
|
59
65
|
# * <tt>:only/:except</tt> - passed to the before_filter call. Set which actions are verified.
|
@@ -123,4 +129,4 @@ module ActionController #:nodoc:
|
|
123
129
|
allow_forgery_protection && request_forgery_protection_token
|
124
130
|
end
|
125
131
|
end
|
126
|
-
end
|
132
|
+
end
|
@@ -154,7 +154,7 @@ module ActionController #:nodoc:
|
|
154
154
|
def render_optional_error_file(status_code)
|
155
155
|
status = interpret_status(status_code)
|
156
156
|
path = "#{RAILS_ROOT}/public/#{status[0,3]}.html"
|
157
|
-
if File.
|
157
|
+
if File.exist?(path)
|
158
158
|
render :file => path, :status => status
|
159
159
|
else
|
160
160
|
head status
|
@@ -268,6 +268,10 @@ module ActionController
|
|
268
268
|
# #...
|
269
269
|
# end
|
270
270
|
#
|
271
|
+
# == View a list of all your routes
|
272
|
+
#
|
273
|
+
# Run <tt>rake routes</tt>.
|
274
|
+
#
|
271
275
|
module Routing
|
272
276
|
SEPARATORS = %w( / . ? )
|
273
277
|
|
@@ -1044,19 +1048,19 @@ module ActionController
|
|
1044
1048
|
end
|
1045
1049
|
end
|
1046
1050
|
|
1047
|
-
class RouteSet #:nodoc:
|
1051
|
+
class RouteSet #:nodoc:
|
1048
1052
|
# Mapper instances are used to build routes. The object passed to the draw
|
1049
1053
|
# block in config/routes.rb is a Mapper instance.
|
1050
1054
|
#
|
1051
1055
|
# Mapper instances have relatively few instance methods, in order to avoid
|
1052
1056
|
# clashes with named routes.
|
1053
|
-
class Mapper #:
|
1054
|
-
def initialize(set)
|
1057
|
+
class Mapper #:doc:
|
1058
|
+
def initialize(set) #:nodoc:
|
1055
1059
|
@set = set
|
1056
1060
|
end
|
1057
1061
|
|
1058
1062
|
# Create an unnamed route with the provided +path+ and +options+. See
|
1059
|
-
#
|
1063
|
+
# ActionController::Routing for an introduction to routes.
|
1060
1064
|
def connect(path, options = {})
|
1061
1065
|
@set.add_route(path, options)
|
1062
1066
|
end
|
@@ -1066,7 +1070,7 @@ module ActionController
|
|
1066
1070
|
named_route("root", '', options)
|
1067
1071
|
end
|
1068
1072
|
|
1069
|
-
def named_route(name, path, options = {})
|
1073
|
+
def named_route(name, path, options = {}) #:nodoc:
|
1070
1074
|
@set.add_named_route(name, path, options)
|
1071
1075
|
end
|
1072
1076
|
|
@@ -1078,8 +1082,8 @@ module ActionController
|
|
1078
1082
|
# :has_many => [ :tags, :images, :variants ]
|
1079
1083
|
# end
|
1080
1084
|
#
|
1081
|
-
# This will create admin_products_url pointing to "admin/products", which will look for an Admin::ProductsController.
|
1082
|
-
# It'll also create admin_product_tags_url pointing to "admin/products/#{product_id}/tags", which will look for
|
1085
|
+
# This will create +admin_products_url+ pointing to "admin/products", which will look for an Admin::ProductsController.
|
1086
|
+
# It'll also create +admin_product_tags_url+ pointing to "admin/products/#{product_id}/tags", which will look for
|
1083
1087
|
# Admin::TagsController.
|
1084
1088
|
def namespace(name, options = {}, &block)
|
1085
1089
|
if options[:namespace]
|
@@ -1089,8 +1093,7 @@ module ActionController
|
|
1089
1093
|
end
|
1090
1094
|
end
|
1091
1095
|
|
1092
|
-
|
1093
|
-
def method_missing(route_name, *args, &proc)
|
1096
|
+
def method_missing(route_name, *args, &proc) #:nodoc:
|
1094
1097
|
super unless args.length >= 1 && proc.nil?
|
1095
1098
|
@set.add_named_route(route_name, *args)
|
1096
1099
|
end
|
@@ -34,6 +34,9 @@ require 'openssl' # to generate the HMAC message digest
|
|
34
34
|
# defaults to 'SHA1' but may be any digest provided by OpenSSL,
|
35
35
|
# such as 'MD5', 'RIPEMD160', 'SHA256', etc.
|
36
36
|
#
|
37
|
+
# To generate a secret key for an existing application, run
|
38
|
+
# `rake secret` and set the key in config/environment.rb
|
39
|
+
#
|
37
40
|
# Note that changing digest or secret invalidates all existing sessions!
|
38
41
|
class CGI::Session::CookieStore
|
39
42
|
# Cookies can typically store 4096 bytes.
|
data/lib/action_pack/version.rb
CHANGED
data/lib/action_view.rb
CHANGED
@@ -21,8 +21,14 @@
|
|
21
21
|
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
22
22
|
#++
|
23
23
|
|
24
|
+
require 'action_view/template_handler'
|
25
|
+
require 'action_view/template_handlers/builder'
|
26
|
+
require 'action_view/template_handlers/erb'
|
27
|
+
require 'action_view/template_handlers/rjs'
|
28
|
+
|
24
29
|
require 'action_view/base'
|
25
30
|
require 'action_view/partials'
|
31
|
+
require 'action_view/template_error'
|
26
32
|
|
27
33
|
ActionView::Base.class_eval do
|
28
34
|
include ActionView::Partials
|
data/lib/action_view/base.rb
CHANGED
@@ -1,16 +1,3 @@
|
|
1
|
-
require 'erb'
|
2
|
-
require 'builder'
|
3
|
-
|
4
|
-
class ERB
|
5
|
-
module Util
|
6
|
-
HTML_ESCAPE = { '&' => '&', '"' => '"', '>' => '>', '<' => '<' }
|
7
|
-
|
8
|
-
def html_escape(s)
|
9
|
-
s.to_s.gsub(/[&\"><]/) { |special| HTML_ESCAPE[special] }
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
13
|
-
|
14
1
|
module ActionView #:nodoc:
|
15
2
|
class ActionViewError < StandardError #:nodoc:
|
16
3
|
end
|
@@ -228,15 +215,8 @@ module ActionView #:nodoc:
|
|
228
215
|
cattr_reader :computed_public_paths
|
229
216
|
@@computed_public_paths = {}
|
230
217
|
|
231
|
-
@@
|
232
|
-
|
233
|
-
# Order of template handers checked by #file_exists? depending on the current #template_format
|
234
|
-
DEFAULT_TEMPLATE_HANDLER_PREFERENCE = [:erb, :rhtml, :builder, :rxml, :javascript, :delegate]
|
235
|
-
TEMPLATE_HANDLER_PREFERENCES = {
|
236
|
-
:js => [:javascript, :erb, :rhtml, :builder, :rxml, :delegate],
|
237
|
-
:xml => [:builder, :rxml, :erb, :rhtml, :javascript, :delegate],
|
238
|
-
:delegate => [:delegate]
|
239
|
-
}
|
218
|
+
@@template_handlers = {}
|
219
|
+
@@default_template_handlers = nil
|
240
220
|
|
241
221
|
class ObjectWrapper < Struct.new(:value) #:nodoc:
|
242
222
|
end
|
@@ -260,10 +240,30 @@ module ActionView #:nodoc:
|
|
260
240
|
# local assigns available to the template. The #render method ought to
|
261
241
|
# return the rendered template as a string.
|
262
242
|
def self.register_template_handler(extension, klass)
|
263
|
-
|
264
|
-
|
243
|
+
@@template_handlers[extension.to_sym] = klass
|
244
|
+
end
|
245
|
+
|
246
|
+
def self.template_handler_extensions
|
247
|
+
@@template_handler_extensions ||= @@template_handlers.keys.map(&:to_s).sort
|
248
|
+
end
|
249
|
+
|
250
|
+
def self.register_default_template_handler(extension, klass)
|
251
|
+
register_template_handler(extension, klass)
|
252
|
+
@@default_template_handlers = klass
|
253
|
+
end
|
254
|
+
|
255
|
+
def self.handler_for_extension(extension)
|
256
|
+
(extension && @@template_handlers[extension.to_sym]) || @@default_template_handlers
|
265
257
|
end
|
266
258
|
|
259
|
+
register_default_template_handler :erb, TemplateHandlers::ERB
|
260
|
+
register_template_handler :rjs, TemplateHandlers::RJS
|
261
|
+
register_template_handler :builder, TemplateHandlers::Builder
|
262
|
+
|
263
|
+
# TODO: Depreciate old template extensions
|
264
|
+
register_template_handler :rhtml, TemplateHandlers::ERB
|
265
|
+
register_template_handler :rxml, TemplateHandlers::Builder
|
266
|
+
|
267
267
|
def initialize(view_paths = [], assigns_for_first_render = {}, controller = nil)#:nodoc:
|
268
268
|
@view_paths = view_paths.respond_to?(:find) ? view_paths.dup : [*view_paths].compact
|
269
269
|
@assigns = assigns_for_first_render
|
@@ -297,7 +297,7 @@ If you are rendering a subtemplate, you must now use controller-like partial syn
|
|
297
297
|
else
|
298
298
|
template_extension = pick_template_extension(template_path).to_s
|
299
299
|
unless template_extension
|
300
|
-
raise ActionViewError, "No
|
300
|
+
raise ActionViewError, "No template found for #{template_path} in #{view_paths.inspect}"
|
301
301
|
end
|
302
302
|
template_file_name = full_template_path(template_path, template_extension)
|
303
303
|
template_extension = template_extension.gsub(/^.+\./, '') # strip off any formats
|
@@ -332,7 +332,7 @@ If you are rendering a subtemplate, you must now use controller-like partial syn
|
|
332
332
|
elsif options == :update
|
333
333
|
update_page(&block)
|
334
334
|
elsif options.is_a?(Hash)
|
335
|
-
options = options.reverse_merge(:
|
335
|
+
options = options.reverse_merge(:locals => {}, :use_full_path => true)
|
336
336
|
|
337
337
|
if options[:layout]
|
338
338
|
path, partial_name = partial_pieces(options.delete(:layout))
|
@@ -359,36 +359,13 @@ If you are rendering a subtemplate, you must now use controller-like partial syn
|
|
359
359
|
# Renders the +template+ which is given as a string as either erb or builder depending on <tt>template_extension</tt>.
|
360
360
|
# The hash in <tt>local_assigns</tt> is made available as local variables.
|
361
361
|
def render_template(template_extension, template, file_path = nil, local_assigns = {}) #:nodoc:
|
362
|
-
|
362
|
+
handler = self.class.handler_for_extension(template_extension)
|
363
|
+
|
364
|
+
if template_handler_is_compilable?(handler)
|
365
|
+
compile_and_render_template(handler, template, file_path, local_assigns)
|
366
|
+
else
|
363
367
|
template ||= read_template_file(file_path, template_extension) # Make sure that a lazyily-read template is loaded.
|
364
368
|
delegate_render(handler, template, local_assigns)
|
365
|
-
else
|
366
|
-
compile_and_render_template(template_extension, template, file_path, local_assigns)
|
367
|
-
end
|
368
|
-
end
|
369
|
-
|
370
|
-
# Render the provided template with the given local assigns. If the template has not been rendered with the provided
|
371
|
-
# local assigns yet, or if the template has been updated on disk, then the template will be compiled to a method.
|
372
|
-
#
|
373
|
-
# Either, but not both, of template and file_path may be nil. If file_path is given, the template
|
374
|
-
# will only be read if it has to be compiled.
|
375
|
-
#
|
376
|
-
def compile_and_render_template(extension, template = nil, file_path = nil, local_assigns = {}) #:nodoc:
|
377
|
-
# convert string keys to symbols if requested
|
378
|
-
local_assigns = local_assigns.symbolize_keys if @@local_assigns_support_string_keys
|
379
|
-
|
380
|
-
# compile the given template, if necessary
|
381
|
-
if compile_template?(template, file_path, local_assigns)
|
382
|
-
template ||= read_template_file(file_path, extension)
|
383
|
-
compile_template(extension, template, file_path, local_assigns)
|
384
|
-
end
|
385
|
-
|
386
|
-
# Get the method name for this template and run it
|
387
|
-
method_name = @@method_names[file_path || template]
|
388
|
-
evaluate_assigns
|
389
|
-
|
390
|
-
send(method_name, local_assigns) do |*name|
|
391
|
-
instance_variable_get "@content_for_#{name.first || 'layout'}"
|
392
369
|
end
|
393
370
|
end
|
394
371
|
|
@@ -422,37 +399,12 @@ If you are rendering a subtemplate, you must now use controller-like partial syn
|
|
422
399
|
end
|
423
400
|
end
|
424
401
|
|
425
|
-
def delegate_template_exists?(template_path)#:nodoc:
|
426
|
-
delegate = @@template_handlers.find { |k,| template_exists?(template_path, k) }
|
427
|
-
delegate && delegate.first.to_sym
|
428
|
-
end
|
429
|
-
|
430
|
-
def erb_template_exists?(template_path)#:nodoc:
|
431
|
-
template_exists?(template_path, :erb)
|
432
|
-
end
|
433
|
-
|
434
|
-
def builder_template_exists?(template_path)#:nodoc:
|
435
|
-
template_exists?(template_path, :builder)
|
436
|
-
end
|
437
|
-
|
438
|
-
def rhtml_template_exists?(template_path)#:nodoc:
|
439
|
-
template_exists?(template_path, :rhtml)
|
440
|
-
end
|
441
|
-
|
442
|
-
def rxml_template_exists?(template_path)#:nodoc:
|
443
|
-
template_exists?(template_path, :rxml)
|
444
|
-
end
|
445
|
-
|
446
|
-
def javascript_template_exists?(template_path)#:nodoc:
|
447
|
-
template_exists?(template_path, :rjs)
|
448
|
-
end
|
449
|
-
|
450
402
|
def file_exists?(template_path)#:nodoc:
|
451
403
|
template_file_name, template_file_extension = path_and_extension(template_path)
|
452
404
|
if template_file_extension
|
453
405
|
template_exists?(template_file_name, template_file_extension)
|
454
406
|
else
|
455
|
-
pick_template_extension(template_path)
|
407
|
+
template_exists?(template_file_name, pick_template_extension(template_path))
|
456
408
|
end
|
457
409
|
end
|
458
410
|
|
@@ -468,10 +420,6 @@ If you are rendering a subtemplate, you must now use controller-like partial syn
|
|
468
420
|
@template_format = format.blank? ? :html : format.to_sym
|
469
421
|
end
|
470
422
|
|
471
|
-
def template_handler_preferences
|
472
|
-
TEMPLATE_HANDLER_PREFERENCES[template_format] || DEFAULT_TEMPLATE_HANDLER_PREFERENCE
|
473
|
-
end
|
474
|
-
|
475
423
|
# Adds a view_path to the front of the view_paths array.
|
476
424
|
# This change affects the current request only.
|
477
425
|
#
|
@@ -502,7 +450,7 @@ If you are rendering a subtemplate, you must now use controller-like partial syn
|
|
502
450
|
# Asserts the existence of a template.
|
503
451
|
def template_exists?(template_path, extension)
|
504
452
|
file_path = full_template_path(template_path, extension)
|
505
|
-
!file_path.blank? && @@method_names.has_key?(file_path) ||
|
453
|
+
!file_path.blank? && @@method_names.has_key?(file_path) || File.exist?(file_path)
|
506
454
|
end
|
507
455
|
|
508
456
|
# Splits the path and extension from the given template_path and returns as an array.
|
@@ -530,17 +478,9 @@ If you are rendering a subtemplate, you must now use controller-like partial syn
|
|
530
478
|
|
531
479
|
def find_template_extension_from_handler(template_path, formatted = nil)
|
532
480
|
checked_template_path = formatted ? "#{template_path}.#{template_format}" : template_path
|
533
|
-
|
534
|
-
|
535
|
-
|
536
|
-
when :javascript
|
537
|
-
template_exists?(checked_template_path, :rjs) && :rjs
|
538
|
-
when :delegate
|
539
|
-
delegate_template_exists?(checked_template_path)
|
540
|
-
else
|
541
|
-
template_exists?(checked_template_path, template_type) && template_type
|
542
|
-
end
|
543
|
-
if extension
|
481
|
+
|
482
|
+
self.class.template_handler_extensions.each do |extension|
|
483
|
+
if template_exists?(checked_template_path, extension)
|
544
484
|
return formatted ? "#{template_format}.#{extension}" : extension.to_s
|
545
485
|
end
|
546
486
|
end
|
@@ -569,6 +509,14 @@ If you are rendering a subtemplate, you must now use controller-like partial syn
|
|
569
509
|
handler.new(self).render(template, local_assigns)
|
570
510
|
end
|
571
511
|
|
512
|
+
def delegate_compile(handler, template)
|
513
|
+
handler.new(self).compile(template)
|
514
|
+
end
|
515
|
+
|
516
|
+
def template_handler_is_compilable?(handler)
|
517
|
+
handler.new(self).respond_to?(:compile)
|
518
|
+
end
|
519
|
+
|
572
520
|
# Assigns instance variables from the controller to the view.
|
573
521
|
def assign_variables_from_controller
|
574
522
|
@assigns.each { |key, value| instance_variable_set("@#{key}", value) }
|
@@ -608,22 +556,8 @@ If you are rendering a subtemplate, you must now use controller-like partial syn
|
|
608
556
|
end
|
609
557
|
|
610
558
|
# Method to create the source code for a given template.
|
611
|
-
def create_template_source(
|
612
|
-
|
613
|
-
body = case extension.to_sym
|
614
|
-
when :rxml, :builder
|
615
|
-
content_type_handler = (controller.respond_to?(:response) ? "controller.response" : "controller")
|
616
|
-
"#{content_type_handler}.content_type ||= Mime::XML\n" +
|
617
|
-
"xml = Builder::XmlMarkup.new(:indent => 2)\n" +
|
618
|
-
template +
|
619
|
-
"\nxml.target!\n"
|
620
|
-
when :rjs
|
621
|
-
"controller.response.content_type ||= Mime::JS\n" +
|
622
|
-
"update_page do |page|\n#{template}\nend"
|
623
|
-
end
|
624
|
-
else
|
625
|
-
body = ERB.new(template, nil, @@erb_trim_mode).src
|
626
|
-
end
|
559
|
+
def create_template_source(handler, template, render_symbol, locals)
|
560
|
+
body = delegate_compile(handler, template)
|
627
561
|
|
628
562
|
@@template_args[render_symbol] ||= {}
|
629
563
|
locals_keys = @@template_args[render_symbol].keys | locals
|
@@ -637,24 +571,20 @@ If you are rendering a subtemplate, you must now use controller-like partial syn
|
|
637
571
|
"def #{render_symbol}(local_assigns)\n#{locals_code}#{body}\nend"
|
638
572
|
end
|
639
573
|
|
640
|
-
def
|
641
|
-
@@templates_requiring_setup.include? extension.to_s
|
642
|
-
end
|
643
|
-
|
644
|
-
def assign_method_name(extension, template, file_name)
|
574
|
+
def assign_method_name(handler, template, file_name)
|
645
575
|
method_key = file_name || template
|
646
|
-
@@method_names[method_key] ||= compiled_method_name(
|
576
|
+
@@method_names[method_key] ||= compiled_method_name(handler, template, file_name)
|
647
577
|
end
|
648
578
|
|
649
|
-
def compiled_method_name(
|
650
|
-
['_run',
|
579
|
+
def compiled_method_name(handler, template, file_name)
|
580
|
+
['_run', handler.to_s.demodulize.underscore, compiled_method_name_file_path_segment(file_name)].compact.join('_').to_sym
|
651
581
|
end
|
652
582
|
|
653
583
|
def compiled_method_name_file_path_segment(file_name)
|
654
584
|
if file_name
|
655
585
|
s = File.expand_path(file_name)
|
656
586
|
s.sub!(/^#{Regexp.escape(File.expand_path(RAILS_ROOT))}/, '') if defined?(RAILS_ROOT)
|
657
|
-
s.gsub!(/([^a-zA-Z0-9_])/) { $1
|
587
|
+
s.gsub!(/([^a-zA-Z0-9_])/) { $1.ord }
|
658
588
|
s
|
659
589
|
else
|
660
590
|
(@@inline_template_count += 1).to_s
|
@@ -662,24 +592,14 @@ If you are rendering a subtemplate, you must now use controller-like partial syn
|
|
662
592
|
end
|
663
593
|
|
664
594
|
# Compile and evaluate the template's code
|
665
|
-
def compile_template(
|
666
|
-
render_symbol = assign_method_name(
|
667
|
-
render_source = create_template_source(
|
668
|
-
|
669
|
-
|
670
|
-
if extension
|
671
|
-
case extension.to_sym
|
672
|
-
when :builder, :rxml, :rjs
|
673
|
-
line_offset += 2
|
674
|
-
end
|
675
|
-
end
|
676
|
-
|
595
|
+
def compile_template(handler, template, file_name, local_assigns)
|
596
|
+
render_symbol = assign_method_name(handler, template, file_name)
|
597
|
+
render_source = create_template_source(handler, template, render_symbol, local_assigns.keys)
|
598
|
+
line_offset = @@template_args[render_symbol].size + handler.line_offset
|
599
|
+
|
677
600
|
begin
|
678
|
-
|
679
|
-
|
680
|
-
else
|
681
|
-
CompiledTemplates.module_eval(render_source, 'compiled-template', -line_offset)
|
682
|
-
end
|
601
|
+
file_name = 'compiled-template' if file_name.blank?
|
602
|
+
CompiledTemplates.module_eval(render_source, file_name, -line_offset)
|
683
603
|
rescue Exception => e # errors from template code
|
684
604
|
if logger
|
685
605
|
logger.debug "ERROR: compiling #{render_symbol} RAISED #{e}"
|
@@ -693,7 +613,30 @@ If you are rendering a subtemplate, you must now use controller-like partial syn
|
|
693
613
|
@@compile_time[render_symbol] = Time.now
|
694
614
|
# logger.debug "Compiled template #{file_name || template}\n ==> #{render_symbol}" if logger
|
695
615
|
end
|
616
|
+
|
617
|
+
# Render the provided template with the given local assigns. If the template has not been rendered with the provided
|
618
|
+
# local assigns yet, or if the template has been updated on disk, then the template will be compiled to a method.
|
619
|
+
#
|
620
|
+
# Either, but not both, of template and file_path may be nil. If file_path is given, the template
|
621
|
+
# will only be read if it has to be compiled.
|
622
|
+
#
|
623
|
+
def compile_and_render_template(handler, template = nil, file_path = nil, local_assigns = {}) #:nodoc:
|
624
|
+
# convert string keys to symbols if requested
|
625
|
+
local_assigns = local_assigns.symbolize_keys if @@local_assigns_support_string_keys
|
626
|
+
|
627
|
+
# compile the given template, if necessary
|
628
|
+
if compile_template?(template, file_path, local_assigns)
|
629
|
+
template ||= read_template_file(file_path, nil)
|
630
|
+
compile_template(handler, template, file_path, local_assigns)
|
631
|
+
end
|
632
|
+
|
633
|
+
# Get the method name for this template and run it
|
634
|
+
method_name = @@method_names[file_path || template]
|
635
|
+
evaluate_assigns
|
636
|
+
|
637
|
+
send(method_name, local_assigns) do |*name|
|
638
|
+
instance_variable_get "@content_for_#{name.first || 'layout'}"
|
639
|
+
end
|
640
|
+
end
|
696
641
|
end
|
697
642
|
end
|
698
|
-
|
699
|
-
require 'action_view/template_error'
|