Sane template options [#191]
* The options hash now takes the :views, :layout, and :locals options but also any template-specific options. The generic options are removed before calling the template specific render method. * The haml ":options" and ":haml" options are deprecated. These should be merged in directly with the options hash. * The sass ":sass" option is deprecated. Merge directly with the options hash instead. * All template engines have an app-level option named the same as their engine (erb, haml, sass, etc.). This must be a hash and is merged with the options passed to the render method. * The :views_directory option is deprecated; renamed :views.
This commit is contained in:
parent
5b2dfebbf0
commit
49adaa5362
|
@ -52,6 +52,16 @@ context "Sass" do
|
|||
body.should.equal "#sass {\n background_color: #FFF; }\n"
|
||||
end
|
||||
|
||||
it "passes :sass option to the Sass engine" do
|
||||
get '/' do
|
||||
sass "#sass\n :background-color #FFF\n :color #000\n", :sass => {:style => :compact}
|
||||
end
|
||||
|
||||
get_it '/'
|
||||
should.be.ok
|
||||
body.should.equal "#sass { background-color: #FFF; color: #000; }\n"
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
end
|
||||
|
|
|
@ -232,53 +232,60 @@ module Sinatra
|
|||
# :locals A hash with local variables that should be available
|
||||
# in the template
|
||||
module Templates
|
||||
def erb(template, options={})
|
||||
def erb(template, options={}, locals={})
|
||||
require 'erb' unless defined? ::ERB
|
||||
render :erb, template, options
|
||||
render :erb, template, options, locals
|
||||
end
|
||||
|
||||
def haml(template, options={})
|
||||
def haml(template, options={}, locals={})
|
||||
require 'haml' unless defined? ::Haml::Engine
|
||||
opts = options[:haml_options] || options.delete(:options) || {}
|
||||
opts = self.class.haml.merge(opts) if self.class.respond_to?(:haml)
|
||||
options[:haml_options] = opts
|
||||
render :haml, template, options
|
||||
render :haml, template, options, locals
|
||||
end
|
||||
|
||||
def sass(template, options={}, &block)
|
||||
def sass(template, options={}, locals={})
|
||||
require 'sass' unless defined? ::Sass::Engine
|
||||
opts = options[:sass_options] || options.delete(:sass) || {}
|
||||
opts = self.class.sass.merge(opts) if self.class.respond_to?(:sass)
|
||||
options.merge! :layout => false, :sass_options => opts
|
||||
render :sass, template, options
|
||||
options[:layout] = false
|
||||
render :sass, template, options, locals
|
||||
end
|
||||
|
||||
def builder(template=nil, options={}, &block)
|
||||
def builder(template=nil, options={}, locals={}, &block)
|
||||
require 'builder' unless defined? ::Builder
|
||||
options, template = template, nil if template.is_a?(Hash)
|
||||
template = lambda { block } if template.nil?
|
||||
render :builder, template, options
|
||||
render :builder, template, options, locals
|
||||
end
|
||||
|
||||
private
|
||||
def render(engine, template, options={}) #:nodoc:
|
||||
data = lookup_template(engine, template, options)
|
||||
output = __send__("render_#{engine}", template, data, options)
|
||||
layout, data = lookup_layout(engine, options)
|
||||
if layout
|
||||
__send__("render_#{engine}", layout, data, options) { output }
|
||||
def render(engine, template, options={}, locals={})
|
||||
# merge app-level options
|
||||
options = self.class.send(engine).merge(options) if self.class.respond_to?(engine)
|
||||
|
||||
# extract generic options
|
||||
layout = options.delete(:layout)
|
||||
layout = :layout if layout.nil? || layout == true
|
||||
views = options.delete(:views) || self.class.views || "./views"
|
||||
locals = options.delete(:locals) || locals || {}
|
||||
|
||||
# render template
|
||||
data = lookup_template(engine, template, views)
|
||||
output = __send__("render_#{engine}", template, data, options, locals)
|
||||
|
||||
# render layout
|
||||
if layout && data = lookup_layout(engine, layout, views)
|
||||
__send__("render_#{engine}", layout, data, options, {}) { output }
|
||||
else
|
||||
output
|
||||
end
|
||||
end
|
||||
|
||||
def lookup_template(engine, template, options={})
|
||||
def lookup_template(engine, template, views_dir)
|
||||
case template
|
||||
when Symbol
|
||||
if cached = self.class.templates[template]
|
||||
lookup_template(engine, cached, options)
|
||||
lookup_template(engine, cached, views_dir)
|
||||
else
|
||||
::File.read(template_path(engine, template, options))
|
||||
path = ::File.join(views_dir, "#{template}.#{engine}")
|
||||
::File.read(path)
|
||||
end
|
||||
when Proc
|
||||
template.call
|
||||
|
@ -289,28 +296,17 @@ module Sinatra
|
|||
end
|
||||
end
|
||||
|
||||
def lookup_layout(engine, options)
|
||||
return if options[:layout] == false
|
||||
options.delete(:layout) if options[:layout] == true
|
||||
template = options[:layout] || :layout
|
||||
data = lookup_template(engine, template, options)
|
||||
[template, data]
|
||||
def lookup_layout(engine, template, views_dir)
|
||||
lookup_template(engine, template, views_dir)
|
||||
rescue Errno::ENOENT
|
||||
nil
|
||||
end
|
||||
|
||||
def template_path(engine, template, options={})
|
||||
views_dir =
|
||||
options[:views_directory] || self.options.views || "./views"
|
||||
"#{views_dir}/#{template}.#{engine}"
|
||||
end
|
||||
|
||||
def render_erb(template, data, options, &block)
|
||||
def render_erb(template, data, options, locals, &block)
|
||||
original_out_buf = @_out_buf
|
||||
data = data.call if data.kind_of? Proc
|
||||
|
||||
instance = ::ERB.new(data, nil, nil, '@_out_buf')
|
||||
locals = options[:locals] || {}
|
||||
locals_assigns = locals.to_a.collect { |k,v| "#{k} = locals[:#{k}]" }
|
||||
|
||||
src = "#{locals_assigns.join("\n")}\n#{instance.src}"
|
||||
|
@ -319,18 +315,17 @@ module Sinatra
|
|||
result
|
||||
end
|
||||
|
||||
def render_haml(template, data, options, &block)
|
||||
engine = ::Haml::Engine.new(data, options[:haml_options] || {})
|
||||
engine.render(self, options[:locals] || {}, &block)
|
||||
def render_haml(template, data, options, locals, &block)
|
||||
::Haml::Engine.new(data, options).render(self, locals, &block)
|
||||
end
|
||||
|
||||
def render_sass(template, data, options, &block)
|
||||
engine = ::Sass::Engine.new(data, options[:sass_options] || {})
|
||||
engine.render
|
||||
def render_sass(template, data, options, locals, &block)
|
||||
::Sass::Engine.new(data, options).render
|
||||
end
|
||||
|
||||
def render_builder(template, data, options, &block)
|
||||
xml = ::Builder::XmlMarkup.new(:indent => 2)
|
||||
def render_builder(template, data, options, locals, &block)
|
||||
options = { :indent => 2 }.merge(options)
|
||||
xml = ::Builder::XmlMarkup.new(options)
|
||||
if data.respond_to?(:to_str)
|
||||
eval data.to_str, binding, '<BUILDER>', 1
|
||||
elsif data.kind_of?(Proc)
|
||||
|
|
|
@ -115,6 +115,22 @@ module Sinatra
|
|||
halt data
|
||||
end
|
||||
|
||||
# The :views_directory, :options, :haml, and :sass options are deprecated.
|
||||
def render(engine, template, options={}, locals={}, &bk)
|
||||
if options.key?(:views_directory)
|
||||
sinatra_warn "The :views_directory option is deprecated; use :views instead."
|
||||
options[:views] = options.delete(:views_directory)
|
||||
end
|
||||
[:options, engine.to_sym].each do |key|
|
||||
if options.key?(key)
|
||||
sinatra_warn "Passing :#{key} => {} to #{engine} is deprecated; " +
|
||||
"merge options directly into hash instead."
|
||||
options.merge! options.delete(key)
|
||||
end
|
||||
end
|
||||
super(engine, template, options, locals, &bk)
|
||||
end
|
||||
|
||||
# Throwing halt with a Symbol and the to_result convention are
|
||||
# deprecated. Override the invoke method to detect those types of return
|
||||
# values.
|
||||
|
|
|
@ -49,18 +49,12 @@ describe "HAML Templates" do
|
|||
it "passes HAML options to the Haml engine" do
|
||||
mock_app {
|
||||
get '/' do
|
||||
haml "!!!\n%h1 Hello World", :haml_options => {:format => :html5}
|
||||
end
|
||||
get '/backwards_compatible' do
|
||||
haml "!!!\n%h1 Hello World", :options => {:format => :html4}
|
||||
haml "!!!\n%h1 Hello World", :format => :html5
|
||||
end
|
||||
}
|
||||
get '/'
|
||||
assert ok?
|
||||
assert_equal "<!DOCTYPE html>\n<h1>Hello World</h1>\n", body
|
||||
get '/backwards_compatible'
|
||||
assert ok?
|
||||
assert_match(/^<!DOCTYPE html PUBLIC (.*) HTML 4.01/, body)
|
||||
end
|
||||
|
||||
it "passes default HAML options to the Haml engine" do
|
||||
|
@ -82,7 +76,7 @@ describe "HAML Templates" do
|
|||
haml "!!!\n%h1{:class => :header} Hello World"
|
||||
end
|
||||
get '/html4' do
|
||||
haml "!!!\n%h1{:class => 'header'} Hello World", :haml_options => {:format => :html4}
|
||||
haml "!!!\n%h1{:class => 'header'} Hello World", :format => :html4
|
||||
end
|
||||
}
|
||||
get '/'
|
||||
|
|
|
@ -36,15 +36,7 @@ describe "Sass Templates" do
|
|||
|
||||
it "passes SASS options to the Sass engine" do
|
||||
sass_app {
|
||||
sass "#sass\n :background-color #FFF\n :color #000\n", :sass_options => {:style => :compact}
|
||||
}
|
||||
assert ok?
|
||||
assert_equal "#sass { background-color: #FFF; color: #000; }\n", body
|
||||
end
|
||||
|
||||
it "passes backwards compatible SASS options to the Sass engine" do
|
||||
sass_app {
|
||||
sass "#sass\n :background-color #FFF\n :color #000\n", :sass => {:style => :compact}
|
||||
sass "#sass\n :background-color #FFF\n :color #000\n", :style => :compact
|
||||
}
|
||||
assert ok?
|
||||
assert_equal "#sass { background-color: #FFF; color: #000; }\n", body
|
||||
|
@ -69,10 +61,10 @@ describe "Sass Templates" do
|
|||
sass "#sass\n background-color: #FFF\n color: #000\n"
|
||||
end
|
||||
get '/raised' do
|
||||
sass "#sass\n :background-color #FFF\n :color #000\n", :sass_options => {:style => :expanded } # retains global attribute_syntax settings
|
||||
sass "#sass\n :background-color #FFF\n :color #000\n", :style => :expanded # retains global attribute_syntax settings
|
||||
end
|
||||
get '/expanded_normal' do
|
||||
sass "#sass\n :background-color #FFF\n :color #000\n", :sass_options => {:style => :expanded, :attribute_syntax => :normal }
|
||||
sass "#sass\n :background-color #FFF\n :color #000\n", :style => :expanded, :attribute_syntax => :normal
|
||||
end
|
||||
}
|
||||
get '/'
|
||||
|
@ -82,6 +74,5 @@ describe "Sass Templates" do
|
|||
get '/expanded_normal'
|
||||
assert ok?
|
||||
assert_equal "#sass {\n background-color: #FFF;\n color: #000;\n}\n", body
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
@ -3,7 +3,7 @@ require File.dirname(__FILE__) + '/helper'
|
|||
describe 'Templating' do
|
||||
def render_app(&block)
|
||||
mock_app {
|
||||
def render_test(template, data, options, &block)
|
||||
def render_test(template, data, options, locals, &block)
|
||||
inner = block ? block.call : ''
|
||||
data + inner
|
||||
end
|
||||
|
|
Loading…
Reference in New Issue