halorgium-actionpack 3.0.pre
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.
- data/CHANGELOG +5179 -0
- data/MIT-LICENSE +21 -0
- data/README +409 -0
- data/lib/abstract_controller.rb +16 -0
- data/lib/abstract_controller/base.rb +158 -0
- data/lib/abstract_controller/callbacks.rb +113 -0
- data/lib/abstract_controller/exceptions.rb +12 -0
- data/lib/abstract_controller/helpers.rb +151 -0
- data/lib/abstract_controller/layouts.rb +250 -0
- data/lib/abstract_controller/localized_cache.rb +49 -0
- data/lib/abstract_controller/logger.rb +61 -0
- data/lib/abstract_controller/rendering_controller.rb +188 -0
- data/lib/action_controller.rb +72 -0
- data/lib/action_controller/base.rb +168 -0
- data/lib/action_controller/caching.rb +80 -0
- data/lib/action_controller/caching/actions.rb +163 -0
- data/lib/action_controller/caching/fragments.rb +116 -0
- data/lib/action_controller/caching/pages.rb +154 -0
- data/lib/action_controller/caching/sweeping.rb +97 -0
- data/lib/action_controller/deprecated.rb +4 -0
- data/lib/action_controller/deprecated/integration_test.rb +2 -0
- data/lib/action_controller/deprecated/performance_test.rb +1 -0
- data/lib/action_controller/dispatch/dispatcher.rb +57 -0
- data/lib/action_controller/metal.rb +129 -0
- data/lib/action_controller/metal/benchmarking.rb +73 -0
- data/lib/action_controller/metal/compatibility.rb +145 -0
- data/lib/action_controller/metal/conditional_get.rb +86 -0
- data/lib/action_controller/metal/configuration.rb +28 -0
- data/lib/action_controller/metal/cookies.rb +105 -0
- data/lib/action_controller/metal/exceptions.rb +55 -0
- data/lib/action_controller/metal/filter_parameter_logging.rb +77 -0
- data/lib/action_controller/metal/flash.rb +162 -0
- data/lib/action_controller/metal/head.rb +27 -0
- data/lib/action_controller/metal/helpers.rb +115 -0
- data/lib/action_controller/metal/hide_actions.rb +47 -0
- data/lib/action_controller/metal/http_authentication.rb +312 -0
- data/lib/action_controller/metal/layouts.rb +171 -0
- data/lib/action_controller/metal/mime_responds.rb +317 -0
- data/lib/action_controller/metal/rack_convenience.rb +27 -0
- data/lib/action_controller/metal/redirector.rb +22 -0
- data/lib/action_controller/metal/render_options.rb +103 -0
- data/lib/action_controller/metal/rendering_controller.rb +57 -0
- data/lib/action_controller/metal/request_forgery_protection.rb +108 -0
- data/lib/action_controller/metal/rescuable.rb +13 -0
- data/lib/action_controller/metal/responder.rb +200 -0
- data/lib/action_controller/metal/session.rb +15 -0
- data/lib/action_controller/metal/session_management.rb +45 -0
- data/lib/action_controller/metal/streaming.rb +188 -0
- data/lib/action_controller/metal/testing.rb +39 -0
- data/lib/action_controller/metal/url_for.rb +41 -0
- data/lib/action_controller/metal/verification.rb +130 -0
- data/lib/action_controller/middleware.rb +38 -0
- data/lib/action_controller/notifications.rb +10 -0
- data/lib/action_controller/polymorphic_routes.rb +183 -0
- data/lib/action_controller/record_identifier.rb +91 -0
- data/lib/action_controller/testing/process.rb +111 -0
- data/lib/action_controller/testing/test_case.rb +345 -0
- data/lib/action_controller/translation.rb +13 -0
- data/lib/action_controller/url_rewriter.rb +204 -0
- data/lib/action_controller/vendor/html-scanner.rb +16 -0
- data/lib/action_controller/vendor/html-scanner/html/document.rb +68 -0
- data/lib/action_controller/vendor/html-scanner/html/node.rb +537 -0
- data/lib/action_controller/vendor/html-scanner/html/sanitizer.rb +176 -0
- data/lib/action_controller/vendor/html-scanner/html/selector.rb +828 -0
- data/lib/action_controller/vendor/html-scanner/html/tokenizer.rb +105 -0
- data/lib/action_controller/vendor/html-scanner/html/version.rb +11 -0
- data/lib/action_dispatch.rb +70 -0
- data/lib/action_dispatch/http/headers.rb +33 -0
- data/lib/action_dispatch/http/mime_type.rb +231 -0
- data/lib/action_dispatch/http/mime_types.rb +23 -0
- data/lib/action_dispatch/http/request.rb +539 -0
- data/lib/action_dispatch/http/response.rb +290 -0
- data/lib/action_dispatch/http/status_codes.rb +42 -0
- data/lib/action_dispatch/http/utils.rb +20 -0
- data/lib/action_dispatch/middleware/callbacks.rb +50 -0
- data/lib/action_dispatch/middleware/params_parser.rb +79 -0
- data/lib/action_dispatch/middleware/rescue.rb +26 -0
- data/lib/action_dispatch/middleware/session/abstract_store.rb +208 -0
- data/lib/action_dispatch/middleware/session/cookie_store.rb +235 -0
- data/lib/action_dispatch/middleware/session/mem_cache_store.rb +47 -0
- data/lib/action_dispatch/middleware/show_exceptions.rb +143 -0
- data/lib/action_dispatch/middleware/stack.rb +116 -0
- data/lib/action_dispatch/middleware/static.rb +44 -0
- data/lib/action_dispatch/middleware/string_coercion.rb +29 -0
- data/lib/action_dispatch/middleware/templates/rescues/_request_and_response.erb +24 -0
- data/lib/action_dispatch/middleware/templates/rescues/_trace.erb +26 -0
- data/lib/action_dispatch/middleware/templates/rescues/diagnostics.erb +10 -0
- data/lib/action_dispatch/middleware/templates/rescues/layout.erb +29 -0
- data/lib/action_dispatch/middleware/templates/rescues/missing_template.erb +2 -0
- data/lib/action_dispatch/middleware/templates/rescues/routing_error.erb +10 -0
- data/lib/action_dispatch/middleware/templates/rescues/template_error.erb +21 -0
- data/lib/action_dispatch/middleware/templates/rescues/unknown_action.erb +2 -0
- data/lib/action_dispatch/routing.rb +381 -0
- data/lib/action_dispatch/routing/deprecated_mapper.rb +878 -0
- data/lib/action_dispatch/routing/mapper.rb +327 -0
- data/lib/action_dispatch/routing/route.rb +49 -0
- data/lib/action_dispatch/routing/route_set.rb +497 -0
- data/lib/action_dispatch/testing/assertions.rb +8 -0
- data/lib/action_dispatch/testing/assertions/dom.rb +35 -0
- data/lib/action_dispatch/testing/assertions/model.rb +19 -0
- data/lib/action_dispatch/testing/assertions/response.rb +145 -0
- data/lib/action_dispatch/testing/assertions/routing.rb +144 -0
- data/lib/action_dispatch/testing/assertions/selector.rb +639 -0
- data/lib/action_dispatch/testing/assertions/tag.rb +123 -0
- data/lib/action_dispatch/testing/integration.rb +504 -0
- data/lib/action_dispatch/testing/performance_test.rb +15 -0
- data/lib/action_dispatch/testing/test_request.rb +83 -0
- data/lib/action_dispatch/testing/test_response.rb +131 -0
- data/lib/action_pack.rb +24 -0
- data/lib/action_pack/version.rb +9 -0
- data/lib/action_view.rb +58 -0
- data/lib/action_view/base.rb +308 -0
- data/lib/action_view/context.rb +44 -0
- data/lib/action_view/erb/util.rb +48 -0
- data/lib/action_view/helpers.rb +62 -0
- data/lib/action_view/helpers/active_model_helper.rb +306 -0
- data/lib/action_view/helpers/ajax_helper.rb +68 -0
- data/lib/action_view/helpers/asset_tag_helper.rb +830 -0
- data/lib/action_view/helpers/atom_feed_helper.rb +198 -0
- data/lib/action_view/helpers/cache_helper.rb +39 -0
- data/lib/action_view/helpers/capture_helper.rb +168 -0
- data/lib/action_view/helpers/date_helper.rb +988 -0
- data/lib/action_view/helpers/debug_helper.rb +38 -0
- data/lib/action_view/helpers/form_helper.rb +1102 -0
- data/lib/action_view/helpers/form_options_helper.rb +600 -0
- data/lib/action_view/helpers/form_tag_helper.rb +495 -0
- data/lib/action_view/helpers/javascript_helper.rb +208 -0
- data/lib/action_view/helpers/number_helper.rb +311 -0
- data/lib/action_view/helpers/prototype_helper.rb +1309 -0
- data/lib/action_view/helpers/raw_output_helper.rb +9 -0
- data/lib/action_view/helpers/record_identification_helper.rb +20 -0
- data/lib/action_view/helpers/record_tag_helper.rb +58 -0
- data/lib/action_view/helpers/sanitize_helper.rb +259 -0
- data/lib/action_view/helpers/scriptaculous_helper.rb +226 -0
- data/lib/action_view/helpers/tag_helper.rb +151 -0
- data/lib/action_view/helpers/text_helper.rb +594 -0
- data/lib/action_view/helpers/translation_helper.rb +39 -0
- data/lib/action_view/helpers/url_helper.rb +639 -0
- data/lib/action_view/locale/en.yml +117 -0
- data/lib/action_view/paths.rb +80 -0
- data/lib/action_view/render/partials.rb +342 -0
- data/lib/action_view/render/rendering.rb +134 -0
- data/lib/action_view/safe_buffer.rb +28 -0
- data/lib/action_view/template/error.rb +101 -0
- data/lib/action_view/template/handler.rb +36 -0
- data/lib/action_view/template/handlers.rb +52 -0
- data/lib/action_view/template/handlers/builder.rb +17 -0
- data/lib/action_view/template/handlers/erb.rb +53 -0
- data/lib/action_view/template/handlers/rjs.rb +18 -0
- data/lib/action_view/template/resolver.rb +165 -0
- data/lib/action_view/template/template.rb +131 -0
- data/lib/action_view/template/text.rb +38 -0
- data/lib/action_view/test_case.rb +163 -0
- metadata +236 -0
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
module ActionView
|
|
2
|
+
module Rendering
|
|
3
|
+
# Returns the result of a render that's dictated by the options hash. The primary options are:
|
|
4
|
+
#
|
|
5
|
+
# * <tt>:partial</tt> - See ActionView::Partials.
|
|
6
|
+
# * <tt>:update</tt> - Calls update_page with the block given.
|
|
7
|
+
# * <tt>:file</tt> - Renders an explicit template file (this used to be the old default), add :locals to pass in those.
|
|
8
|
+
# * <tt>:inline</tt> - Renders an inline template similar to how it's done in the controller.
|
|
9
|
+
# * <tt>:text</tt> - Renders the text passed in out.
|
|
10
|
+
#
|
|
11
|
+
# If no options hash is passed or :update specified, the default is to render a partial and use the second parameter
|
|
12
|
+
# as the locals hash.
|
|
13
|
+
def render(options = {}, locals = {}, &block) #:nodoc:
|
|
14
|
+
case options
|
|
15
|
+
when Hash
|
|
16
|
+
layout = options[:layout]
|
|
17
|
+
options[:locals] ||= {}
|
|
18
|
+
|
|
19
|
+
if block_given?
|
|
20
|
+
return concat(_render_partial(options.merge(:partial => layout), &block))
|
|
21
|
+
elsif options.key?(:partial)
|
|
22
|
+
return _render_partial(options)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
layout = find(layout, {:formats => formats}) if layout
|
|
26
|
+
|
|
27
|
+
if file = options[:file]
|
|
28
|
+
template = find(file, {:formats => formats})
|
|
29
|
+
_render_template(template, layout, :locals => options[:locals])
|
|
30
|
+
elsif inline = options[:inline]
|
|
31
|
+
_render_inline(inline, layout, options)
|
|
32
|
+
elsif text = options[:text]
|
|
33
|
+
_render_text(text, layout, options[:locals])
|
|
34
|
+
end
|
|
35
|
+
when :update
|
|
36
|
+
update_page(&block)
|
|
37
|
+
else
|
|
38
|
+
_render_partial(:partial => options, :locals => locals)
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
# You can think of a layout as a method that is called with a block. _layout_for
|
|
43
|
+
# returns the contents that are yielded to the layout. If the user calls yield
|
|
44
|
+
# :some_name, the block, by default, returns content_for(:some_name). If the user
|
|
45
|
+
# calls yield, the default block returns content_for(:layout).
|
|
46
|
+
#
|
|
47
|
+
# The user can override this default by passing a block to the layout.
|
|
48
|
+
#
|
|
49
|
+
# ==== Example
|
|
50
|
+
#
|
|
51
|
+
# # The template
|
|
52
|
+
# <% render :layout => "my_layout" do %>Content<% end %>
|
|
53
|
+
#
|
|
54
|
+
# # The layout
|
|
55
|
+
# <html><% yield %></html>
|
|
56
|
+
#
|
|
57
|
+
# In this case, instead of the default block, which would return content_for(:layout),
|
|
58
|
+
# this method returns the block that was passed in to render layout, and the response
|
|
59
|
+
# would be <html>Content</html>.
|
|
60
|
+
#
|
|
61
|
+
# Finally, the block can take block arguments, which can be passed in by yield.
|
|
62
|
+
#
|
|
63
|
+
# ==== Example
|
|
64
|
+
#
|
|
65
|
+
# # The template
|
|
66
|
+
# <% render :layout => "my_layout" do |customer| %>Hello <%= customer.name %><% end %>
|
|
67
|
+
#
|
|
68
|
+
# # The layout
|
|
69
|
+
# <html><% yield Struct.new(:name).new("David") %></html>
|
|
70
|
+
#
|
|
71
|
+
# In this case, the layout would receive the block passed into <tt>render :layout</tt>,
|
|
72
|
+
# and the Struct specified in the layout would be passed into the block. The result
|
|
73
|
+
# would be <html>Hello David</html>.
|
|
74
|
+
def _layout_for(name = nil, &block)
|
|
75
|
+
return @_content_for[name || :layout] if !block_given? || name
|
|
76
|
+
|
|
77
|
+
capture(&block)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def _render_inline(inline, layout, options)
|
|
81
|
+
handler = Template.handler_class_for_extension(options[:type] || "erb")
|
|
82
|
+
template = Template.new(options[:inline],
|
|
83
|
+
"inline #{options[:inline].inspect}", handler, {})
|
|
84
|
+
|
|
85
|
+
locals = options[:locals]
|
|
86
|
+
content = template.render(self, locals)
|
|
87
|
+
_render_text(content, layout, locals)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def _render_text(content, layout, locals)
|
|
91
|
+
content = layout.render(self, locals) do |*name|
|
|
92
|
+
_layout_for(*name) { content }
|
|
93
|
+
end if layout
|
|
94
|
+
content
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# This is the API to render a ViewContext's template from a controller.
|
|
98
|
+
#
|
|
99
|
+
# Internal Options:
|
|
100
|
+
# _template:: The Template object to render
|
|
101
|
+
# _layout:: The layout, if any, to wrap the Template in
|
|
102
|
+
# _partial:: true if the template is a partial
|
|
103
|
+
def render_template(options)
|
|
104
|
+
_evaluate_assigns_and_ivars
|
|
105
|
+
template, layout, partial = options.values_at(:_template, :_layout, :_partial)
|
|
106
|
+
_render_template(template, layout, options, partial)
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def _render_template(template, layout = nil, options = {}, partial = nil)
|
|
110
|
+
logger && logger.info do
|
|
111
|
+
msg = "Rendering #{template.inspect}"
|
|
112
|
+
msg << " (#{options[:status]})" if options[:status]
|
|
113
|
+
msg
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
locals = options[:locals] || {}
|
|
117
|
+
|
|
118
|
+
content = if partial
|
|
119
|
+
_render_partial_object(template, options)
|
|
120
|
+
else
|
|
121
|
+
template.render(self, locals)
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
@_content_for[:layout] = content
|
|
125
|
+
|
|
126
|
+
if layout
|
|
127
|
+
@_layout = layout.identifier
|
|
128
|
+
logger.info("Rendering template within #{layout.inspect}") if logger
|
|
129
|
+
content = layout.render(self, locals) {|*name| _layout_for(*name) }
|
|
130
|
+
end
|
|
131
|
+
content
|
|
132
|
+
end
|
|
133
|
+
end
|
|
134
|
+
end
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
|
|
2
|
+
module ActionView #:nodoc:
|
|
3
|
+
class SafeBuffer < String
|
|
4
|
+
def <<(value)
|
|
5
|
+
if value.html_safe?
|
|
6
|
+
super(value)
|
|
7
|
+
else
|
|
8
|
+
super(ERB::Util.h(value))
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def concat(value)
|
|
13
|
+
self << value
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def html_safe?
|
|
17
|
+
true
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def html_safe!
|
|
21
|
+
self
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def to_s
|
|
25
|
+
self
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
require "active_support/core_ext/enumerable"
|
|
2
|
+
|
|
3
|
+
module ActionView
|
|
4
|
+
# The TemplateError exception is raised when the compilation of the template fails. This exception then gathers a
|
|
5
|
+
# bunch of intimate details and uses it to report a very precise exception message.
|
|
6
|
+
class TemplateError < ActionViewError #:nodoc:
|
|
7
|
+
SOURCE_CODE_RADIUS = 3
|
|
8
|
+
|
|
9
|
+
attr_reader :original_exception
|
|
10
|
+
|
|
11
|
+
def initialize(template, assigns, original_exception)
|
|
12
|
+
@template, @assigns, @original_exception = template, assigns.dup, original_exception
|
|
13
|
+
@backtrace = compute_backtrace
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def file_name
|
|
17
|
+
@template.identifier
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def message
|
|
21
|
+
ActiveSupport::Deprecation.silence { original_exception.message }
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def clean_backtrace
|
|
25
|
+
if defined?(Rails) && Rails.respond_to?(:backtrace_cleaner)
|
|
26
|
+
Rails.backtrace_cleaner.clean(original_exception.backtrace)
|
|
27
|
+
else
|
|
28
|
+
original_exception.backtrace
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def sub_template_message
|
|
33
|
+
if @sub_templates
|
|
34
|
+
"Trace of template inclusion: " +
|
|
35
|
+
@sub_templates.collect { |template| template.inspect }.join(", ")
|
|
36
|
+
else
|
|
37
|
+
""
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def source_extract(indentation = 0)
|
|
42
|
+
return unless num = line_number
|
|
43
|
+
num = num.to_i
|
|
44
|
+
|
|
45
|
+
source_code = @template.source.split("\n")
|
|
46
|
+
|
|
47
|
+
start_on_line = [ num - SOURCE_CODE_RADIUS - 1, 0 ].max
|
|
48
|
+
end_on_line = [ num + SOURCE_CODE_RADIUS - 1, source_code.length].min
|
|
49
|
+
|
|
50
|
+
indent = ' ' * indentation
|
|
51
|
+
line_counter = start_on_line
|
|
52
|
+
return unless source_code = source_code[start_on_line..end_on_line]
|
|
53
|
+
|
|
54
|
+
source_code.sum do |line|
|
|
55
|
+
line_counter += 1
|
|
56
|
+
"#{indent}#{line_counter}: #{line}\n"
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def sub_template_of(template_path)
|
|
61
|
+
@sub_templates ||= []
|
|
62
|
+
@sub_templates << template_path
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def line_number
|
|
66
|
+
@line_number ||=
|
|
67
|
+
if file_name
|
|
68
|
+
regexp = /#{Regexp.escape File.basename(file_name)}:(\d+)/
|
|
69
|
+
|
|
70
|
+
$1 if message =~ regexp or clean_backtrace.find { |line| line =~ regexp }
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def to_s
|
|
75
|
+
"\n#{self.class} (#{message}) #{source_location}:\n" +
|
|
76
|
+
"#{source_extract}\n #{clean_backtrace.join("\n ")}\n\n"
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# don't do anything nontrivial here. Any raised exception from here becomes fatal
|
|
80
|
+
# (and can't be rescued).
|
|
81
|
+
def backtrace
|
|
82
|
+
@backtrace
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
private
|
|
86
|
+
def compute_backtrace
|
|
87
|
+
[
|
|
88
|
+
"#{source_location.capitalize}\n\n#{source_extract(4)}\n " +
|
|
89
|
+
clean_backtrace.join("\n ")
|
|
90
|
+
]
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def source_location
|
|
94
|
+
if line_number
|
|
95
|
+
"on line ##{line_number} of "
|
|
96
|
+
else
|
|
97
|
+
'in '
|
|
98
|
+
end + file_name
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
end
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
require "active_support/core_ext/class/inheritable_attributes"
|
|
2
|
+
require "action_dispatch/http/mime_type"
|
|
3
|
+
|
|
4
|
+
# Legacy TemplateHandler stub
|
|
5
|
+
module ActionView
|
|
6
|
+
module TemplateHandlers #:nodoc:
|
|
7
|
+
module Compilable
|
|
8
|
+
def self.included(base)
|
|
9
|
+
base.extend(ClassMethods)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
module ClassMethods
|
|
13
|
+
def call(template)
|
|
14
|
+
new.compile(template)
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def compile(template)
|
|
19
|
+
raise "Need to implement #{self.class.name}#compile(template)"
|
|
20
|
+
end
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
class TemplateHandler
|
|
25
|
+
extlib_inheritable_accessor :default_format
|
|
26
|
+
self.default_format = Mime::HTML
|
|
27
|
+
|
|
28
|
+
def self.call(template)
|
|
29
|
+
raise "Need to implement #{self.class.name}#call(template)"
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
def render(template, local_assigns)
|
|
33
|
+
raise "Need to implement #{self.class.name}#render(template, local_assigns)"
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
module ActionView #:nodoc:
|
|
2
|
+
module TemplateHandlers #:nodoc:
|
|
3
|
+
autoload :ERB, 'action_view/template/handlers/erb'
|
|
4
|
+
autoload :RJS, 'action_view/template/handlers/rjs'
|
|
5
|
+
autoload :Builder, 'action_view/template/handlers/builder'
|
|
6
|
+
|
|
7
|
+
def self.extended(base)
|
|
8
|
+
base.register_default_template_handler :erb, TemplateHandlers::ERB
|
|
9
|
+
base.register_template_handler :rjs, TemplateHandlers::RJS
|
|
10
|
+
base.register_template_handler :builder, TemplateHandlers::Builder
|
|
11
|
+
|
|
12
|
+
# TODO: Depreciate old template extensions
|
|
13
|
+
base.register_template_handler :rhtml, TemplateHandlers::ERB
|
|
14
|
+
base.register_template_handler :rxml, TemplateHandlers::Builder
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
@@template_handlers = {}
|
|
18
|
+
@@default_template_handlers = nil
|
|
19
|
+
|
|
20
|
+
def self.extensions
|
|
21
|
+
@@template_handlers.keys
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Register a class that knows how to handle template files with the given
|
|
25
|
+
# extension. This can be used to implement new template types.
|
|
26
|
+
# The constructor for the class must take the ActiveView::Base instance
|
|
27
|
+
# as a parameter, and the class must implement a +render+ method that
|
|
28
|
+
# takes the contents of the template to render as well as the Hash of
|
|
29
|
+
# local assigns available to the template. The +render+ method ought to
|
|
30
|
+
# return the rendered template as a string.
|
|
31
|
+
def register_template_handler(extension, klass)
|
|
32
|
+
@@template_handlers[extension.to_sym] = klass
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def template_handler_extensions
|
|
36
|
+
@@template_handlers.keys.map {|key| key.to_s }.sort
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def registered_template_handler(extension)
|
|
40
|
+
extension && @@template_handlers[extension.to_sym]
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def register_default_template_handler(extension, klass)
|
|
44
|
+
register_template_handler(extension, klass)
|
|
45
|
+
@@default_template_handlers = klass
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def handler_class_for_extension(extension)
|
|
49
|
+
(extension && registered_template_handler(extension.to_sym)) || @@default_template_handlers
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module ActionView
|
|
2
|
+
module TemplateHandlers
|
|
3
|
+
class Builder < TemplateHandler
|
|
4
|
+
include Compilable
|
|
5
|
+
|
|
6
|
+
self.default_format = Mime::XML
|
|
7
|
+
|
|
8
|
+
def compile(template)
|
|
9
|
+
require 'builder'
|
|
10
|
+
"xml = ::Builder::XmlMarkup.new(:indent => 2);" +
|
|
11
|
+
"self.output_buffer = xml.target!;" +
|
|
12
|
+
template.source +
|
|
13
|
+
";xml.target!;"
|
|
14
|
+
end
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
require 'active_support/core_ext/class/attribute_accessors'
|
|
2
|
+
require 'active_support/core_ext/string/output_safety'
|
|
3
|
+
require 'erubis'
|
|
4
|
+
|
|
5
|
+
module ActionView
|
|
6
|
+
module TemplateHandlers
|
|
7
|
+
class Erubis < ::Erubis::Eruby
|
|
8
|
+
def add_preamble(src)
|
|
9
|
+
src << "@output_buffer = ActionView::SafeBuffer.new;"
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def add_text(src, text)
|
|
13
|
+
src << "@output_buffer << ('" << escape_text(text) << "'.html_safe!);"
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def add_expr_literal(src, code)
|
|
17
|
+
src << '@output_buffer << ((' << code << ').to_s);'
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def add_expr_escaped(src, code)
|
|
21
|
+
src << '@output_buffer << ' << escaped_expr(code) << ';'
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def add_postamble(src)
|
|
25
|
+
src << '@output_buffer.to_s'
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
class ERB < TemplateHandler
|
|
30
|
+
include Compilable
|
|
31
|
+
|
|
32
|
+
##
|
|
33
|
+
# :singleton-method:
|
|
34
|
+
# Specify trim mode for the ERB compiler. Defaults to '-'.
|
|
35
|
+
# See ERb documentation for suitable values.
|
|
36
|
+
cattr_accessor :erb_trim_mode
|
|
37
|
+
self.erb_trim_mode = '-'
|
|
38
|
+
|
|
39
|
+
self.default_format = Mime::HTML
|
|
40
|
+
|
|
41
|
+
cattr_accessor :erubis_implementation
|
|
42
|
+
self.erubis_implementation = Erubis
|
|
43
|
+
|
|
44
|
+
def compile(template)
|
|
45
|
+
source = template.source.gsub(/\A(<%(#.*coding[:=]\s*(\S+)\s*)-?%>)\s*\n?/, '')
|
|
46
|
+
erb = "<% __in_erb_template=true %>#{source}"
|
|
47
|
+
result = self.class.erubis_implementation.new(erb, :trim=>(self.class.erb_trim_mode == "-")).src
|
|
48
|
+
result = "#{$2}\n#{result}" if $2
|
|
49
|
+
result
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
module ActionView
|
|
2
|
+
module TemplateHandlers
|
|
3
|
+
class RJS < TemplateHandler
|
|
4
|
+
include Compilable
|
|
5
|
+
|
|
6
|
+
self.default_format = Mime::JS
|
|
7
|
+
|
|
8
|
+
def compile(template)
|
|
9
|
+
"controller.response.content_type ||= Mime::JS;" +
|
|
10
|
+
"update_page do |page|;#{template.source}\nend"
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def default_format
|
|
14
|
+
Mime::JS
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|