diff options
Diffstat (limited to 'actionpack/lib/action_view')
-rw-r--r-- | actionpack/lib/action_view/base.rb | 89 | ||||
-rw-r--r-- | actionpack/lib/action_view/helpers/prototype_helper.rb | 6 | ||||
-rw-r--r-- | actionpack/lib/action_view/paths.rb | 20 | ||||
-rw-r--r-- | actionpack/lib/action_view/render/partials.rb (renamed from actionpack/lib/action_view/partials.rb) | 179 | ||||
-rw-r--r-- | actionpack/lib/action_view/render/rendering.rb | 119 | ||||
-rw-r--r-- | actionpack/lib/action_view/renderable_partial.rb | 47 | ||||
-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.rb | 18 | ||||
-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.rb | 19 |
17 files changed, 337 insertions, 238 deletions
diff --git a/actionpack/lib/action_view/base.rb b/actionpack/lib/action_view/base.rb index 1529bd3de7..2f7cfeb88e 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 = [] @@ -224,54 +228,6 @@ module ActionView #:nodoc: @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.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 ee26542a07..d88296daa6 100644 --- a/actionpack/lib/action_view/paths.rb +++ b/actionpack/lib/action_view/paths.rb @@ -32,18 +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}.#{I18n.locale}.#{format}"]) - return template - elsif format && (template = load_path["#{template_path}.#{format}"]) - return template - elsif template = load_path["#{template_path}.#{I18n.locale}"] - return template - elsif template = load_path[template_path] + if template = load_path.find_by_parts(template_path, format) return template # Try to find html version if the format is javascript elsif format == :js && template = load_path["#{template_path}.html"] diff --git a/actionpack/lib/action_view/partials.rb b/actionpack/lib/action_view/render/partials.rb index 59e82b98a4..e337dcb63b 100644 --- a/actionpack/lib/action_view/partials.rb +++ b/actionpack/lib/action_view/render/partials.rb @@ -172,63 +172,156 @@ 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 _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 + + 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]) : '' - partial = options[:partial] - spacer = options[:spacer_template] ? render(:partial => options[:spacer_template]) : '' - local_assigns = options[:locals] ? options[:locals].clone : {} - as = options[: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 - 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) + _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 1361a969a9..4b4b80d48c 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 @@ -178,18 +196,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 |