Permalink
Browse files

Ensure the template format is always passed to the template finder. N…

…ow we can cleanup some nasty stuff.
  • Loading branch information...
1 parent f5b7f09 commit 858a420ce18719c720b80508b336e37ce37a20bf @josh josh committed Dec 21, 2008
@@ -570,7 +570,9 @@ def default_template_format
end
def candidate_for_layout?(options)
- !@template.send(:_exempt_from_layout?, default_template_name)
+ !self.view_paths.find_template(default_template_name, default_template_format).exempt_from_layout?
+ rescue ActionView::MissingTemplate
+ return true
end
def template_root
@@ -10,11 +10,14 @@
ActiveSupport::Deprecation.debug = true
# Bogus template processors
-ActionView::Template.register_template_handler :haml, lambda { |template| "Look its HAML!" }
-ActionView::Template.register_template_handler :bak, lambda { |template| "Lame backup" }
+ActionView::Template.register_template_handler :haml, lambda { |template| "Look its HAML!".inspect }
+ActionView::Template.register_template_handler :bak, lambda { |template| "Lame backup".inspect }
$:.unshift "#{File.dirname(__FILE__)}/fixtures/helpers"
-ActionMailer::Base.template_root = "#{File.dirname(__FILE__)}/fixtures"
+
+FIXTURE_LOAD_PATH = File.join(File.dirname(__FILE__), 'fixtures')
+ActionMailer::Base.template_root = FIXTURE_LOAD_PATH
+ActionMailer::Base.template_root.load
class MockSMTP
def self.deliveries
@@ -502,7 +502,7 @@ def filter_parameter_logging(*filter_words, &block)
protected :filter_parameters
end
- delegate :exempt_from_layout, :to => 'ActionView::Base'
+ delegate :exempt_from_layout, :to => 'ActionView::Template'
end
public
@@ -860,7 +860,7 @@ def render(options = nil, extra_options = {}, &block) #:doc:
raise DoubleRenderError, "Can only render or redirect once per action" if performed?
if options.nil?
- return render(:file => default_template_name, :layout => true)
+ return render(:file => default_template, :layout => true)
elsif !extra_options.is_a?(Hash)
raise RenderError, "You called render with invalid options : #{options.inspect}, #{extra_options.inspect}"
else
@@ -898,7 +898,7 @@ def render(options = nil, extra_options = {}, &block) #:doc:
render_for_text(@template.render(options.merge(:layout => layout)), options[:status])
elsif action_name = options[:action]
- render_for_file(default_template_name(action_name.to_s), options[:status], layout)
+ render_for_file(default_template(action_name.to_s), options[:status], layout)
elsif xml = options[:xml]
response.content_type ||= Mime::XML
@@ -933,7 +933,7 @@ def render(options = nil, extra_options = {}, &block) #:doc:
render_for_text(nil, options[:status])
else
- render_for_file(default_template_name, options[:status], layout)
+ render_for_file(default_template, options[:status], layout)
end
end
end
@@ -1164,7 +1164,8 @@ def reset_session #:doc:
private
def render_for_file(template_path, status = nil, layout = nil, locals = {}) #:nodoc:
- logger.info("Rendering #{template_path}" + (status ? " (#{status})" : '')) if logger
+ path = template_path.respond_to?(:path_without_format_and_extension) ? template_path.path_without_format_and_extension : template_path
+ logger.info("Rendering #{path}" + (status ? " (#{status})" : '')) if logger
render_for_text @template.render(:file => template_path, :locals => locals, :layout => layout), status
end
@@ -1241,10 +1242,17 @@ def perform_action
elsif respond_to? :method_missing
method_missing action_name
default_render unless performed?
- elsif template_exists?
- default_render
else
- raise UnknownAction, "No action responded to #{action_name}. Actions: #{action_methods.sort.to_sentence}", caller
+ begin
+ default_render
+ rescue ActionView::MissingTemplate => e
+ # Was the implicit template missing, or was it another template?
+ if e.path == default_template_name
+ raise UnknownAction, "No action responded to #{action_name}. Actions: #{action_methods.sort.to_sentence}", caller
+ else
+ raise e
+ end
+ end
end
end
@@ -1290,10 +1298,8 @@ def close_session
@_session.close if @_session && @_session.respond_to?(:close)
end
- def template_exists?(template_name = default_template_name)
- @template.send(:_pick_template, template_name) ? true : false
- rescue ActionView::MissingTemplate
- false
+ def default_template(action_name = self.action_name)
+ self.view_paths.find_template(default_template_name(action_name), default_template_format)
end
def default_template_name(action_name = self.action_name)
@@ -178,17 +178,23 @@ def default_layout(format) #:nodoc:
find_layout(layout, format)
end
+ def layout_list #:nodoc:
+ Array(view_paths).sum([]) { |path| Dir["#{path}/layouts/**/*"] }
+ end
+
def find_layout(layout, *formats) #:nodoc:
return layout if layout.respond_to?(:render)
view_paths.find_template(layout.to_s =~ /layouts\// ? layout : "layouts/#{layout}", *formats)
+ rescue ActionView::MissingTemplate
+ nil
end
private
def inherited_with_layout(child)
inherited_without_layout(child)
unless child.name.blank?
layout_match = child.name.underscore.sub(/_controller$/, '').sub(/^controllers\//, '')
- child.layout(layout_match, {}, true) if child.find_layout(layout_match, :all)
+ child.layout(layout_match, {}, true) unless child.layout_list.grep(%r{layouts/#{layout_match}(\.[a-z][0-9a-z]*)+$}).empty?
end
end
@@ -225,8 +231,16 @@ def active_layout(passed_layout = nil)
private
def candidate_for_layout?(options)
- options.values_at(:text, :xml, :json, :file, :inline, :partial, :nothing, :update).compact.empty? &&
- !@template.__send__(:_exempt_from_layout?, options[:template] || default_template_name(options[:action]))
+ template = options[:template] || default_template(options[:action])
+ if options.values_at(:text, :xml, :json, :file, :inline, :partial, :nothing, :update).compact.empty?
+ begin
+ !self.view_paths.find_template(template, default_template_format).exempt_from_layout?
+ rescue ActionView::MissingTemplate
+ true
+ end
+ end
+ rescue ActionView::MissingTemplate
+ false
end
def pick_layout(options)
@@ -235,7 +249,7 @@ def pick_layout(options)
when FalseClass
nil
when NilClass, TrueClass
- active_layout if action_has_layout? && !@template.__send__(:_exempt_from_layout?, default_template_name)
+ active_layout if action_has_layout? && candidate_for_layout?(:template => default_template_name)
else
active_layout(layout)
end
@@ -3,7 +3,10 @@ class ActionViewError < StandardError #:nodoc:
end
class MissingTemplate < ActionViewError #:nodoc:
+ attr_reader :path
+
def initialize(paths, path, template_format = nil)
+ @path = path
full_template_path = path.include?('.') ? path : "#{path}.erb"
display_paths = paths.compact.join(":")
template_type = (path =~ /layouts/i) ? 'layout' : 'template'
@@ -172,30 +175,13 @@ class << self
delegate :logger, :to => 'ActionController::Base'
end
- # Templates that are exempt from layouts
- @@exempt_from_layout = Set.new([/\.rjs$/])
-
- # Don't render layouts for templates with the given extensions.
- def self.exempt_from_layout(*extensions)
- regexps = extensions.collect do |extension|
- extension.is_a?(Regexp) ? extension : /\.#{Regexp.escape(extension.to_s)}$/
- end
- @@exempt_from_layout.merge(regexps)
- end
-
@@debug_rjs = false
##
# :singleton-method:
# Specify whether RJS responses should be wrapped in a try/catch block
# that alert()s the caught exception (and then re-raises it).
cattr_accessor :debug_rjs
- @@warn_cache_misses = false
- ##
- # :singleton-method:
- # A warning will be displayed whenever an action results in a cache miss on your view paths.
- cattr_accessor :warn_cache_misses
-
attr_internal :request
delegate :request_forgery_protection_token, :template, :params, :session, :cookies, :response, :headers,
@@ -257,7 +243,8 @@ def render(options = {}, local_assigns = {}, &block) #:nodoc:
if options[:layout]
_render_with_layout(options, local_assigns, &block)
elsif options[:file]
- _pick_template(options[:file]).render_template(self, options[:locals])
+ tempalte = self.view_paths.find_template(options[:file], template_format)
@lukemelia

lukemelia Jan 5, 2009

Contributor

FYI, typo in the variable name “tempalte”

+ tempalte.render_template(self, options[:locals])
elsif options[:partial]
render_partial(options)
elsif options[:inline]
@@ -315,45 +302,6 @@ def _set_controller_content_type(content_type) #:nodoc:
end
end
- def _pick_template(template_path)
- return template_path if template_path.respond_to?(:render)
-
- path = template_path.sub(/^\//, '')
- if m = path.match(/(.*)\.(\w+)$/)
- template_file_name, template_file_extension = m[1], m[2]
- else
- template_file_name = path
- end
-
- # OPTIMIZE: Checks to lookup template in view path
- if template = self.view_paths.find_template(template_file_name, template_format)
- template
- elsif (first_render = @_render_stack.first) && first_render.respond_to?(:format_and_extension) &&
- (template = self.view_paths["#{template_file_name}.#{first_render.format_and_extension}"])
- template
- else
- template = Template.new(template_path, view_paths)
-
- if self.class.warn_cache_misses && logger
- logger.debug "[PERFORMANCE] Rendering a template that was " +
- "not found in view path. Templates outside the view path are " +
- "not cached and result in expensive disk operations. Move this " +
- "file into #{view_paths.join(':')} or add the folder to your " +
- "view path list"
- end
-
- template
- end
- end
- memoize :_pick_template
-
- def _exempt_from_layout?(template_path) #:nodoc:
- template = _pick_template(template_path).to_s
- @@exempt_from_layout.any? { |ext| template =~ ext }
- rescue ActionView::MissingTemplate
- return false
- end
-
def _render_with_layout(options, local_assigns, &block) #:nodoc:
partial_layout = options.delete(:layout)
@@ -228,7 +228,7 @@ def _pick_partial_template(partial_path) #:nodoc:
path = "_#{partial_path}"
end
- _pick_template(path)
+ self.view_paths.find_template(path, self.template_format)
end
memoize :_pick_partial_template
end
@@ -2,13 +2,6 @@ module ActionView #:nodoc:
class PathSet < Array #:nodoc:
def self.type_cast(obj)
if obj.is_a?(String)
- if Base.warn_cache_misses && defined?(Rails) && Rails.initialized?
- Base.logger.debug "[PERFORMANCE] Processing view path during a " +
- "request. This an expense disk operation that should be done at " +
- "boot. You can manually process this view path with " +
- "ActionView::Base.process_view_paths(#{obj.inspect}) and set it " +
- "as your view path"
- end
Path.new(obj)
else
obj
@@ -92,7 +85,7 @@ def [](path)
else
Dir.glob("#{@path}/#{path}*").each do |file|
template = create_template(file)
- if path == template.path_without_extension || path == template.path
+ if template.accessible_paths.include?(path)
return template
end
end
@@ -115,8 +108,9 @@ def reload!
templates_in_path do |template|
template.load!
- @paths[template.path] = template
- @paths[template.path_without_extension] ||= template
+ template.accessible_paths.each do |path|
+ @paths[path] = template
+ end
end
@paths.freeze
@@ -143,28 +137,19 @@ def reload!
each { |path| path.reload! }
end
- def [](template_path)
- each do |path|
- if template = path[template_path]
- return template
- end
- end
- nil
- 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(/^\//, '')
- def find_template(path, *formats)
- if formats && formats.first == :all
- formats = Mime::EXTENSION_LOOKUP.values.map(&:to_sym)
- end
- formats.each do |format|
- if template = self["#{path}.#{format}"]
+ each do |load_path|
+ if format && (template = load_path["#{template_path}.#{format}"])
+ return template
+ elsif template = load_path[template_path]
return template
end
end
- if template = self[path]
- return template
- end
- nil
+
+ Template.new(original_template_path, self)
end
end
end
@@ -22,6 +22,11 @@ def compiled_source
end
memoize :compiled_source
+ def method_name_without_locals
+ ['_run', extension, method_segment].compact.join('_')
+ end
+ memoize :method_name_without_locals
+
def render(view, local_assigns = {})
compile(local_assigns)
@@ -46,9 +51,12 @@ def render(view, local_assigns = {})
def method_name(local_assigns)
if local_assigns && local_assigns.any?
- local_assigns_keys = "locals_#{local_assigns.keys.map { |k| k.to_s }.sort.join('_')}"
+ method_name = method_name_without_locals.dup
+ method_name << "_locals_#{local_assigns.keys.map { |k| k.to_s }.sort.join('_')}"
+ else
+ method_name = method_name_without_locals
end
- ['_run', extension, method_segment, local_assigns_keys].compact.join('_').to_sym
+ method_name.to_sym
end
private
Oops, something went wrong.

0 comments on commit 858a420

Please sign in to comment.