mirror of
https://github.com/github/rails.git
synced 2026-01-10 07:07:54 -05:00
Optimize layout lookup to avoid double calls.
This commit is contained in:
@@ -168,11 +168,12 @@ module AbstractController
|
||||
included do
|
||||
class_attribute :_layout_conditions
|
||||
remove_possible_method :_layout_conditions
|
||||
delegate :_layout_conditions, :to => :'self.class'
|
||||
self._layout_conditions = {}
|
||||
_write_layout_method
|
||||
end
|
||||
|
||||
delegate :_layout_conditions, :to => "self.class"
|
||||
|
||||
module ClassMethods
|
||||
def inherited(klass)
|
||||
super
|
||||
@@ -188,7 +189,7 @@ module AbstractController
|
||||
#
|
||||
# ==== Returns
|
||||
# * <tt> Boolean</tt> - True if the action has a layout, false otherwise.
|
||||
def action_has_layout?
|
||||
def conditional_layout?
|
||||
return unless super
|
||||
|
||||
conditions = _layout_conditions
|
||||
@@ -244,7 +245,13 @@ module AbstractController
|
||||
def _write_layout_method
|
||||
remove_possible_method(:_layout)
|
||||
|
||||
prefixes = _implied_layout_name =~ /\blayouts/ ? [] : ["layouts"]
|
||||
prefixes = _implied_layout_name =~ /\blayouts/ ? [] : ["layouts"]
|
||||
name_clause = if name
|
||||
<<-RUBY
|
||||
lookup_context.find_all("#{_implied_layout_name}", #{prefixes.inspect}).first || super
|
||||
RUBY
|
||||
end
|
||||
|
||||
layout_definition = case defined?(@_layout) ? @_layout : nil
|
||||
when String
|
||||
@_layout.inspect
|
||||
@@ -265,27 +272,15 @@ module AbstractController
|
||||
when true
|
||||
raise ArgumentError, "Layouts must be specified as a String, Symbol, false, or nil"
|
||||
when nil
|
||||
if name
|
||||
<<-RUBY
|
||||
if template_exists?("#{_implied_layout_name}", #{prefixes.inspect})
|
||||
"#{_implied_layout_name}"
|
||||
else
|
||||
super
|
||||
end
|
||||
RUBY
|
||||
end
|
||||
name_clause
|
||||
end
|
||||
|
||||
self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
|
||||
def _layout
|
||||
if action_has_layout?
|
||||
if conditional_layout?
|
||||
#{layout_definition}
|
||||
elsif self.class.name
|
||||
if template_exists?("#{_implied_layout_name}", #{prefixes.inspect})
|
||||
"#{_implied_layout_name}"
|
||||
else
|
||||
super
|
||||
end
|
||||
else
|
||||
#{name_clause}
|
||||
end
|
||||
end
|
||||
RUBY
|
||||
@@ -298,8 +293,7 @@ module AbstractController
|
||||
|
||||
if _include_layout?(options)
|
||||
layout = options.key?(:layout) ? options.delete(:layout) : :default
|
||||
value = _layout_for_option(layout)
|
||||
options[:layout] = (value =~ /\blayouts/ ? value : "layouts/#{value}") if value
|
||||
options[:layout] = Proc.new { _normalize_layout(_layout_for_option(layout)) }
|
||||
end
|
||||
end
|
||||
|
||||
@@ -314,6 +308,10 @@ module AbstractController
|
||||
@_action_has_layout
|
||||
end
|
||||
|
||||
def conditional_layout?
|
||||
true
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# This will be overwritten by _write_layout_method
|
||||
@@ -335,6 +333,10 @@ module AbstractController
|
||||
end
|
||||
end
|
||||
|
||||
def _normalize_layout(value)
|
||||
value.is_a?(String) && value !~ /\blayouts/ ? "layouts/#{value}" : value
|
||||
end
|
||||
|
||||
# Returns the default layout for this controller.
|
||||
# Optionally raises an exception if the layout could not be found.
|
||||
#
|
||||
@@ -346,17 +348,17 @@ module AbstractController
|
||||
# * <tt>template</tt> - The template object for the default layout (or nil)
|
||||
def _default_layout(require_layout = false)
|
||||
begin
|
||||
layout_name = _layout
|
||||
value = _layout if action_has_layout?
|
||||
rescue NameError => e
|
||||
raise e, "Could not render layout: #{e.message}"
|
||||
end
|
||||
|
||||
if require_layout && action_has_layout? && !layout_name
|
||||
if require_layout && action_has_layout? && !value
|
||||
raise ArgumentError,
|
||||
"There was no default layout for #{self.class} in #{view_paths.inspect}"
|
||||
end
|
||||
|
||||
layout_name
|
||||
value
|
||||
end
|
||||
|
||||
def _include_layout?(options)
|
||||
|
||||
@@ -10,7 +10,7 @@ module AbstractController
|
||||
self._view_paths.freeze
|
||||
end
|
||||
|
||||
delegate :find_template, :template_exists?, :view_paths, :formats, :formats=,
|
||||
delegate :template_exists?, :view_paths, :formats, :formats=,
|
||||
:locale, :locale=, :to => :lookup_context
|
||||
|
||||
module ClassMethods
|
||||
|
||||
@@ -227,7 +227,6 @@ module ActionView
|
||||
end
|
||||
|
||||
# A method which only uses the first format in the formats array for layout lookup.
|
||||
# This method plays straight with instance variables for performance reasons.
|
||||
def with_layout_format
|
||||
if formats.size == 1
|
||||
yield
|
||||
|
||||
@@ -58,14 +58,21 @@ module ActionView
|
||||
# context object. If no layout is found, it checks if at least a layout with
|
||||
# the given name exists across all details before raising the error.
|
||||
def find_layout(layout, keys)
|
||||
begin
|
||||
with_layout_format do
|
||||
layout =~ /^\// ?
|
||||
with_fallbacks { find_template(layout, nil, false, keys, @details) } : find_template(layout, nil, false, keys, @details)
|
||||
with_layout_format { resolve_layout(layout, keys) }
|
||||
end
|
||||
|
||||
def resolve_layout(layout, keys)
|
||||
case layout
|
||||
when String
|
||||
if layout =~ /^\//
|
||||
with_fallbacks { find_template(layout, nil, false, keys, @details) }
|
||||
else
|
||||
find_template(layout, nil, false, keys, @details)
|
||||
end
|
||||
rescue ActionView::MissingTemplate
|
||||
all_details = @details.merge(:formats => @lookup_context.default_formats)
|
||||
raise unless template_exists?(layout, nil, false, keys, all_details)
|
||||
when Proc
|
||||
resolve_layout(layout.call, keys)
|
||||
else
|
||||
layout
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user