From 441b17ead90d3e3a90a3a478edb216a00f624d0f Mon Sep 17 00:00:00 2001 From: Konstantin Haase Date: Sat, 19 Feb 2011 15:37:49 +0100 Subject: [PATCH] extract template lookup logic, fixes #48 --- lib/sinatra/base.rb | 19 +++++++++++++++---- test/templates_test.rb | 19 +++++++++++++++++++ test/views/a/in_a.str | 1 + test/views/b/in_b.str | 1 + 4 files changed, 36 insertions(+), 4 deletions(-) create mode 100644 test/views/a/in_a.str create mode 100644 test/views/b/in_b.str diff --git a/lib/sinatra/base.rb b/lib/sinatra/base.rb index b7d33228..310419bd 100644 --- a/lib/sinatra/base.rb +++ b/lib/sinatra/base.rb @@ -460,6 +460,15 @@ module Sinatra render :slim, template, options, locals end + # Calls the given block for every possible template file in views, + # named name.ext, where ext is registered on engine. + def find_template(views, name, engine) + Tilt.mappings.each do |ext, klass| + next unless klass == engine + yield ::File.join(views, "#{name}.#{ext}") + end + end + private # logic shared between builder and nokogiri def render_ruby(engine, template, options={}, locals={}, &block) @@ -516,10 +525,12 @@ module Sinatra template.new(path, line.to_i, options) { body } else found = false - Tilt.mappings.each do |ext, klass| - next unless klass == template - path = ::File.join(views, "#{data}.#{ext}") - break if found = File.exists?(path) + find_template(views, data, template) do |file| + path ||= file # keep the initial path rather than the last one + if found = File.exists?(file) + path = file + break + end end throw :layout_missing if eat_errors and not found template.new(path, 1, options) diff --git a/test/templates_test.rb b/test/templates_test.rb index 8ee15d8d..119f3872 100644 --- a/test/templates_test.rb +++ b/test/templates_test.rb @@ -247,6 +247,25 @@ class TemplatesTest < Test::Unit::TestCase assert ok? assert_equal 'Hello World!', body end + + it "is possible to use custom logic for finding template files" do + mock_app do + set :views, ["a", "b"].map { |d| File.dirname(__FILE__) + '/views/' + d } + def find_template(views, name, engine, &block) + Array(views).each { |v| super(v, name, engine, &block) } + end + + get('/:name') do + render :str, params[:name].to_sym + end + end + + get '/in_a' + assert_body 'Gimme an A!' + + get '/in_b' + assert_body 'Gimme a B!' + end end # __END__ : this is not the real end of the script. diff --git a/test/views/a/in_a.str b/test/views/a/in_a.str new file mode 100644 index 00000000..88805dc4 --- /dev/null +++ b/test/views/a/in_a.str @@ -0,0 +1 @@ +Gimme an A! diff --git a/test/views/b/in_b.str b/test/views/b/in_b.str new file mode 100644 index 00000000..156de211 --- /dev/null +++ b/test/views/b/in_b.str @@ -0,0 +1 @@ +Gimme a B!