Better template inheritance

This commit is contained in:
Ryan Tomayko 2009-03-26 08:01:20 -07:00
parent d5c5aca35f
commit 4de90276a0
2 changed files with 40 additions and 11 deletions

View File

@ -270,23 +270,33 @@ module Sinatra
def lookup_template(engine, template, views_dir, filename = nil, line = nil)
case template
when Symbol
if cached = self.class.templates[template]
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
load_template(engine, template, views_dir, options)
when Proc
filename, line = self.class.caller_locations.first if filename.nil?
[ template.call, filename, line.to_i ]
[template.call, filename, line.to_i]
when String
filename, line = self.class.caller_locations.first if filename.nil?
[ template, filename, line.to_i ]
[template, filename, line.to_i]
else
raise ArgumentError
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)
lookup_template(engine, template, views_dir)
rescue Errno::ENOENT
@ -887,7 +897,7 @@ module Sinatra
def reset!(base=superclass)
@routes = {}
@templates = base.templates.dup
@templates = {}
@conditions = []
@filters = []
@errors = base.errors.dup

View File

@ -1,8 +1,8 @@
require File.dirname(__FILE__) + '/helper'
class TemplatesTest < Test::Unit::TestCase
def render_app(&block)
mock_app {
def render_app(base=Sinatra::Base, &block)
mock_app(base) {
def render_test(template, data, options, locals, &block)
inner = block ? block.call : ''
data + inner
@ -107,6 +107,25 @@ class TemplatesTest < Test::Unit::TestCase
assert ok?
assert_equal 'Hello Mike!<p>content</p>', body
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__ : this is not the real end of the script.