mirror of
https://github.com/sinatra/sinatra
synced 2023-03-27 23:18:01 -04:00
Better template inheritance
This commit is contained in:
parent
d5c5aca35f
commit
4de90276a0
2 changed files with 40 additions and 11 deletions
|
@ -270,23 +270,33 @@ module Sinatra
|
||||||
def lookup_template(engine, template, views_dir, filename = nil, line = nil)
|
def lookup_template(engine, template, views_dir, filename = nil, line = nil)
|
||||||
case template
|
case template
|
||||||
when Symbol
|
when Symbol
|
||||||
if cached = self.class.templates[template]
|
load_template(engine, template, views_dir, options)
|
||||||
lookup_template(engine, cached[:template], views_dir, cached[:filename], cached[:line])
|
|
||||||
else
|
|
||||||
path = ::File.join(views_dir, "#{template}.#{engine}")
|
|
||||||
[ ::File.read(path), path, 1 ]
|
|
||||||
end
|
|
||||||
when Proc
|
when Proc
|
||||||
filename, line = self.class.caller_locations.first if filename.nil?
|
filename, line = self.class.caller_locations.first if filename.nil?
|
||||||
[ template.call, filename, line.to_i ]
|
[template.call, filename, line.to_i]
|
||||||
when String
|
when String
|
||||||
filename, line = self.class.caller_locations.first if filename.nil?
|
filename, line = self.class.caller_locations.first if filename.nil?
|
||||||
[ template, filename, line.to_i ]
|
[template, filename, line.to_i]
|
||||||
else
|
else
|
||||||
raise ArgumentError
|
raise ArgumentError
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def load_template(engine, template, views_dir, options={})
|
||||||
|
base = self.class
|
||||||
|
while base.respond_to?(:templates)
|
||||||
|
if cached = base.templates[template]
|
||||||
|
return lookup_template(engine, cached[:template], views_dir, cached[:filename], cached[:line])
|
||||||
|
else
|
||||||
|
base = base.superclass
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# If no template exists in the cache, try loading from disk.
|
||||||
|
path = ::File.join(views_dir, "#{template}.#{engine}")
|
||||||
|
[ ::File.read(path), path, 1 ]
|
||||||
|
end
|
||||||
|
|
||||||
def lookup_layout(engine, template, views_dir)
|
def lookup_layout(engine, template, views_dir)
|
||||||
lookup_template(engine, template, views_dir)
|
lookup_template(engine, template, views_dir)
|
||||||
rescue Errno::ENOENT
|
rescue Errno::ENOENT
|
||||||
|
@ -887,7 +897,7 @@ module Sinatra
|
||||||
|
|
||||||
def reset!(base=superclass)
|
def reset!(base=superclass)
|
||||||
@routes = {}
|
@routes = {}
|
||||||
@templates = base.templates.dup
|
@templates = {}
|
||||||
@conditions = []
|
@conditions = []
|
||||||
@filters = []
|
@filters = []
|
||||||
@errors = base.errors.dup
|
@errors = base.errors.dup
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
require File.dirname(__FILE__) + '/helper'
|
require File.dirname(__FILE__) + '/helper'
|
||||||
|
|
||||||
class TemplatesTest < Test::Unit::TestCase
|
class TemplatesTest < Test::Unit::TestCase
|
||||||
def render_app(&block)
|
def render_app(base=Sinatra::Base, &block)
|
||||||
mock_app {
|
mock_app(base) {
|
||||||
def render_test(template, data, options, locals, &block)
|
def render_test(template, data, options, locals, &block)
|
||||||
inner = block ? block.call : ''
|
inner = block ? block.call : ''
|
||||||
data + inner
|
data + inner
|
||||||
|
@ -107,6 +107,25 @@ class TemplatesTest < Test::Unit::TestCase
|
||||||
assert ok?
|
assert ok?
|
||||||
assert_equal 'Hello Mike!<p>content</p>', body
|
assert_equal 'Hello Mike!<p>content</p>', body
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it 'loads templates defined in subclasses' do
|
||||||
|
base = Class.new(Sinatra::Base)
|
||||||
|
base.template(:foo) { 'bar' }
|
||||||
|
render_app(base) { render :test, :foo }
|
||||||
|
assert ok?
|
||||||
|
assert_equal 'bar', body
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'uses templates in superclasses before subclasses' do
|
||||||
|
base = Class.new(Sinatra::Base)
|
||||||
|
base.template(:foo) { 'template in superclass' }
|
||||||
|
render_app(base) { render :test, :foo }
|
||||||
|
@app.template(:foo) { 'template in subclass' }
|
||||||
|
|
||||||
|
get '/'
|
||||||
|
assert ok?
|
||||||
|
assert_equal 'template in subclass', body
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# __END__ : this is not the real end of the script.
|
# __END__ : this is not the real end of the script.
|
||||||
|
|
Loading…
Reference in a new issue