提交 ddd85ef9 编写于 作者: A artemave 提交者: wycats

#948 template_inheritance

上级 9bac649f
......@@ -265,11 +265,11 @@ def _layout
raise ArgumentError, "Layouts must be specified as a String, Symbol, false, or nil"
when nil
if name
_prefix = "layouts" unless _implied_layout_name =~ /\blayouts/
_prefixes = _implied_layout_name =~ /\blayouts/ ? [] : ["layouts"]
self.class_eval <<-RUBY, __FILE__, __LINE__ + 1
def _layout
if template_exists?("#{_implied_layout_name}", #{_prefix.inspect})
if template_exists?("#{_implied_layout_name}", #{_prefixes.inspect})
"#{_implied_layout_name}"
else
super
......
......@@ -114,9 +114,17 @@ def _render_template(options) #:nodoc:
view_context.render(options)
end
# The prefix used in render "foo" shortcuts.
def _prefix
controller_path
# The prefixes used in render "foo" shortcuts.
def _prefixes
prefixes = [controller_path]
parent_controller = self.class.superclass
until parent_controller.abstract?
prefixes << parent_controller.controller_path
parent_controller = parent_controller.superclass
end
prefixes
end
private
......@@ -156,7 +164,7 @@ def _normalize_options(options)
end
if (options.keys & [:partial, :file, :template, :once]).empty?
options[:prefix] ||= _prefix
options[:prefixes] ||= _prefixes
end
options[:template] ||= (options[:action] || action_name).to_s
......
......@@ -12,10 +12,10 @@ def default_render
def method_for_action(action_name)
super || begin
if template_exists?(action_name.to_s, _prefix)
if template_exists?(action_name.to_s, _prefixes)
"default_render"
end
end
end
end
end
\ No newline at end of file
end
......@@ -78,17 +78,17 @@ def view_paths=(paths)
@view_paths = ActionView::Base.process_view_paths(paths)
end
def find(name, prefix = nil, partial = false, keys = [])
@view_paths.find(*args_for_lookup(name, prefix, partial, keys))
def find(name, prefixes = [], partial = false, keys = [])
@view_paths.find(*args_for_lookup(name, prefixes, partial, keys))
end
alias :find_template :find
def find_all(name, prefix = nil, partial = false, keys = [])
@view_paths.find_all(*args_for_lookup(name, prefix, partial, keys))
def find_all(name, prefixes = [], partial = false, keys = [])
@view_paths.find_all(*args_for_lookup(name, prefixes, partial, keys))
end
def exists?(name, prefix = nil, partial = false, keys = [])
@view_paths.exists?(*args_for_lookup(name, prefix, partial, keys))
def exists?(name, prefixes = [], partial = false, keys = [])
@view_paths.exists?(*args_for_lookup(name, prefixes, partial, keys))
end
alias :template_exists? :exists?
......@@ -107,18 +107,25 @@ def with_fallbacks
protected
def args_for_lookup(name, prefix, partial, keys) #:nodoc:
name, prefix = normalize_name(name, prefix)
[name, prefix, partial || false, @details, details_key, keys]
def args_for_lookup(name, prefixes, partial, keys) #:nodoc:
name, prefixes = normalize_name(name, prefixes)
[name, prefixes, partial || false, @details, details_key, keys]
end
# Support legacy foo.erb names even though we now ignore .erb
# as well as incorrectly putting part of the path in the template
# name instead of the prefix.
def normalize_name(name, prefix) #:nodoc:
def normalize_name(name, prefixes) #:nodoc:
name = name.to_s.gsub(handlers_regexp, '')
parts = name.split('/')
return parts.pop, [prefix, *parts].compact.join("/")
name = parts.pop
prx = if not prefixes or prefixes.empty?
[parts.compact.join('/')]
else
prefixes.map {|prefix| [prefix, *parts].compact.join('/') }
end
return name, prx
end
def default_handlers #:nodoc:
......@@ -237,4 +244,4 @@ def _set_detail(key, value)
include Details
include ViewPaths
end
end
\ No newline at end of file
end
......@@ -11,15 +11,19 @@ def #{method}(*args)
end
def find(*args)
find_all(*args).first || raise(MissingTemplate.new(self, "#{args[1]}/#{args[0]}", args[3], args[2]))
template = find_all(*args).first
template or raise MissingTemplate.new(self, "{#{args[1].join(',')},}/#{args[0]}", args[3], args[2])
end
def find_all(*args)
each do |resolver|
templates = resolver.find_all(*args)
return templates unless templates.empty?
def find_all(path, prefixes = [], *args)
templates = []
prefixes.each do |prefix|
each do |resolver|
templates << resolver.find_all(path, prefix, *args)
end
# return templates unless templates.flatten!.empty? XXX this was original behavior; turns this method into find_some, but probably makes it faster
end
[]
templates.flatten
end
def exists?(*args)
......
......@@ -111,8 +111,8 @@ def find_partial
end
def find_template(path=@path, locals=@locals.keys)
prefix = @view.controller_prefix unless path.include?(?/)
@lookup_context.find_template(path, prefix, true, locals)
prefixes = path.include?(?/) ? [] : @view.controller._prefixes
@lookup_context.find_template(path, prefixes, true, locals)
end
def collection_with_template
......
......@@ -43,13 +43,13 @@ def determine_template(options) #:nodoc:
if options.key?(:text)
Template::Text.new(options[:text], formats.try(:first))
elsif options.key?(:file)
with_fallbacks { find_template(options[:file], options[:prefix], false, keys) }
with_fallbacks { find_template(options[:file], [], false, keys) }
elsif options.key?(:inline)
handler = Template.handler_for_extension(options[:type] || "erb")
Template.new(options[:inline], "inline template", handler, :locals => keys)
elsif options.key?(:template)
options[:template].respond_to?(:render) ?
options[:template] : find_template(options[:template], options[:prefix], false, keys)
options[:template] : find_template(options[:template], options[:prefixes], false, keys)
end
end
......
......@@ -13,7 +13,11 @@ def initialize(hash = {})
@hash = hash
end
private
def to_s
@hash.keys.join(', ')
end
private
def query(path, exts, formats)
query = ""
......
......@@ -30,14 +30,14 @@ class TestBasic < ActiveSupport::TestCase
class RenderingController < AbstractController::Base
include ::AbstractController::Rendering
def _prefix() end
def _prefixes
[]
end
def render(options = {})
if options.is_a?(String)
options = {:_template_name => options}
end
options[:_prefix] = _prefix
super
end
......@@ -116,8 +116,8 @@ def self.prefix
name.underscore
end
def _prefix
self.class.prefix
def _prefixes
[self.class.prefix]
end
end
......@@ -157,10 +157,10 @@ class WithLayouts < PrefixedViews
private
def self.layout(formats)
begin
find_template(name.underscore, {:formats => formats}, :_prefix => "layouts")
find_template(name.underscore, {:formats => formats}, :_prefixes => ["layouts"])
rescue ActionView::MissingTemplate
begin
find_template("application", {:formats => formats}, :_prefix => "layouts")
find_template("application", {:formats => formats}, :_prefixes => ["layouts"])
rescue ActionView::MissingTemplate
end
end
......
......@@ -6,8 +6,8 @@ module Testing
class ControllerRenderer < AbstractController::Base
include AbstractController::Rendering
def _prefix
"renderer"
def _prefixes
%w[renderer]
end
self.view_paths = [ActionView::FixtureResolver.new(
......
......@@ -9,7 +9,10 @@ class BasicController < ActionController::Base
"render_partial/basic/basic.html.erb" => "<%= @test_unchanged = 'goodbye' %><%= render :partial => 'basic' %><%= @test_unchanged %>",
"render_partial/basic/with_json.html.erb" => "<%= render 'with_json.json' %>",
"render_partial/basic/_with_json.json.erb" => "<%= render 'final' %>",
"render_partial/basic/_final.json.erb" => "{ final: json }"
"render_partial/basic/_final.json.erb" => "{ final: json }",
"render_partial/basic/overriden.html.erb" => "<%= @test_unchanged = 'goodbye' %><%= render :partial => 'overriden' %><%= @test_unchanged %>",
"render_partial/basic/_overriden.html.erb" => "ParentPartial!",
"render_partial/child/_overriden.html.erb" => "OverridenPartial!"
)]
def html_with_json_inside_json
......@@ -20,7 +23,13 @@ def changing
@test_unchanged = 'hello'
render :action => "basic"
end
def overriden
@test_unchanged = 'hello'
end
end
class ChildController < BasicController; end
class TestPartial < Rack::TestCase
testing BasicController
......@@ -37,4 +46,18 @@ class TestPartial < Rack::TestCase
end
end
class TestInheritedPartial < Rack::TestCase
testing ChildController
test "partial from parent controller gets picked if missing in child one" do
get :changing
assert_response("goodbyeBasicPartial!goodbye")
end
test "partial from child controller gets picked" do
get :overriden
assert_response("goodbyeOverridenPartial!goodbye")
end
end
end
......@@ -6,7 +6,11 @@ class BlankRenderController < ActionController::Base
"render/blank_render/index.html.erb" => "Hello world!",
"render/blank_render/access_request.html.erb" => "The request: <%= request.method.to_s.upcase %>",
"render/blank_render/access_action_name.html.erb" => "Action Name: <%= action_name %>",
"render/blank_render/access_controller_name.html.erb" => "Controller Name: <%= controller_name %>"
"render/blank_render/access_controller_name.html.erb" => "Controller Name: <%= controller_name %>",
"render/blank_render/overriden_with_own_view_paths_appended.html.erb" => "parent content",
"render/blank_render/overriden_with_own_view_paths_prepended.html.erb" => "parent content",
"render/blank_render/overriden.html.erb" => "parent content",
"render/child_render/overriden.html.erb" => "child content"
)]
def index
......@@ -21,6 +25,15 @@ def render_action_name
render :action => "access_action_name"
end
def overriden_with_own_view_paths_appended
end
def overriden_with_own_view_paths_prepended
end
def overriden
end
private
def secretz
......@@ -35,6 +48,11 @@ def index
end
end
class ChildRenderController < BlankRenderController
append_view_path ActionView::FixtureResolver.new("render/child_render/overriden_with_own_view_paths_appended.html.erb" => "child content")
prepend_view_path ActionView::FixtureResolver.new("render/child_render/overriden_with_own_view_paths_prepended.html.erb" => "child content")
end
class RenderTest < Rack::TestCase
test "render with blank" do
with_routing do |set|
......@@ -94,4 +112,27 @@ class TestVariousObjectsAvailableInView < Rack::TestCase
assert_body "Controller Name: blank_render"
end
end
class TestViewInheritance < Rack::TestCase
test "Template from child controller gets picked over parent one" do
get "/render/child_render/overriden"
assert_body "child content"
end
test "Template from child controller with custom view_paths prepended gets picked over parent one" do
get "/render/child_render/overriden_with_own_view_paths_prepended"
assert_body "child content"
end
test "Template from child controller with custom view_paths appended gets picked over parent one" do
get "/render/child_render/overriden_with_own_view_paths_appended"
assert_body "child content"
end
test "Template from parent controller gets picked if missing in child controller" do
get "/render/child_render/index"
assert_body "Hello world!"
end
end
end
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册