aboutsummaryrefslogtreecommitdiffstats
path: root/actionpack/lib/action_view
diff options
context:
space:
mode:
authorYehuda Katz <wycats@gmail.com>2009-01-22 16:18:10 -0600
committerJoshua Peek <josh@joshpeek.com>2009-01-22 16:18:10 -0600
commiteb9af20b7cc0e374277cf330bdd404f9daab28ec (patch)
treeba05a906690684e442ed92db3e63e295f0dd133e /actionpack/lib/action_view
parentcc0b5fa9930dcc60914e21b518b3c54109243cfa (diff)
downloadrails-eb9af20b7cc0e374277cf330bdd404f9daab28ec.tar.gz
rails-eb9af20b7cc0e374277cf330bdd404f9daab28ec.tar.bz2
rails-eb9af20b7cc0e374277cf330bdd404f9daab28ec.zip
Begin unifying the interface between ActionController and ActionView
Diffstat (limited to 'actionpack/lib/action_view')
-rw-r--r--actionpack/lib/action_view/base.rb91
-rw-r--r--actionpack/lib/action_view/helpers/prototype_helper.rb6
-rw-r--r--actionpack/lib/action_view/paths.rb16
-rw-r--r--actionpack/lib/action_view/render/partials.rb (renamed from actionpack/lib/action_view/partials.rb)151
-rw-r--r--actionpack/lib/action_view/render/rendering.rb119
-rw-r--r--actionpack/lib/action_view/renderable_partial.rb47
-rw-r--r--actionpack/lib/action_view/template/error.rb (renamed from actionpack/lib/action_view/template_error.rb)0
-rw-r--r--actionpack/lib/action_view/template/handler.rb (renamed from actionpack/lib/action_view/template_handler.rb)0
-rw-r--r--actionpack/lib/action_view/template/handlers.rb (renamed from actionpack/lib/action_view/template_handlers.rb)6
-rw-r--r--actionpack/lib/action_view/template/handlers/builder.rb (renamed from actionpack/lib/action_view/template_handlers/builder.rb)0
-rw-r--r--actionpack/lib/action_view/template/handlers/erb.rb (renamed from actionpack/lib/action_view/template_handlers/erb.rb)0
-rw-r--r--actionpack/lib/action_view/template/handlers/rjs.rb (renamed from actionpack/lib/action_view/template_handlers/rjs.rb)2
-rw-r--r--actionpack/lib/action_view/template/inline.rb (renamed from actionpack/lib/action_view/inline_template.rb)0
-rw-r--r--actionpack/lib/action_view/template/partial.rb18
-rw-r--r--actionpack/lib/action_view/template/renderable.rb (renamed from actionpack/lib/action_view/renderable.rb)36
-rw-r--r--actionpack/lib/action_view/template/template.rb (renamed from actionpack/lib/action_view/template.rb)34
-rw-r--r--actionpack/lib/action_view/test_case.rb19
17 files changed, 310 insertions, 235 deletions
diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb
index 70a0ba91a7..80b8ea6a4c 100644
--- a/actionpack/lib/action_view/base.rb
+++ b/actionpack/lib/action_view/base.rb
@@ -160,14 +160,13 @@ module ActionView #:nodoc:
#
# See the ActionView::Helpers::PrototypeHelper::GeneratorMethods documentation for more details.
class Base
- include Helpers, Partials, ::ERB::Util
+ include Helpers, Rendering, Partials, ::ERB::Util
+
extend ActiveSupport::Memoizable
- attr_accessor :base_path, :assigns, :template_extension
+ attr_accessor :base_path, :assigns, :template_extension, :formats
attr_accessor :controller
- attr_writer :template_format
-
attr_accessor :output_buffer
class << self
@@ -184,9 +183,13 @@ module ActionView #:nodoc:
attr_internal :request
+ delegate :controller_path, :to => :controller, :allow_nil => true
+
delegate :request_forgery_protection_token, :template, :params, :session, :cookies, :response, :headers,
:flash, :logger, :action_name, :controller_name, :to => :controller
+ delegate :find_by_parts, :to => :view_paths
+
module CompiledTemplates #:nodoc:
# holds compiled template code
end
@@ -209,7 +212,8 @@ module ActionView #:nodoc:
end
end
- def initialize(view_paths = [], assigns_for_first_render = {}, controller = nil)#:nodoc:
+ def initialize(view_paths = [], assigns_for_first_render = {}, controller = nil, formats = nil)#:nodoc:
+ @formats = formats || [:html]
@assigns = assigns_for_first_render
@assigns_added = nil
@_render_stack = []
@@ -223,55 +227,7 @@ module ActionView #:nodoc:
def view_paths=(paths)
@view_paths = self.class.process_view_paths(paths)
end
-
- # Returns the result of a render that's dictated by the options hash. The primary options are:
- #
- # * <tt>:partial</tt> - See ActionView::Partials.
- # * <tt>:update</tt> - Calls update_page with the block given.
- # * <tt>:file</tt> - Renders an explicit template file (this used to be the old default), add :locals to pass in those.
- # * <tt>:inline</tt> - Renders an inline template similar to how it's done in the controller.
- # * <tt>:text</tt> - Renders the text passed in out.
- #
- # If no options hash is passed or :update specified, the default is to render a partial and use the second parameter
- # as the locals hash.
- def render(options = {}, local_assigns = {}, &block) #:nodoc:
- local_assigns ||= {}
-
- case options
- when Hash
- options = options.reverse_merge(:locals => {})
- if options[:layout]
- _render_with_layout(options, local_assigns, &block)
- elsif options[:file]
- tempalte = self.view_paths.find_template(options[:file], template_format)
- tempalte.render_template(self, options[:locals])
- elsif options[:partial]
- render_partial(options)
- elsif options[:inline]
- InlineTemplate.new(options[:inline], options[:type]).render(self, options[:locals])
- elsif options[:text]
- options[:text]
- end
- when :update
- update_page(&block)
- else
- render_partial(:partial => options, :locals => local_assigns)
- end
- end
-
- # The format to be used when choosing between multiple templates with
- # the same name but differing formats. See +Request#template_format+
- # for more details.
- def template_format
- if defined? @template_format
- @template_format
- elsif controller && controller.respond_to?(:request)
- @template_format = controller.request.template_format.to_sym
- else
- @template_format = :html
- end
- end
-
+
# Access the current template being rendered.
# Returns a ActionView::Template object.
def template
@@ -301,32 +257,5 @@ module ActionView #:nodoc:
controller.response.content_type ||= content_type
end
end
-
- def _render_with_layout(options, local_assigns, &block) #:nodoc:
- partial_layout = options.delete(:layout)
-
- if block_given?
- begin
- @_proc_for_layout = block
- concat(render(options.merge(:partial => partial_layout)))
- ensure
- @_proc_for_layout = nil
- end
- else
- begin
- original_content_for_layout = @content_for_layout if defined?(@content_for_layout)
- @content_for_layout = render(options)
-
- if (options[:inline] || options[:file] || options[:text])
- @cached_content_for_layout = @content_for_layout
- render(:file => partial_layout, :locals => local_assigns)
- else
- render(options.merge(:partial => partial_layout))
- end
- ensure
- @content_for_layout = original_content_for_layout
- end
- end
- end
end
end
diff --git a/actionpack/lib/action_view/helpers/prototype_helper.rb b/actionpack/lib/action_view/helpers/prototype_helper.rb
index 18a209dcea..99676a9c27 100644
--- a/actionpack/lib/action_view/helpers/prototype_helper.rb
+++ b/actionpack/lib/action_view/helpers/prototype_helper.rb
@@ -987,13 +987,13 @@ module ActionView
end
def render(*options_for_render)
- old_format = @context && @context.template_format
- @context.template_format = :html if @context
+ old_formats = @context && @context.formats
+ @context.formats = [:html] if @context
Hash === options_for_render.first ?
@context.render(*options_for_render) :
options_for_render.first.to_s
ensure
- @context.template_format = old_format if @context
+ @context.formats = old_formats if @context
end
def javascript_object_for(object)
diff --git a/actionpack/lib/action_view/paths.rb b/actionpack/lib/action_view/paths.rb
index 19207e7262..4c3a226ac6 100644
--- a/actionpack/lib/action_view/paths.rb
+++ b/actionpack/lib/action_view/paths.rb
@@ -32,14 +32,24 @@ module ActionView #:nodoc:
super(*objs.map { |obj| self.class.type_cast(obj) })
end
+ def find_by_parts(path, extension = nil, prefix = nil, partial = false)
+ template_path = path.sub(/^\//, '')
+
+ each do |load_path|
+ if template = load_path.find_by_parts(template_path, extension, prefix, partial)
+ return template
+ end
+ end
+
+ Template.new(path, self)
+ end
+
def find_template(original_template_path, format = nil)
return original_template_path if original_template_path.respond_to?(:render)
template_path = original_template_path.sub(/^\//, '')
each do |load_path|
- if format && (template = load_path["#{template_path}.#{format}"])
- return template
- elsif template = load_path[template_path]
+ if template = load_path.find_by_parts(template_path, format)
return template
end
end
diff --git a/actionpack/lib/action_view/partials.rb b/actionpack/lib/action_view/render/partials.rb
index 59e82b98a4..aa4c4af213 100644
--- a/actionpack/lib/action_view/partials.rb
+++ b/actionpack/lib/action_view/render/partials.rb
@@ -172,63 +172,128 @@ module ActionView
module Partials
extend ActiveSupport::Memoizable
+ def _render_partial(options = {}) #:nodoc:
+ options[:locals] ||= {}
+
+ case path = partial = options[:partial]
+ when *_array_like_objects
+ return _render_partial_collection(partial, options)
+ else
+ if partial.is_a?(ActionView::Helpers::FormBuilder)
+ path = partial.class.to_s.demodulize.underscore.sub(/_builder$/, '')
+ options[:locals].merge!(path.to_sym => partial)
+ elsif !partial.is_a?(String)
+ options[:object] = object = partial
+ path = ActionController::RecordIdentifier.partial_path(object, controller_path)
+ end
+ _, _, prefix, object = parts = partial_parts(path, options)
+ template = find_by_parts(*parts)
+ _render_partial_object(template, options, (object unless object == true))
+ end
+ end
+
private
- def render_partial(options = {}) #:nodoc:
- local_assigns = options[:locals] || {}
+ def partial_parts(name, options)
+ segments = name.split("/")
+ parts = segments.pop.split(".")
- case partial_path = options[:partial]
- when String, Symbol, NilClass
- if options.has_key?(:collection)
- render_partial_collection(options)
- else
- _pick_partial_template(partial_path).render_partial(self, options[:object], local_assigns)
+ case parts.size
+ when 1
+ parts
+ when 2, 3
+ extension = parts.delete_at(1).to_sym
+ if formats.include?(extension)
+ self.formats.replace [extension]
end
- when ActionView::Helpers::FormBuilder
- builder_partial_path = partial_path.class.to_s.demodulize.underscore.sub(/_builder$/, '')
- local_assigns.merge!(builder_partial_path.to_sym => partial_path)
- render_partial(:partial => builder_partial_path, :object => options[:object], :locals => local_assigns)
- when Array, ActiveRecord::Associations::AssociationCollection, ActiveRecord::NamedScope::Scope
- render_partial_collection(options.except(:partial).merge(:collection => partial_path))
+ parts.pop if parts.size == 2
+ end
+
+ path = parts.join(".")
+ prefix = segments[0..-1].join("/")
+ prefix = prefix.blank? ? controller_path : prefix
+ parts = [path, formats, prefix]
+ parts.push options[:object] || true
+ end
+
+ def _render_partial_with_block(layout, block, options)
+ @_proc_for_layout = block
+ concat(_render_partial(options.merge(:partial => layout)))
+ ensure
+ @_proc_for_layout = nil
+ end
+
+ def _render_partial_with_layout(layout, options)
+ if layout
+ prefix = controller && !layout.include?("/") ? controller.controller_path : nil
+ layout = find_by_parts(layout, formats, prefix, true)
+ end
+ content = _render_partial(options)
+ return _render_content_with_layout(content, layout, options[:locals])
+ end
+
+ def _deprecated_ivar_assign(template)
+ if respond_to?(:controller)
+ ivar = :"@#{template.variable_name}"
+ object =
+ if controller.instance_variable_defined?(ivar)
+ ActiveSupport::Deprecation::DeprecatedObjectProxy.new(
+ controller.instance_variable_get(ivar),
+ "#{ivar} will no longer be implicitly assigned to #{template.variable_name}")
+ end
+ end
+ end
+
+ def _array_like_objects
+ array_like = [Array]
+ if defined?(ActiveRecord)
+ array_like.push(ActiveRecord::Associations::AssociationCollection, ActiveRecord::NamedScope::Scope)
+ end
+ array_like
+ end
+
+ def _render_partial_object(template, options, object = nil)
+ if options.key?(:collection)
+ _render_partial_collection(options.delete(:collection), options, template)
else
- object = partial_path
- render_partial(
- :partial => ActionController::RecordIdentifier.partial_path(object, controller.class.controller_path),
- :object => object,
- :locals => local_assigns
- )
+ locals = (options[:locals] ||= {})
+ object ||= locals[:object] || locals[template.variable_name]
+
+ _set_locals(object, locals, template, options)
+ _render_template(template, locals)
end
end
- def render_partial_collection(options = {}) #:nodoc:
- return nil if options[:collection].blank?
+ def _set_locals(object, locals, template, options)
+ object ||= _deprecated_ivar_assign(template)
+ locals[:object] = locals[template.variable_name] = object
+ locals[options[:as]] = object if options[:as]
+ end
- partial = options[:partial]
- spacer = options[:spacer_template] ? render(:partial => options[:spacer_template]) : ''
- local_assigns = options[:locals] ? options[:locals].clone : {}
- as = options[:as]
+ def _render_partial_collection(collection, options = {}, passed_template = nil) #:nodoc:
+ return nil if collection.blank?
+
+ spacer = options[:spacer_template] ? _render_partial(:partial => options[:spacer_template]) : ''
- index = 0
- options[:collection].map do |object|
- _partial_path ||= partial ||
- ActionController::RecordIdentifier.partial_path(object, controller.class.controller_path)
- template = _pick_partial_template(_partial_path)
- local_assigns[template.counter_name] = index
- result = template.render_partial(self, object, local_assigns.dup, as)
+ locals = (options[:locals] ||= {})
+ index, @_partial_path = 0, nil
+ collection.map do |object|
+ template = passed_template || begin
+ _partial_path =
+ ActionController::RecordIdentifier.partial_path(object, controller_path)
+ template = _pick_partial_template(_partial_path)
+ end
+
+ _set_locals(object, locals, template, options)
+ locals[template.counter_name] = index
+
index += 1
- result
+ _render_template(template, locals)
end.join(spacer)
end
def _pick_partial_template(partial_path) #:nodoc:
- if partial_path.include?('/')
- path = File.join(File.dirname(partial_path), "_#{File.basename(partial_path)}")
- elsif controller
- path = "#{controller.class.controller_path}/_#{partial_path}"
- else
- path = "_#{partial_path}"
- end
-
- self.view_paths.find_template(path, self.template_format)
+ prefix = controller_path unless partial_path.include?('/')
+ find_by_parts(partial_path, formats, prefix, true)
end
memoize :_pick_partial_template
end
diff --git a/actionpack/lib/action_view/render/rendering.rb b/actionpack/lib/action_view/render/rendering.rb
new file mode 100644
index 0000000000..a02c058725
--- /dev/null
+++ b/actionpack/lib/action_view/render/rendering.rb
@@ -0,0 +1,119 @@
+module ActionView
+ module Rendering
+ # Returns the result of a render that's dictated by the options hash. The primary options are:
+ #
+ # * <tt>:partial</tt> - See ActionView::Partials.
+ # * <tt>:update</tt> - Calls update_page with the block given.
+ # * <tt>:file</tt> - Renders an explicit template file (this used to be the old default), add :locals to pass in those.
+ # * <tt>:inline</tt> - Renders an inline template similar to how it's done in the controller.
+ # * <tt>:text</tt> - Renders the text passed in out.
+ #
+ # If no options hash is passed or :update specified, the default is to render a partial and use the second parameter
+ # as the locals hash.
+ def render(options = {}, local_assigns = {}, &block) #:nodoc:
+ local_assigns ||= {}
+
+ @exempt_from_layout = true
+
+ case options
+ when Hash
+ options[:locals] ||= {}
+ layout = options[:layout]
+
+ return _render_partial_with_layout(layout, options) if options.key?(:partial)
+ return _render_partial_with_block(layout, block, options) if block_given?
+
+ layout = find_by_parts(layout, formats) if layout
+
+ if file = options[:file]
+ template = find_by_parts(file, formats)
+ _render_template_with_layout(template, layout, :locals => options[:locals])
+ elsif inline = options[:inline]
+ _render_inline(inline, layout, options)
+ elsif text = options[:text]
+ _render_text(text, layout, options)
+ end
+ when :update
+ update_page(&block)
+ when String, NilClass
+ _render_partial(:partial => options, :locals => local_assigns)
+ end
+ end
+
+ def _render_content_with_layout(content, layout, locals)
+ return content unless layout
+
+ locals ||= {}
+
+ if controller && layout
+ response.layout = layout.path_without_format_and_extension if controller.respond_to?(:response)
+ logger.info("Rendering template within #{layout.path_without_format_and_extension}") if logger
+ end
+
+ begin
+ original_content_for_layout = @content_for_layout if defined?(@content_for_layout)
+ @content_for_layout = content
+
+ @cached_content_for_layout = @content_for_layout
+ _render_template(layout, locals)
+ ensure
+ @content_for_layout = original_content_for_layout
+ end
+ end
+
+ def _render_template(template, local_assigns = {})
+ template.compile(local_assigns)
+
+ @_render_stack.push(template)
+
+ _evaluate_assigns_and_ivars
+ _set_controller_content_type(template.mime_type) if template.respond_to?(:mime_type)
+
+ result = send(template.method_name(local_assigns), local_assigns) do |*names|
+ if !instance_variable_defined?(:"@content_for_#{names.first}") &&
+ instance_variable_defined?(:@_proc_for_layout) && (proc = @_proc_for_layout)
+ capture(*names, &proc)
+ elsif instance_variable_defined?(ivar = :"@content_for_#{names.first || :layout}")
+ instance_variable_get(ivar)
+ end
+ end
+
+ @_render_stack.pop
+ result
+ rescue Exception => e
+ raise e if !template.filename || template.is_a?(InlineTemplate)
+ if TemplateError === e
+ e.sub_template_of(template)
+ raise e
+ else
+ raise TemplateError.new(template, assigns, e)
+ end
+ end
+
+ def _render_inline(inline, layout, options)
+ content = _render_template(InlineTemplate.new(options[:inline], options[:type]), options[:locals] || {})
+ layout ? _render_content_with_layout(content, layout, options[:locals]) : content
+ end
+
+ def _render_text(text, layout, options)
+ layout ? _render_content_with_layout(text, layout, options[:locals]) : text
+ end
+
+ def _render_template_with_layout(template, layout = nil, options = {}, partial = false)
+ if controller && logger
+ logger.info("Rendering #{template.path_without_extension}" +
+ (options[:status] ? " (#{options[:status]})" : ''))
+ end
+
+ content = if partial
+ object = partial unless partial == true
+ _render_partial_object(template, options, object)
+ else
+ _render_template(template, options[:locals] || {})
+ end
+
+ return content unless layout && !template.exempt_from_layout?
+ _render_content_with_layout(content, layout, options[:locals] || {})
+ end
+ end
+end \ No newline at end of file
diff --git a/actionpack/lib/action_view/renderable_partial.rb b/actionpack/lib/action_view/renderable_partial.rb
deleted file mode 100644
index 3ea836fa25..0000000000
--- a/actionpack/lib/action_view/renderable_partial.rb
+++ /dev/null
@@ -1,47 +0,0 @@
-module ActionView
- # NOTE: The template that this mixin is being included into is frozen
- # so you cannot set or modify any instance variables
- module RenderablePartial #:nodoc:
- extend ActiveSupport::Memoizable
-
- def variable_name
- name.sub(/\A_/, '').to_sym
- end
- memoize :variable_name
-
- def counter_name
- "#{variable_name}_counter".to_sym
- end
- memoize :counter_name
-
- def render(view, local_assigns = {})
- if defined? ActionController
- ActionController::Base.benchmark("Rendered #{path_without_format_and_extension}", Logger::DEBUG, false) do
- super
- end
- else
- super
- end
- end
-
- def render_partial(view, object = nil, local_assigns = {}, as = nil)
- object ||= local_assigns[:object] || local_assigns[variable_name]
-
- if object.nil? && view.respond_to?(:controller)
- ivar = :"@#{variable_name}"
- object =
- if view.controller.instance_variable_defined?(ivar)
- ActiveSupport::Deprecation::DeprecatedObjectProxy.new(
- view.controller.instance_variable_get(ivar),
- "#{ivar} will no longer be implicitly assigned to #{variable_name}")
- end
- end
-
- # Ensure correct object is reassigned to other accessors
- local_assigns[:object] = local_assigns[variable_name] = object
- local_assigns[as] = object if as
-
- render_template(view, local_assigns)
- end
- end
-end
diff --git a/actionpack/lib/action_view/template_error.rb b/actionpack/lib/action_view/template/error.rb
index 37cb1c7c6c..37cb1c7c6c 100644
--- a/actionpack/lib/action_view/template_error.rb
+++ b/actionpack/lib/action_view/template/error.rb
diff --git a/actionpack/lib/action_view/template_handler.rb b/actionpack/lib/action_view/template/handler.rb
index 672da0ed2b..672da0ed2b 100644
--- a/actionpack/lib/action_view/template_handler.rb
+++ b/actionpack/lib/action_view/template/handler.rb
diff --git a/actionpack/lib/action_view/template_handlers.rb b/actionpack/lib/action_view/template/handlers.rb
index 205f8628f0..fb85f28851 100644
--- a/actionpack/lib/action_view/template_handlers.rb
+++ b/actionpack/lib/action_view/template/handlers.rb
@@ -1,8 +1,8 @@
module ActionView #:nodoc:
module TemplateHandlers #:nodoc:
- autoload :ERB, 'action_view/template_handlers/erb'
- autoload :RJS, 'action_view/template_handlers/rjs'
- autoload :Builder, 'action_view/template_handlers/builder'
+ autoload :ERB, 'action_view/template/handlers/erb'
+ autoload :RJS, 'action_view/template/handlers/rjs'
+ autoload :Builder, 'action_view/template/handlers/builder'
def self.extended(base)
base.register_default_template_handler :erb, TemplateHandlers::ERB
diff --git a/actionpack/lib/action_view/template_handlers/builder.rb b/actionpack/lib/action_view/template/handlers/builder.rb
index 788dc93326..788dc93326 100644
--- a/actionpack/lib/action_view/template_handlers/builder.rb
+++ b/actionpack/lib/action_view/template/handlers/builder.rb
diff --git a/actionpack/lib/action_view/template_handlers/erb.rb b/actionpack/lib/action_view/template/handlers/erb.rb
index e3120ba267..e3120ba267 100644
--- a/actionpack/lib/action_view/template_handlers/erb.rb
+++ b/actionpack/lib/action_view/template/handlers/erb.rb
diff --git a/actionpack/lib/action_view/template_handlers/rjs.rb b/actionpack/lib/action_view/template/handlers/rjs.rb
index 41a1fddb47..802a79b3fc 100644
--- a/actionpack/lib/action_view/template_handlers/rjs.rb
+++ b/actionpack/lib/action_view/template/handlers/rjs.rb
@@ -4,7 +4,7 @@ module ActionView
include Compilable
def compile(template)
- "@template_format = :html;" +
+ "@formats = [:html];" +
"controller.response.content_type ||= Mime::JS;" +
"update_page do |page|;#{template.source}\nend"
end
diff --git a/actionpack/lib/action_view/inline_template.rb b/actionpack/lib/action_view/template/inline.rb
index 54efa543c8..54efa543c8 100644
--- a/actionpack/lib/action_view/inline_template.rb
+++ b/actionpack/lib/action_view/template/inline.rb
diff --git a/actionpack/lib/action_view/template/partial.rb b/actionpack/lib/action_view/template/partial.rb
new file mode 100644
index 0000000000..30dec1dc5b
--- /dev/null
+++ b/actionpack/lib/action_view/template/partial.rb
@@ -0,0 +1,18 @@
+module ActionView
+ # NOTE: The template that this mixin is being included into is frozen
+ # so you cannot set or modify any instance variables
+ module RenderablePartial #:nodoc:
+ extend ActiveSupport::Memoizable
+
+ def variable_name
+ name.sub(/\A_/, '').to_sym
+ end
+ memoize :variable_name
+
+ def counter_name
+ "#{variable_name}_counter".to_sym
+ end
+ memoize :counter_name
+
+ end
+end
diff --git a/actionpack/lib/action_view/renderable.rb b/actionpack/lib/action_view/template/renderable.rb
index 153e14f68b..35c832aaba 100644
--- a/actionpack/lib/action_view/renderable.rb
+++ b/actionpack/lib/action_view/template/renderable.rb
@@ -23,28 +23,6 @@ module ActionView
end
memoize :method_name_without_locals
- def render(view, local_assigns = {})
- compile(local_assigns)
-
- stack = view.instance_variable_get(:@_render_stack)
- stack.push(self)
-
- view.send(:_evaluate_assigns_and_ivars)
- view.send(:_set_controller_content_type, mime_type) if respond_to?(:mime_type)
-
- result = view.send(method_name(local_assigns), local_assigns) do |*names|
- ivar = :@_proc_for_layout
- if !view.instance_variable_defined?(:"@content_for_#{names.first}") && view.instance_variable_defined?(ivar) && (proc = view.instance_variable_get(ivar))
- view.capture(*names, &proc)
- elsif view.instance_variable_defined?(ivar = :"@content_for_#{names.first || :layout}")
- view.instance_variable_get(ivar)
- end
- end
-
- stack.pop
- result
- end
-
def method_name(local_assigns)
if local_assigns && local_assigns.any?
method_name = method_name_without_locals.dup
@@ -55,16 +33,16 @@ module ActionView
method_name.to_sym
end
- private
- # Compile and evaluate the template's code (if necessary)
- def compile(local_assigns)
- render_symbol = method_name(local_assigns)
+ # Compile and evaluate the template's code (if necessary)
+ def compile(local_assigns)
+ render_symbol = method_name(local_assigns)
- if !Base::CompiledTemplates.method_defined?(render_symbol) || recompile?
- compile!(render_symbol, local_assigns)
- end
+ if !Base::CompiledTemplates.method_defined?(render_symbol) || recompile?
+ compile!(render_symbol, local_assigns)
end
+ end
+ private
def compile!(render_symbol, local_assigns)
locals_code = local_assigns.keys.map { |key| "#{key} = local_assigns[:#{key}];" }.join
diff --git a/actionpack/lib/action_view/template.rb b/actionpack/lib/action_view/template/template.rb
index 9d1e0d3ac5..235a95a0f3 100644
--- a/actionpack/lib/action_view/template.rb
+++ b/actionpack/lib/action_view/template/template.rb
@@ -38,7 +38,7 @@ module ActionView #:nodoc:
# should not be confused with format extensions +html+, +js+, +xml+,
# etc. A format must be supplied to match a formated file. +hello/index+
# will never match +hello/index.html.erb+.
- def [](path)
+ def find_template(path)
templates_in_path do |template|
if template.accessible_paths.include?(path)
return template
@@ -47,6 +47,24 @@ module ActionView #:nodoc:
nil
end
+ def find_by_parts(name, extensions = nil, prefix = nil, partial = nil)
+ path = prefix ? "#{prefix}/" : ""
+
+ name = name.split("/")
+ name[-1] = "_#{name[-1]}" if partial
+
+ path << name.join("/")
+
+ template = nil
+
+ Array(extensions).each do |extension|
+ extensioned_path = extension ? "#{path}.#{extension}" : path
+ template = find_template(extensioned_path) || find_template(path)
+ break if template
+ end
+ template
+ end
+
private
def templates_in_path
(Dir.glob("#{@path}/**/*/**") | Dir.glob("#{@path}/**")).each do |file|
@@ -73,7 +91,7 @@ module ActionView #:nodoc:
@paths.freeze
end
- def [](path)
+ def find_template(path)
@paths[path]
end
end
@@ -177,18 +195,6 @@ module ActionView #:nodoc:
end
memoize :method_segment
- def render_template(view, local_assigns = {})
- render(view, local_assigns)
- rescue Exception => e
- raise e unless filename
- if TemplateError === e
- e.sub_template_of(self)
- raise e
- else
- raise TemplateError.new(self, view.assigns, e)
- end
- end
-
def stale?
File.mtime(filename) > mtime
end
diff --git a/actionpack/lib/action_view/test_case.rb b/actionpack/lib/action_view/test_case.rb
index ec337bb05b..c8f204046b 100644
--- a/actionpack/lib/action_view/test_case.rb
+++ b/actionpack/lib/action_view/test_case.rb
@@ -7,18 +7,15 @@ module ActionView
@_rendered = { :template => nil, :partials => Hash.new(0) }
initialize_without_template_tracking(*args)
end
- end
-
- module Renderable
- alias_method :render_without_template_tracking, :render
- def render(view, local_assigns = {})
- if respond_to?(:path) && !is_a?(InlineTemplate)
- rendered = view.instance_variable_get(:@_rendered)
- rendered[:partials][self] += 1 if is_a?(RenderablePartial)
- rendered[:template] ||= self
+
+ alias_method :_render_template_without_template_tracking, :_render_template
+ def _render_template(template, local_assigns = {})
+ if template.respond_to?(:path) && !template.is_a?(InlineTemplate)
+ @_rendered[:partials][template] += 1 if template.is_a?(RenderablePartial)
+ @_rendered[:template] ||= template
end
- render_without_template_tracking(view, local_assigns)
- end
+ _render_template_without_template_tracking(template, local_assigns)
+ end
end
class TestCase < ActiveSupport::TestCase