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.

Files changed (200) hide show
  1. data/CHANGELOG +223 -7
  2. data/README +6 -12
  3. data/Rakefile +11 -11
  4. data/lib/action_controller.rb +9 -9
  5. data/lib/action_controller/assertions/response_assertions.rb +29 -78
  6. data/lib/action_controller/assertions/routing_assertions.rb +33 -33
  7. data/lib/action_controller/assertions/selector_assertions.rb +9 -5
  8. data/lib/action_controller/base.rb +227 -161
  9. data/lib/action_controller/benchmarking.rb +37 -24
  10. data/lib/action_controller/caching/actions.rb +53 -21
  11. data/lib/action_controller/caching/fragments.rb +10 -36
  12. data/lib/action_controller/caching/sweeping.rb +3 -3
  13. data/lib/action_controller/cgi_ext/session.rb +2 -22
  14. data/lib/action_controller/cgi_process.rb +8 -46
  15. data/lib/action_controller/components.rb +4 -1
  16. data/lib/action_controller/cookies.rb +10 -0
  17. data/lib/action_controller/dispatcher.rb +49 -15
  18. data/lib/action_controller/filters.rb +48 -10
  19. data/lib/action_controller/headers.rb +16 -14
  20. data/lib/action_controller/helpers.rb +2 -2
  21. data/lib/action_controller/http_authentication.rb +1 -1
  22. data/lib/action_controller/integration.rb +57 -60
  23. data/lib/action_controller/layout.rb +27 -53
  24. data/lib/action_controller/mime_responds.rb +5 -1
  25. data/lib/action_controller/mime_type.rb +64 -42
  26. data/lib/action_controller/mime_types.rb +2 -1
  27. data/lib/action_controller/performance_test.rb +16 -0
  28. data/lib/action_controller/polymorphic_routes.rb +16 -9
  29. data/lib/action_controller/rack_process.rb +303 -0
  30. data/lib/action_controller/request.rb +205 -97
  31. data/lib/action_controller/request_forgery_protection.rb +2 -2
  32. data/lib/action_controller/request_profiler.rb +0 -0
  33. data/lib/action_controller/rescue.rb +20 -115
  34. data/lib/action_controller/resources.rb +186 -83
  35. data/lib/action_controller/response.rb +140 -26
  36. data/lib/action_controller/routing.rb +28 -30
  37. data/lib/action_controller/routing/builder.rb +45 -54
  38. data/lib/action_controller/routing/optimisations.rb +31 -21
  39. data/lib/action_controller/routing/recognition_optimisation.rb +33 -27
  40. data/lib/action_controller/routing/route.rb +162 -147
  41. data/lib/action_controller/routing/route_set.rb +8 -7
  42. data/lib/action_controller/routing/routing_ext.rb +4 -1
  43. data/lib/action_controller/routing/segments.rb +50 -21
  44. data/lib/action_controller/session/cookie_store.rb +3 -2
  45. data/lib/action_controller/session/drb_server.rb +7 -7
  46. data/lib/action_controller/session_management.rb +6 -2
  47. data/lib/action_controller/streaming.rb +15 -8
  48. data/lib/action_controller/templates/rescues/diagnostics.erb +2 -2
  49. data/lib/action_controller/templates/rescues/template_error.erb +2 -2
  50. data/lib/action_controller/test_case.rb +66 -2
  51. data/lib/action_controller/test_process.rb +71 -66
  52. data/lib/action_controller/translation.rb +13 -0
  53. data/lib/action_controller/url_rewriter.rb +90 -13
  54. data/lib/action_controller/vendor/html-scanner/html/node.rb +9 -2
  55. data/lib/action_controller/vendor/html-scanner/html/sanitizer.rb +1 -1
  56. data/lib/action_controller/vendor/html-scanner/html/selector.rb +2 -2
  57. data/lib/action_controller/verification.rb +2 -2
  58. data/lib/action_pack/version.rb +1 -1
  59. data/lib/action_view.rb +19 -11
  60. data/lib/action_view/base.rb +184 -150
  61. data/lib/action_view/helpers.rb +38 -0
  62. data/lib/action_view/helpers/active_record_helper.rb +56 -27
  63. data/lib/action_view/helpers/asset_tag_helper.rb +356 -153
  64. data/lib/action_view/helpers/atom_feed_helper.rb +74 -19
  65. data/lib/action_view/helpers/benchmark_helper.rb +3 -3
  66. data/lib/action_view/helpers/cache_helper.rb +1 -2
  67. data/lib/action_view/helpers/capture_helper.rb +19 -44
  68. data/lib/action_view/helpers/date_helper.rb +486 -296
  69. data/lib/action_view/helpers/debug_helper.rb +20 -13
  70. data/lib/action_view/helpers/form_helper.rb +71 -30
  71. data/lib/action_view/helpers/form_options_helper.rb +15 -85
  72. data/lib/action_view/helpers/form_tag_helper.rb +61 -38
  73. data/lib/action_view/helpers/javascript_helper.rb +80 -89
  74. data/lib/action_view/helpers/number_helper.rb +179 -74
  75. data/lib/action_view/helpers/prototype_helper.rb +216 -201
  76. data/lib/action_view/helpers/record_tag_helper.rb +4 -5
  77. data/lib/action_view/helpers/sanitize_helper.rb +65 -33
  78. data/lib/action_view/helpers/scriptaculous_helper.rb +2 -2
  79. data/lib/action_view/helpers/tag_helper.rb +39 -22
  80. data/lib/action_view/helpers/text_helper.rb +212 -118
  81. data/lib/action_view/helpers/translation_helper.rb +21 -0
  82. data/lib/action_view/helpers/url_helper.rb +100 -58
  83. data/lib/action_view/inline_template.rb +13 -14
  84. data/lib/action_view/locale/en.yml +91 -0
  85. data/lib/action_view/partials.rb +100 -55
  86. data/lib/action_view/paths.rb +125 -0
  87. data/lib/action_view/renderable.rb +102 -0
  88. data/lib/action_view/renderable_partial.rb +48 -0
  89. data/lib/action_view/template.rb +90 -101
  90. data/lib/action_view/template_error.rb +11 -21
  91. data/lib/action_view/template_handler.rb +8 -28
  92. data/lib/action_view/template_handlers.rb +45 -0
  93. data/lib/action_view/template_handlers/builder.rb +5 -15
  94. data/lib/action_view/template_handlers/erb.rb +9 -6
  95. data/lib/action_view/template_handlers/rjs.rb +2 -17
  96. data/lib/action_view/test_case.rb +7 -4
  97. data/test/abstract_unit.rb +4 -1
  98. data/test/active_record_unit.rb +28 -30
  99. data/test/activerecord/render_partial_with_record_identification_test.rb +25 -12
  100. data/test/controller/action_pack_assertions_test.rb +8 -37
  101. data/test/controller/addresses_render_test.rb +0 -3
  102. data/test/controller/assert_select_test.rb +51 -24
  103. data/test/controller/base_test.rb +4 -4
  104. data/test/controller/caching_test.rb +136 -66
  105. data/test/controller/capture_test.rb +1 -21
  106. data/test/controller/cgi_test.rb +157 -10
  107. data/test/controller/components_test.rb +41 -25
  108. data/test/controller/content_type_test.rb +49 -17
  109. data/test/controller/cookie_test.rb +1 -1
  110. data/test/controller/deprecation/deprecated_base_methods_test.rb +0 -3
  111. data/test/controller/dispatcher_test.rb +9 -1
  112. data/test/controller/filter_params_test.rb +2 -2
  113. data/test/controller/filters_test.rb +13 -13
  114. data/test/controller/html-scanner/cdata_node_test.rb +15 -0
  115. data/test/controller/html-scanner/node_test.rb +21 -0
  116. data/test/controller/html-scanner/sanitizer_test.rb +14 -0
  117. data/test/controller/integration_test.rb +167 -6
  118. data/test/controller/layout_test.rb +11 -68
  119. data/test/controller/logging_test.rb +46 -0
  120. data/test/controller/mime_responds_test.rb +61 -59
  121. data/test/controller/mime_type_test.rb +6 -6
  122. data/test/controller/polymorphic_routes_test.rb +37 -2
  123. data/test/controller/rack_test.rb +323 -0
  124. data/test/controller/redirect_test.rb +72 -71
  125. data/test/controller/render_test.rb +1120 -108
  126. data/test/controller/request_forgery_protection_test.rb +66 -52
  127. data/test/controller/request_test.rb +103 -146
  128. data/test/controller/rescue_test.rb +20 -24
  129. data/test/controller/resources_test.rb +408 -25
  130. data/test/controller/routing_test.rb +1774 -1774
  131. data/test/controller/send_file_test.rb +0 -4
  132. data/test/controller/session/cookie_store_test.rb +53 -1
  133. data/test/controller/test_test.rb +15 -37
  134. data/test/controller/translation_test.rb +26 -0
  135. data/test/controller/url_rewriter_test.rb +27 -28
  136. data/test/controller/view_paths_test.rb +48 -47
  137. data/test/fixtures/_top_level_partial.html.erb +1 -0
  138. data/test/fixtures/_top_level_partial_only.erb +1 -0
  139. data/test/fixtures/developers/_developer.erb +1 -0
  140. data/test/fixtures/fun/games/_game.erb +1 -0
  141. data/test/fixtures/fun/serious/games/_game.erb +1 -0
  142. data/test/fixtures/functional_caching/formatted_fragment_cached.html.erb +3 -0
  143. data/test/fixtures/functional_caching/formatted_fragment_cached.js.rjs +6 -0
  144. data/test/fixtures/functional_caching/formatted_fragment_cached.xml.builder +5 -0
  145. data/test/fixtures/functional_caching/inline_fragment_cached.html.erb +2 -0
  146. data/test/fixtures/layouts/_column.html.erb +2 -0
  147. data/test/fixtures/projects/_project.erb +1 -0
  148. data/test/fixtures/public/javascripts/subdir/subdir.js +1 -0
  149. data/test/fixtures/public/stylesheets/subdir/subdir.css +1 -0
  150. data/test/fixtures/replies/_reply.erb +1 -0
  151. data/test/fixtures/test/_counter.html.erb +1 -0
  152. data/test/fixtures/test/_customer.erb +1 -1
  153. data/test/fixtures/test/_customer_with_var.erb +1 -0
  154. data/test/fixtures/test/_layout_for_block_with_args.html.erb +3 -0
  155. data/test/fixtures/test/_local_inspector.html.erb +1 -0
  156. data/test/fixtures/test/_partial_with_only_html_version.html.erb +1 -0
  157. data/test/fixtures/test/hello.builder +1 -1
  158. data/test/fixtures/test/hyphen-ated.erb +1 -0
  159. data/test/fixtures/test/implicit_content_type.atom.builder +2 -0
  160. data/test/fixtures/test/nested_layout.erb +3 -0
  161. data/test/fixtures/test/non_erb_block_content_for.builder +1 -1
  162. data/test/fixtures/test/sub_template_raise.html.erb +1 -0
  163. data/test/fixtures/test/template.erb +1 -0
  164. data/test/fixtures/test/using_layout_around_block_with_args.html.erb +1 -0
  165. data/test/template/active_record_helper_i18n_test.rb +46 -0
  166. data/test/template/active_record_helper_test.rb +24 -24
  167. data/test/template/asset_tag_helper_test.rb +161 -29
  168. data/test/template/atom_feed_helper_test.rb +114 -5
  169. data/test/template/compiled_templates_test.rb +59 -0
  170. data/test/template/date_helper_i18n_test.rb +113 -0
  171. data/test/template/date_helper_test.rb +403 -109
  172. data/test/template/form_helper_test.rb +213 -154
  173. data/test/template/form_options_helper_test.rb +249 -897
  174. data/test/template/form_tag_helper_test.rb +80 -32
  175. data/test/template/javascript_helper_test.rb +17 -18
  176. data/test/template/number_helper_i18n_test.rb +54 -0
  177. data/test/template/number_helper_test.rb +43 -13
  178. data/test/template/prototype_helper_test.rb +101 -84
  179. data/test/template/record_tag_helper_test.rb +24 -20
  180. data/test/template/render_test.rb +193 -0
  181. data/test/template/sanitize_helper_test.rb +3 -3
  182. data/test/template/tag_helper_test.rb +34 -14
  183. data/test/template/text_helper_test.rb +83 -9
  184. data/test/template/translation_helper_test.rb +28 -0
  185. data/test/template/url_helper_test.rb +55 -18
  186. metadata +57 -18
  187. data/lib/action_view/helpers/javascripts/controls.js +0 -963
  188. data/lib/action_view/helpers/javascripts/dragdrop.js +0 -972
  189. data/lib/action_view/helpers/javascripts/effects.js +0 -1120
  190. data/lib/action_view/helpers/javascripts/prototype.js +0 -4225
  191. data/lib/action_view/partial_template.rb +0 -70
  192. data/lib/action_view/template_finder.rb +0 -177
  193. data/lib/action_view/template_handlers/compilable.rb +0 -128
  194. data/test/controller/custom_handler_test.rb +0 -45
  195. data/test/controller/new_render_test.rb +0 -945
  196. data/test/fixtures/test/block_content_for.erb +0 -2
  197. data/test/fixtures/test/erb_content_for.erb +0 -2
  198. data/test/template/deprecated_erb_variable_test.rb +0 -9
  199. data/test/template/template_finder_test.rb +0 -73
  200. data/test/template/template_object_test.rb +0 -95
@@ -1,127 +1,116 @@
1
+ require 'action_controller/mime_type'
2
+
1
3
  module ActionView #:nodoc:
2
- class Template #:nodoc:
3
-
4
- attr_accessor :locals
5
- attr_reader :handler, :path, :extension, :filename, :path_without_extension, :method
6
-
7
- def initialize(view, path, use_full_path, locals = {})
8
- @view = view
9
- @finder = @view.finder
10
-
11
- # Clear the forward slash at the beginning if exists
12
- @path = use_full_path ? path.sub(/^\//, '') : path
13
- @view.first_render ||= @path
14
- @source = nil # Don't read the source until we know that it is required
15
- set_extension_and_file_name(use_full_path)
16
-
17
- @locals = locals || {}
18
- @handler = self.class.handler_class_for_extension(@extension).new(@view)
4
+ class Template
5
+ extend TemplateHandlers
6
+ extend ActiveSupport::Memoizable
7
+ include Renderable
8
+
9
+ attr_accessor :filename, :load_path, :base_path, :name, :format, :extension
10
+ delegate :to_s, :to => :path
11
+
12
+ def initialize(template_path, load_paths = [])
13
+ template_path = template_path.dup
14
+ @base_path, @name, @format, @extension = split(template_path)
15
+ @base_path.to_s.gsub!(/\/$/, '') # Push to split method
16
+ @load_path, @filename = find_full_path(template_path, load_paths)
17
+
18
+ # Extend with partial super powers
19
+ extend RenderablePartial if @name =~ /^_/
19
20
  end
20
21
 
21
- def render_template
22
- render
23
- rescue Exception => e
24
- raise e unless filename
25
- if TemplateError === e
26
- e.sub_template_of(filename)
27
- raise e
28
- else
29
- raise TemplateError.new(self, @view.assigns, e)
30
- end
31
- end
32
-
33
- def render
34
- prepare!
35
- @handler.render(self)
22
+ def format_and_extension
23
+ (extensions = [format, extension].compact.join(".")).blank? ? nil : extensions
36
24
  end
25
+ memoize :format_and_extension
37
26
 
38
- def source
39
- @source ||= File.read(self.filename)
27
+ def multipart?
28
+ format && format.include?('.')
40
29
  end
41
30
 
42
- def method_key
43
- @filename
31
+ def content_type
32
+ format.gsub('.', '/')
44
33
  end
45
34
 
46
- def base_path_for_exception
47
- @finder.find_base_path_for("#{@path_without_extension}.#{@extension}") || @finder.view_paths.first
48
- end
49
-
50
- def prepare!
51
- @view.send :evaluate_assigns
52
- @view.current_render_extension = @extension
53
-
54
- if @handler.compilable?
55
- @handler.compile_template(self) # compile the given template, if necessary
56
- @method = @view.method_names[method_key] # Set the method name for this template and run it
57
- end
35
+ def mime_type
36
+ Mime::Type.lookup_by_extension(format) if format
58
37
  end
38
+ memoize :mime_type
59
39
 
60
- private
61
-
62
- def set_extension_and_file_name(use_full_path)
63
- @path_without_extension, @extension = @finder.path_and_extension(@path)
64
- if use_full_path
65
- if @extension
66
- @filename = @finder.pick_template(@path_without_extension, @extension)
67
- else
68
- @extension = @finder.pick_template_extension(@path).to_s
69
- raise_missing_template_exception unless @extension
70
-
71
- @filename = @finder.pick_template(@path, @extension)
72
- @extension = @extension.gsub(/^.+\./, '') # strip off any formats
73
- end
74
- else
75
- @filename = @path
76
- end
40
+ def path
41
+ [base_path, [name, format, extension].compact.join('.')].compact.join('/')
42
+ end
43
+ memoize :path
77
44
 
78
- raise_missing_template_exception if @filename.blank?
45
+ def path_without_extension
46
+ [base_path, [name, format].compact.join('.')].compact.join('/')
79
47
  end
80
-
81
- def raise_missing_template_exception
82
- full_template_path = @path.include?('.') ? @path : "#{@path}.#{@view.template_format}.erb"
83
- display_paths = @finder.view_paths.join(':')
84
- template_type = (@path =~ /layouts/i) ? 'layout' : 'template'
85
- raise(MissingTemplate, "Missing #{template_type} #{full_template_path} in view path #{display_paths}")
48
+ memoize :path_without_extension
49
+
50
+ def path_without_format_and_extension
51
+ [base_path, name].compact.join('/')
86
52
  end
53
+ memoize :path_without_format_and_extension
87
54
 
88
- # Template Handlers
89
-
90
- @@template_handlers = HashWithIndifferentAccess.new
91
- @@default_template_handlers = nil
92
-
93
- # Register a class that knows how to handle template files with the given
94
- # extension. This can be used to implement new template types.
95
- # The constructor for the class must take the ActiveView::Base instance
96
- # as a parameter, and the class must implement a +render+ method that
97
- # takes the contents of the template to render as well as the Hash of
98
- # local assigns available to the template. The +render+ method ought to
99
- # return the rendered template as a string.
100
- def self.register_template_handler(extension, klass)
101
- @@template_handlers[extension.to_sym] = klass
102
- TemplateFinder.update_extension_cache_for(extension.to_s)
55
+ def relative_path
56
+ path = File.expand_path(filename)
57
+ path.sub!(/^#{Regexp.escape(File.expand_path(RAILS_ROOT))}\//, '') if defined?(RAILS_ROOT)
58
+ path
103
59
  end
60
+ memoize :relative_path
104
61
 
105
- def self.template_handler_extensions
106
- @@template_handlers.keys.map(&:to_s).sort
62
+ def source
63
+ File.read(filename)
107
64
  end
65
+ memoize :source
108
66
 
109
- def self.register_default_template_handler(extension, klass)
110
- register_template_handler(extension, klass)
111
- @@default_template_handlers = klass
67
+ def method_segment
68
+ relative_path.to_s.gsub(/([^a-zA-Z0-9_])/) { $1.ord }
112
69
  end
70
+ memoize :method_segment
113
71
 
114
- def self.handler_class_for_extension(extension)
115
- (extension && @@template_handlers[extension.to_sym]) || @@default_template_handlers
72
+ def render_template(view, local_assigns = {})
73
+ render(view, local_assigns)
74
+ rescue Exception => e
75
+ raise e unless filename
76
+ if TemplateError === e
77
+ e.sub_template_of(self)
78
+ raise e
79
+ else
80
+ raise TemplateError.new(self, view.assigns, e)
81
+ end
116
82
  end
117
83
 
118
- register_default_template_handler :erb, TemplateHandlers::ERB
119
- register_template_handler :rjs, TemplateHandlers::RJS
120
- register_template_handler :builder, TemplateHandlers::Builder
84
+ private
85
+ def valid_extension?(extension)
86
+ Template.template_handler_extensions.include?(extension)
87
+ end
88
+
89
+ def find_full_path(path, load_paths)
90
+ load_paths = Array(load_paths) + [nil]
91
+ load_paths.each do |load_path|
92
+ file = [load_path, path].compact.join('/')
93
+ return load_path, file if File.file?(file)
94
+ end
95
+ raise MissingTemplate.new(load_paths, path)
96
+ end
121
97
 
122
- # TODO: Depreciate old template extensions
123
- register_template_handler :rhtml, TemplateHandlers::ERB
124
- register_template_handler :rxml, TemplateHandlers::Builder
125
-
98
+ # Returns file split into an array
99
+ # [base_path, name, format, extension]
100
+ def split(file)
101
+ if m = file.match(/^(.*\/)?([^\.]+)\.?(\w+)?\.?(\w+)?\.?(\w+)?$/)
102
+ if m[5] # Multipart formats
103
+ [m[1], m[2], "#{m[3]}.#{m[4]}", m[5]]
104
+ elsif m[4] # Single format
105
+ [m[1], m[2], m[3], m[4]]
106
+ else
107
+ if valid_extension?(m[3]) # No format
108
+ [m[1], m[2], nil, m[3]]
109
+ else # No extension
110
+ [m[1], m[2], m[3], nil]
111
+ end
112
+ end
113
+ end
114
+ end
126
115
  end
127
116
  end
@@ -7,12 +7,14 @@ module ActionView
7
7
  attr_reader :original_exception
8
8
 
9
9
  def initialize(template, assigns, original_exception)
10
- @base_path = template.base_path_for_exception
11
- @assigns, @source, @original_exception = assigns.dup, template.source, original_exception
12
- @file_path = template.filename
10
+ @template, @assigns, @original_exception = template, assigns.dup, original_exception
13
11
  @backtrace = compute_backtrace
14
12
  end
15
13
 
14
+ def file_name
15
+ @template.relative_path
16
+ end
17
+
16
18
  def message
17
19
  ActiveSupport::Deprecation.silence { original_exception.message }
18
20
  end
@@ -24,7 +26,7 @@ module ActionView
24
26
  def sub_template_message
25
27
  if @sub_templates
26
28
  "Trace of template inclusion: " +
27
- @sub_templates.collect { |template| strip_base_path(template) }.join(", ")
29
+ @sub_templates.collect { |template| template.relative_path }.join(", ")
28
30
  else
29
31
  ""
30
32
  end
@@ -34,18 +36,18 @@ module ActionView
34
36
  return unless num = line_number
35
37
  num = num.to_i
36
38
 
37
- source_code = IO.readlines(@file_path)
39
+ source_code = @template.source.split("\n")
38
40
 
39
41
  start_on_line = [ num - SOURCE_CODE_RADIUS - 1, 0 ].max
40
42
  end_on_line = [ num + SOURCE_CODE_RADIUS - 1, source_code.length].min
41
43
 
42
44
  indent = ' ' * indentation
43
45
  line_counter = start_on_line
44
- return unless source_code = source_code[start_on_line..end_on_line]
45
-
46
+ return unless source_code = source_code[start_on_line..end_on_line]
47
+
46
48
  source_code.sum do |line|
47
49
  line_counter += 1
48
- "#{indent}#{line_counter}: #{line}"
50
+ "#{indent}#{line_counter}: #{line}\n"
49
51
  end
50
52
  end
51
53
 
@@ -63,12 +65,6 @@ module ActionView
63
65
  end
64
66
  end
65
67
 
66
- def file_name
67
- stripped = strip_base_path(@file_path)
68
- stripped.slice!(0,1) if stripped[0] == ?/
69
- stripped
70
- end
71
-
72
68
  def to_s
73
69
  "\n\n#{self.class} (#{message}) #{source_location}:\n" +
74
70
  "#{source_extract}\n #{clean_backtrace.join("\n ")}\n\n"
@@ -88,12 +84,6 @@ module ActionView
88
84
  ]
89
85
  end
90
86
 
91
- def strip_base_path(path)
92
- stripped_path = File.expand_path(path).gsub(@base_path, "")
93
- stripped_path.gsub!(/^#{Regexp.escape File.expand_path(RAILS_ROOT)}/, '') if defined?(RAILS_ROOT)
94
- stripped_path
95
- end
96
-
97
87
  def source_location
98
88
  if line_number
99
89
  "on line ##{line_number} of "
@@ -105,6 +95,6 @@ module ActionView
105
95
  end
106
96
 
107
97
  if defined?(Exception::TraceSubstitutions)
108
- Exception::TraceSubstitutions << [/:in\s+`_run_(html|xml).*'\s*$/, '']
98
+ Exception::TraceSubstitutions << [/:in\s+`_run_.*'\s*$/, '']
109
99
  Exception::TraceSubstitutions << [%r{^\s*#{Regexp.escape RAILS_ROOT}/}, ''] if defined?(RAILS_ROOT)
110
100
  end
@@ -1,34 +1,14 @@
1
- module ActionView
2
- class TemplateHandler
1
+ # Legacy TemplateHandler stub
3
2
 
4
- def self.line_offset
5
- 0
6
- end
7
-
8
- def self.compilable?
9
- false
10
- end
11
-
12
- def initialize(view)
13
- @view = view
14
- end
15
-
16
- def render(template)
17
- end
18
-
19
- def compile(template)
20
- end
21
-
22
- def compilable?
23
- self.class.compilable?
24
- end
25
-
26
- def line_offset
27
- self.class.line_offset
3
+ module ActionView
4
+ module TemplateHandlers
5
+ module Compilable
28
6
  end
7
+ end
29
8
 
30
- # Called by CacheHelper#cache
31
- def cache_fragment(block, name = {}, options = nil)
9
+ class TemplateHandler
10
+ def self.call(template)
11
+ new.compile(template)
32
12
  end
33
13
  end
34
14
  end
@@ -0,0 +1,45 @@
1
+ require 'action_view/template_handler'
2
+ require 'action_view/template_handlers/builder'
3
+ require 'action_view/template_handlers/erb'
4
+ require 'action_view/template_handlers/rjs'
5
+
6
+ module ActionView #:nodoc:
7
+ module TemplateHandlers #:nodoc:
8
+ def self.extended(base)
9
+ base.register_default_template_handler :erb, TemplateHandlers::ERB
10
+ base.register_template_handler :rjs, TemplateHandlers::RJS
11
+ base.register_template_handler :builder, TemplateHandlers::Builder
12
+
13
+ # TODO: Depreciate old template extensions
14
+ base.register_template_handler :rhtml, TemplateHandlers::ERB
15
+ base.register_template_handler :rxml, TemplateHandlers::Builder
16
+ end
17
+
18
+ @@template_handlers = {}
19
+ @@default_template_handlers = nil
20
+
21
+ # Register a class that knows how to handle template files with the given
22
+ # extension. This can be used to implement new template types.
23
+ # The constructor for the class must take the ActiveView::Base instance
24
+ # as a parameter, and the class must implement a +render+ method that
25
+ # takes the contents of the template to render as well as the Hash of
26
+ # local assigns available to the template. The +render+ method ought to
27
+ # return the rendered template as a string.
28
+ def register_template_handler(extension, klass)
29
+ @@template_handlers[extension.to_sym] = klass
30
+ end
31
+
32
+ def template_handler_extensions
33
+ @@template_handlers.keys.map(&:to_s).sort
34
+ end
35
+
36
+ def register_default_template_handler(extension, klass)
37
+ register_template_handler(extension, klass)
38
+ @@default_template_handlers = klass
39
+ end
40
+
41
+ def handler_class_for_extension(extension)
42
+ (extension && @@template_handlers[extension.to_sym]) || @@default_template_handlers
43
+ end
44
+ end
45
+ end
@@ -5,22 +5,12 @@ module ActionView
5
5
  class Builder < TemplateHandler
6
6
  include Compilable
7
7
 
8
- def self.line_offset
9
- 2
10
- end
11
-
12
8
  def compile(template)
13
- content_type_handler = (@view.send!(:controller).respond_to?(:response) ? "controller.response" : "controller")
14
- "#{content_type_handler}.content_type ||= Mime::XML\n" +
15
- "xml = ::Builder::XmlMarkup.new(:indent => 2)\n" +
16
- template.source +
17
- "\nxml.target!\n"
18
- end
19
-
20
- def cache_fragment(block, name = {}, options = nil)
21
- @view.fragment_for(block, name, options) do
22
- eval('xml.target!', block.binding)
23
- end
9
+ "_set_controller_content_type(Mime::XML);" +
10
+ "xml = ::Builder::XmlMarkup.new(:indent => 2);" +
11
+ "self.output_buffer = xml.target!;" +
12
+ template.source +
13
+ ";xml.target!;"
24
14
  end
25
15
  end
26
16
  end
@@ -42,14 +42,17 @@ module ActionView
42
42
  class ERB < TemplateHandler
43
43
  include Compilable
44
44
 
45
+ # Specify trim mode for the ERB compiler. Defaults to '-'.
46
+ # See ERb documentation for suitable values.
47
+ cattr_accessor :erb_trim_mode
48
+ self.erb_trim_mode = '-'
49
+
45
50
  def compile(template)
46
- ::ERB.new(template.source, nil, @view.erb_trim_mode).src
47
- end
51
+ src = ::ERB.new("<% __in_erb_template=true %>#{template.source}", nil, erb_trim_mode, '@output_buffer').src
48
52
 
49
- def cache_fragment(block, name = {}, options = nil) #:nodoc:
50
- @view.fragment_for(block, name, options) do
51
- eval(ActionView::Base.erb_variable, block.binding)
52
- end
53
+ # Ruby 1.9 prepends an encoding to the source. However this is
54
+ # useless because you can only set an encoding on the first line
55
+ RUBY_VERSION >= '1.9' ? src.sub(/\A#coding:.*\n/, '') : src
53
56
  end
54
57
  end
55
58
  end
@@ -3,24 +3,9 @@ module ActionView
3
3
  class RJS < TemplateHandler
4
4
  include Compilable
5
5
 
6
- def self.line_offset
7
- 2
8
- end
9
-
10
6
  def compile(template)
11
- "controller.response.content_type ||= Mime::JS\n" +
12
- "update_page do |page|\n#{template.source}\nend"
13
- end
14
-
15
- def cache_fragment(block, name = {}, options = nil) #:nodoc:
16
- @view.fragment_for(block, name, options) do
17
- begin
18
- debug_mode, ActionView::Base.debug_rjs = ActionView::Base.debug_rjs, false
19
- eval('page.to_s', block.binding)
20
- ensure
21
- ActionView::Base.debug_rjs = debug_mode
22
- end
23
- end
7
+ "controller.response.content_type ||= Mime::JS;" +
8
+ "update_page do |page|;#{template.source}\nend"
24
9
  end
25
10
  end
26
11
  end