From 8a0020b2b8deb0cc7b5b1dfd1921f507fb5470c3 Mon Sep 17 00:00:00 2001 From: Konstantin Haase Date: Tue, 26 Feb 2013 17:13:02 +1100 Subject: [PATCH] add layout_options, fixes #495 --- CHANGES | 3 +++ README.md | 6 ++++++ lib/sinatra/base.rb | 8 +++++--- test/templates_test.rb | 15 +++++++++++++++ 4 files changed, 29 insertions(+), 3 deletions(-) diff --git a/CHANGES b/CHANGES index 50bb8044..20525a60 100644 --- a/CHANGES +++ b/CHANGES @@ -60,6 +60,9 @@ * Improve Accept header parsing, expose parameters. (Pieter van de Bruggen) + * Add `layout_options` render option. Allows you, amongst other things, to + render a layout from a different folder. (Konstantin Haase) + * Explicitly setting `layout` to `nil` is treated like setting it to `false`. (richo) diff --git a/README.md b/README.md index 0c7f4888..4b0c6b08 100644 --- a/README.md +++ b/README.md @@ -386,6 +386,12 @@ Available Options: template. Example: set :rdoc, :layout_engine => :erb +
layout_options
+
+ Special options only used for rendering the layout. Example: + set :rdoc, :layout_options => { :views => 'views/layouts' } +
+
Templates are assumed to be located directly under the `./views` directory. To use a different views directory: diff --git a/lib/sinatra/base.rb b/lib/sinatra/base.rb index 920eec4b..353883f7 100644 --- a/lib/sinatra/base.rb +++ b/lib/sinatra/base.rb @@ -752,9 +752,10 @@ module Sinatra eat_errors = layout.nil? layout = engine_options[:layout] if layout.nil? or layout == true layout = @default_layout if layout.nil? or layout == true - content_type = options.delete(:content_type) || options.delete(:default_content_type) - layout_engine = options.delete(:layout_engine) || engine - scope = options.delete(:scope) || self + layout_options = options.delete(:layout_options) || {} + content_type = options.delete(:content_type) || options.delete(:default_content_type) + layout_engine = options.delete(:layout_engine) || engine + scope = options.delete(:scope) || self options.delete(:layout) # set some defaults @@ -774,6 +775,7 @@ module Sinatra # render layout if layout options = options.merge(:views => views, :layout => false, :eat_errors => eat_errors, :scope => scope) + options.merge! layout_options catch(:layout_missing) { return render(layout_engine, layout, options, locals) { output } } end diff --git a/test/templates_test.rb b/test/templates_test.rb index 1c5aee73..9a2213b3 100644 --- a/test/templates_test.rb +++ b/test/templates_test.rb @@ -222,6 +222,21 @@ class TemplatesTest < Test::Unit::TestCase assert_equal 'Hello Mike!

content

', body end + it 'sets layout-only options via layout_options' do + mock_app do + get '/' do + render(:str, :in_a, + :views => settings.views + '/a', + :layout_options => { :views => settings.views }, + :layout => :layout2) + end + end + + get '/' + assert ok? + assert_equal "

String Layout!

\nGimme an A!\n", body + end + it 'loads templates defined in subclasses' do base = Class.new(Sinatra::Base) base.template(:foo) { 'bar' }