Sets default content type according to template engine used instead of just text/html.
It does so by including a Mixin into the the returned string offering a content_type method. Therefore all of the following examples produce the expected results: # text/html get('/') do haml :index end # text/css get('/') do sass :index end # text/css get('/') do haml :index sass :index end # text/html get('/') do haml '= sass :index' end It also allows setting the default content type for a template engine: set :builder, :content_type => :html Tests and README adjustments (all languages) included.
This commit is contained in:
parent
e5e00471fe
commit
1d676f41f8
|
@ -229,7 +229,6 @@ Das buidler gem wird benötigt um Builder-Templates rendern zu können:
|
|||
require 'builder'
|
||||
|
||||
get '/' do
|
||||
content_type 'application/xml', :charset => 'utf-8'
|
||||
builder :index
|
||||
end
|
||||
|
||||
|
@ -243,7 +242,6 @@ Das haml gem wird benötigt um SASS-Templates rendern zu können:
|
|||
require 'sass'
|
||||
|
||||
get '/stylesheet.css' do
|
||||
content_type 'text/css', :charset => 'utf-8'
|
||||
sass :stylesheet
|
||||
end
|
||||
|
||||
|
@ -257,7 +255,6 @@ und individuell überschrieben werden.
|
|||
set :sass, :style => :compact # Standard Sass-Style ist :nested
|
||||
|
||||
get '/stylesheet.css' do
|
||||
content_type 'text/css', :charset => 'utf-8'
|
||||
sass :stylesheet, :style => :expanded # überschrieben
|
||||
end
|
||||
|
||||
|
@ -269,7 +266,6 @@ Das haml gem wird benötigt um SCSS-Templates rendern zu können:
|
|||
require 'sass'
|
||||
|
||||
get '/stylesheet.css' do
|
||||
content_type 'text/css', :charset => 'utf-8'
|
||||
scss :stylesheet
|
||||
end
|
||||
|
||||
|
@ -283,7 +279,6 @@ und individuell überschrieben werden.
|
|||
set :scss, :style => :compact # Standard Scss-Style ist :nested
|
||||
|
||||
get '/stylesheet.css' do
|
||||
content_type 'text/css', :charset => 'utf-8'
|
||||
scss :stylesheet, :style => :expanded # überschrieben
|
||||
end
|
||||
|
||||
|
@ -295,7 +290,6 @@ Das less gem wird benötigt um Less-Templates rendern zu können:
|
|||
require 'less'
|
||||
|
||||
get '/stylesheet.css' do
|
||||
content_type 'text/css', :charset => 'utf-8'
|
||||
less :stylesheet
|
||||
end
|
||||
|
||||
|
@ -434,7 +428,6 @@ Das coffee-script gem und das `coffee`-Programm werden benötigt um CoffeScript-
|
|||
require 'coffee-script'
|
||||
|
||||
get '/application.js' do
|
||||
content_type 'text/javascript', :charset => 'utf-8'
|
||||
coffee :application
|
||||
end
|
||||
|
||||
|
|
|
@ -154,7 +154,6 @@ builderを使うにはbuilderライブラリが必要です:
|
|||
require 'builder'
|
||||
|
||||
get '/' do
|
||||
content_type 'application/xml', :charset => 'utf-8'
|
||||
builder :index
|
||||
end
|
||||
|
||||
|
@ -168,7 +167,6 @@ Sassテンプレートを使うにはsassライブラリが必要です:
|
|||
require 'sass'
|
||||
|
||||
get '/stylesheet.css' do
|
||||
content_type 'text/css', :charset => 'utf-8'
|
||||
sass :stylesheet
|
||||
end
|
||||
|
||||
|
@ -182,7 +180,6 @@ see {Options and Configurations}[http://www.sinatrarb.com/configuration.html],
|
|||
set :sass, {:style => :compact } # デフォルトのSass styleは :nested
|
||||
|
||||
get '/stylesheet.css' do
|
||||
content_type 'text/css', :charset => 'utf-8'
|
||||
sass :stylesheet, :sass_options => {:style => :expanded } # 上書き
|
||||
end
|
||||
|
||||
|
|
|
@ -225,7 +225,6 @@ The builder gem/library is required to render builder templates:
|
|||
require 'builder'
|
||||
|
||||
get '/' do
|
||||
content_type 'application/xml', :charset => 'utf-8'
|
||||
builder :index
|
||||
end
|
||||
|
||||
|
@ -239,7 +238,6 @@ The sass gem/library is required to render Sass templates:
|
|||
require 'sass'
|
||||
|
||||
get '/stylesheet.css' do
|
||||
content_type 'text/css', :charset => 'utf-8'
|
||||
sass :stylesheet
|
||||
end
|
||||
|
||||
|
@ -253,7 +251,6 @@ and overridden on an individual basis.
|
|||
set :sass, :style => :compact # default Sass style is :nested
|
||||
|
||||
get '/stylesheet.css' do
|
||||
content_type 'text/css', :charset => 'utf-8'
|
||||
sass :stylesheet, :style => :expanded # overridden
|
||||
end
|
||||
|
||||
|
@ -265,7 +262,6 @@ The sass gem/library is required to render Scss templates:
|
|||
require 'sass'
|
||||
|
||||
get '/stylesheet.css' do
|
||||
content_type 'text/css', :charset => 'utf-8'
|
||||
scss :stylesheet
|
||||
end
|
||||
|
||||
|
@ -279,7 +275,6 @@ and overridden on an individual basis.
|
|||
set :scss, :style => :compact # default Scss style is :nested
|
||||
|
||||
get '/stylesheet.css' do
|
||||
content_type 'text/css', :charset => 'utf-8'
|
||||
scss :stylesheet, :style => :expanded # overridden
|
||||
end
|
||||
|
||||
|
@ -291,7 +286,6 @@ The less gem/library is required to render Less templates:
|
|||
require 'less'
|
||||
|
||||
get '/stylesheet.css' do
|
||||
content_type 'text/css', :charset => 'utf-8'
|
||||
less :stylesheet
|
||||
end
|
||||
|
||||
|
@ -422,7 +416,6 @@ CoffeeScript templates:
|
|||
require 'coffee-script'
|
||||
|
||||
get '/application.js' do
|
||||
content_type 'text/javascript', :charset => 'utf-8'
|
||||
coffee :application
|
||||
end
|
||||
|
||||
|
|
|
@ -77,10 +77,12 @@ module Sinatra
|
|||
# evaluation is deferred until the body is read with #each.
|
||||
def body(value=nil, &block)
|
||||
if block_given?
|
||||
def block.each ; yield call ; end
|
||||
def block.each; yield(call) end
|
||||
response.body = block
|
||||
else
|
||||
elsif value
|
||||
response.body = value
|
||||
else
|
||||
response.body
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -137,6 +139,7 @@ module Sinatra
|
|||
def content_type(type, params={})
|
||||
mime_type = mime_type(type)
|
||||
fail "Unknown media type: %p" % type if mime_type.nil?
|
||||
params[:charset] ||= defined?(Encoding) ? Encoding.default_external.to_s.downcase : 'utf-8'
|
||||
if params.any?
|
||||
params = params.collect { |kv| "%s=%s" % kv }.join(', ')
|
||||
response['Content-Type'] = [mime_type, params].join(";")
|
||||
|
@ -300,6 +303,10 @@ module Sinatra
|
|||
# :locals A hash with local variables that should be available
|
||||
# in the template
|
||||
module Templates
|
||||
module ContentTyped
|
||||
attr_accessor :content_type
|
||||
end
|
||||
|
||||
include Tilt::CompileSite
|
||||
|
||||
def erb(template, options={}, locals={})
|
||||
|
@ -315,21 +322,22 @@ module Sinatra
|
|||
end
|
||||
|
||||
def sass(template, options={}, locals={})
|
||||
options[:layout] = false
|
||||
options.merge! :layout => false, :default_content_type => :css
|
||||
render :sass, template, options, locals
|
||||
end
|
||||
|
||||
def scss(template, options={}, locals={})
|
||||
options[:layout] = false
|
||||
options.merge! :layout => false, :default_content_type => :css
|
||||
render :scss, template, options, locals
|
||||
end
|
||||
|
||||
def less(template, options={}, locals={})
|
||||
options[:layout] = false
|
||||
options.merge! :layout => false, :default_content_type => :css
|
||||
render :less, template, options, locals
|
||||
end
|
||||
|
||||
def builder(template=nil, options={}, locals={}, &block)
|
||||
options[:default_content_type] = :xml
|
||||
options, template = template, nil if template.is_a?(Hash)
|
||||
template = Proc.new { block } if template.nil?
|
||||
render :builder, template, options, locals
|
||||
|
@ -360,7 +368,7 @@ module Sinatra
|
|||
end
|
||||
|
||||
def coffee(template, options={}, locals={})
|
||||
options[:layout] = false
|
||||
options.merge! :layout => false, :default_content_type => :js
|
||||
render :coffee, template, options, locals
|
||||
end
|
||||
|
||||
|
@ -376,6 +384,7 @@ module Sinatra
|
|||
@default_layout = :layout if @default_layout.nil?
|
||||
layout = options.delete(:layout)
|
||||
layout = @default_layout if layout.nil? or layout == true
|
||||
content_type = options.delete(:content_type) || options.delete(:default_content_type)
|
||||
|
||||
# compile and render template
|
||||
layout_was = @default_layout
|
||||
|
@ -393,6 +402,7 @@ module Sinatra
|
|||
end
|
||||
end
|
||||
|
||||
output.extend(ContentTyped).content_type = content_type if content_type
|
||||
output
|
||||
end
|
||||
|
||||
|
@ -457,8 +467,16 @@ module Sinatra
|
|||
template_cache.clear if settings.reload_templates
|
||||
force_encoding(@params)
|
||||
|
||||
@response['Content-Type'] = nil
|
||||
invoke { dispatch! }
|
||||
invoke { error_block!(response.status) }
|
||||
unless @response['Content-Type']
|
||||
if body.respond_to?(:to_ary) and body.first.respond_to? :content_type
|
||||
content_type body.first.content_type
|
||||
else
|
||||
content_type :html
|
||||
end
|
||||
end
|
||||
|
||||
status, header, body = @response.finish
|
||||
|
||||
|
|
|
@ -2,9 +2,10 @@ require File.dirname(__FILE__) + '/helper'
|
|||
require 'builder'
|
||||
|
||||
class BuilderTest < Test::Unit::TestCase
|
||||
def builder_app(&block)
|
||||
def builder_app(options = {}, &block)
|
||||
mock_app {
|
||||
set :views, File.dirname(__FILE__) + '/views'
|
||||
set options
|
||||
get '/', &block
|
||||
}
|
||||
get '/'
|
||||
|
@ -16,6 +17,29 @@ class BuilderTest < Test::Unit::TestCase
|
|||
assert_equal %{<?xml version="1.0" encoding="UTF-8"?>\n}, body
|
||||
end
|
||||
|
||||
it 'defaults content type to xml' do
|
||||
builder_app { builder 'xml.instruct!' }
|
||||
assert ok?
|
||||
assert_equal "application/xml;charset=utf-8", response['Content-Type']
|
||||
end
|
||||
|
||||
it 'defaults allows setting content type per route' do
|
||||
builder_app do
|
||||
content_type :html
|
||||
builder 'xml.instruct!'
|
||||
end
|
||||
assert ok?
|
||||
assert_equal "text/html;charset=utf-8", response['Content-Type']
|
||||
end
|
||||
|
||||
it 'defaults allows setting content type globally' do
|
||||
builder_app(:builder => { :content_type => 'html' }) do
|
||||
builder 'xml.instruct!'
|
||||
end
|
||||
assert ok?
|
||||
assert_equal "text/html;charset=utf-8", response['Content-Type']
|
||||
end
|
||||
|
||||
it 'renders inline blocks' do
|
||||
builder_app {
|
||||
@name = "Frank & Mary"
|
||||
|
|
|
@ -4,9 +4,10 @@ begin
|
|||
require 'coffee-script'
|
||||
|
||||
class CoffeeTest < Test::Unit::TestCase
|
||||
def coffee_app(&block)
|
||||
def coffee_app(options = {}, &block)
|
||||
mock_app {
|
||||
set :views, File.dirname(__FILE__) + '/views'
|
||||
set(options)
|
||||
get '/', &block
|
||||
}
|
||||
get '/'
|
||||
|
@ -18,6 +19,29 @@ class CoffeeTest < Test::Unit::TestCase
|
|||
assert_equal "(function() {\n alert('Aye!');\n})();\n", body
|
||||
end
|
||||
|
||||
it 'defaults content type to javascript' do
|
||||
coffee_app { coffee "alert 'Aye!'\n" }
|
||||
assert ok?
|
||||
assert_equal "application/javascript;charset=utf-8", response['Content-Type']
|
||||
end
|
||||
|
||||
it 'defaults allows setting content type per route' do
|
||||
coffee_app do
|
||||
content_type :html
|
||||
coffee "alert 'Aye!'\n"
|
||||
end
|
||||
assert ok?
|
||||
assert_equal "text/html;charset=utf-8", response['Content-Type']
|
||||
end
|
||||
|
||||
it 'defaults allows setting content type globally' do
|
||||
coffee_app(:coffee => { :content_type => 'html' }) do
|
||||
coffee "alert 'Aye!'\n"
|
||||
end
|
||||
assert ok?
|
||||
assert_equal "text/html;charset=utf-8", response['Content-Type']
|
||||
end
|
||||
|
||||
it 'renders .coffee files in views path' do
|
||||
coffee_app { coffee :hello }
|
||||
assert ok?
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
ENV['RACK_ENV'] = 'test'
|
||||
Encoding.default_external = "UTF-8" if defined? Encoding
|
||||
|
||||
begin
|
||||
require 'rack'
|
||||
|
|
|
@ -291,21 +291,21 @@ class HelpersTest < Test::Unit::TestCase
|
|||
}
|
||||
|
||||
get '/'
|
||||
assert_equal 'text/plain', response['Content-Type']
|
||||
assert_equal 'text/plain;charset=utf-8', response['Content-Type']
|
||||
assert_equal 'Hello World', body
|
||||
end
|
||||
|
||||
it 'takes media type parameters (like charset=)' do
|
||||
mock_app {
|
||||
get '/' do
|
||||
content_type 'text/html', :charset => 'utf-8'
|
||||
content_type 'text/html', :charset => 'latin1'
|
||||
"<h1>Hello, World</h1>"
|
||||
end
|
||||
}
|
||||
|
||||
get '/'
|
||||
assert ok?
|
||||
assert_equal 'text/html;charset=utf-8', response['Content-Type']
|
||||
assert_equal 'text/html;charset=latin1', response['Content-Type']
|
||||
assert_equal "<h1>Hello, World</h1>", body
|
||||
end
|
||||
|
||||
|
@ -320,7 +320,7 @@ class HelpersTest < Test::Unit::TestCase
|
|||
|
||||
get '/foo.xml'
|
||||
assert ok?
|
||||
assert_equal 'application/foo', response['Content-Type']
|
||||
assert_equal 'application/foo;charset=utf-8', response['Content-Type']
|
||||
assert_equal 'I AM FOO', body
|
||||
end
|
||||
|
||||
|
@ -366,19 +366,19 @@ class HelpersTest < Test::Unit::TestCase
|
|||
it 'sets the Content-Type response header if a mime-type can be located' do
|
||||
send_file_app
|
||||
get '/file.txt'
|
||||
assert_equal 'text/plain', response['Content-Type']
|
||||
assert_equal 'text/plain;charset=utf-8', response['Content-Type']
|
||||
end
|
||||
|
||||
it 'sets the Content-Type response header if type option is set to a file extesion' do
|
||||
send_file_app :type => 'html'
|
||||
get '/file.txt'
|
||||
assert_equal 'text/html', response['Content-Type']
|
||||
assert_equal 'text/html;charset=utf-8', response['Content-Type']
|
||||
end
|
||||
|
||||
it 'sets the Content-Type response header if type option is set to a mime type' do
|
||||
send_file_app :type => 'application/octet-stream'
|
||||
get '/file.txt'
|
||||
assert_equal 'application/octet-stream', response['Content-Type']
|
||||
assert_equal 'application/octet-stream;charset=utf-8', response['Content-Type']
|
||||
end
|
||||
|
||||
it 'sets the Content-Length response header' do
|
||||
|
|
|
@ -2,20 +2,44 @@ require File.dirname(__FILE__) + '/helper'
|
|||
require 'less'
|
||||
|
||||
class LessTest < Test::Unit::TestCase
|
||||
def less_app(&block)
|
||||
def less_app(options = {}, &block)
|
||||
mock_app {
|
||||
set :views, File.dirname(__FILE__) + '/views'
|
||||
set options
|
||||
get '/', &block
|
||||
}
|
||||
get '/'
|
||||
end
|
||||
|
||||
it 'renders inline Less strings' do
|
||||
less_app { less "@white_color: #fff; #main { background-color: @white_color }"}
|
||||
less_app { less "@white_color: #fff; #main { background-color: @white_color }" }
|
||||
assert ok?
|
||||
assert_equal "#main { background-color: #ffffff; }\n", body
|
||||
end
|
||||
|
||||
it 'defaults content type to css' do
|
||||
less_app { less "@white_color: #fff; #main { background-color: @white_color }" }
|
||||
assert ok?
|
||||
assert_equal "text/css;charset=utf-8", response['Content-Type']
|
||||
end
|
||||
|
||||
it 'defaults allows setting content type per route' do
|
||||
less_app do
|
||||
content_type :html
|
||||
less "@white_color: #fff; #main { background-color: @white_color }"
|
||||
end
|
||||
assert ok?
|
||||
assert_equal "text/html;charset=utf-8", response['Content-Type']
|
||||
end
|
||||
|
||||
it 'defaults allows setting content type globally' do
|
||||
less_app(:less => { :content_type => 'html' }) do
|
||||
less "@white_color: #fff; #main { background-color: @white_color }"
|
||||
end
|
||||
assert ok?
|
||||
assert_equal "text/html;charset=utf-8", response['Content-Type']
|
||||
end
|
||||
|
||||
it 'renders .less files in views path' do
|
||||
less_app { less :hello }
|
||||
assert ok?
|
||||
|
|
|
@ -80,7 +80,7 @@ class RoutingTest < Test::Unit::TestCase
|
|||
|
||||
get '/foo'
|
||||
assert_equal 404, status
|
||||
assert_equal 'text/html', response["Content-Type"]
|
||||
assert_equal 'text/html;charset=utf-8', response["Content-Type"]
|
||||
assert_equal "<h1>Not Found</h1>", response.body
|
||||
end
|
||||
|
||||
|
|
|
@ -4,9 +4,10 @@ begin
|
|||
require 'sass'
|
||||
|
||||
class SassTest < Test::Unit::TestCase
|
||||
def sass_app(&block)
|
||||
def sass_app(options = {}, &block)
|
||||
mock_app {
|
||||
set :views, File.dirname(__FILE__) + '/views'
|
||||
set options
|
||||
get '/', &block
|
||||
}
|
||||
get '/'
|
||||
|
@ -18,6 +19,29 @@ class SassTest < Test::Unit::TestCase
|
|||
assert_equal "#sass {\n background-color: white; }\n", body
|
||||
end
|
||||
|
||||
it 'defaults content type to css' do
|
||||
sass_app { sass "#sass\n :background-color white\n" }
|
||||
assert ok?
|
||||
assert_equal "text/css;charset=utf-8", response['Content-Type']
|
||||
end
|
||||
|
||||
it 'defaults allows setting content type per route' do
|
||||
sass_app do
|
||||
content_type :html
|
||||
sass "#sass\n :background-color white\n"
|
||||
end
|
||||
assert ok?
|
||||
assert_equal "text/html;charset=utf-8", response['Content-Type']
|
||||
end
|
||||
|
||||
it 'defaults allows setting content type globally' do
|
||||
sass_app(:sass => { :content_type => 'html' }) do
|
||||
sass "#sass\n :background-color white\n"
|
||||
end
|
||||
assert ok?
|
||||
assert_equal "text/html;charset=utf-8", response['Content-Type']
|
||||
end
|
||||
|
||||
it 'renders .sass files in views path' do
|
||||
sass_app { sass :hello }
|
||||
assert ok?
|
||||
|
|
|
@ -4,9 +4,10 @@ begin
|
|||
require 'sass'
|
||||
|
||||
class ScssTest < Test::Unit::TestCase
|
||||
def scss_app(&block)
|
||||
def scss_app(options = {}, &block)
|
||||
mock_app {
|
||||
set :views, File.dirname(__FILE__) + '/views'
|
||||
set options
|
||||
get '/', &block
|
||||
}
|
||||
get '/'
|
||||
|
@ -18,6 +19,29 @@ class ScssTest < Test::Unit::TestCase
|
|||
assert_equal "#scss {\n background-color: white; }\n", body
|
||||
end
|
||||
|
||||
it 'defaults content type to css' do
|
||||
scss_app { scss "#scss {\n background-color: white; }\n" }
|
||||
assert ok?
|
||||
assert_equal "text/css;charset=utf-8", response['Content-Type']
|
||||
end
|
||||
|
||||
it 'defaults allows setting content type per route' do
|
||||
scss_app do
|
||||
content_type :html
|
||||
scss "#scss {\n background-color: white; }\n"
|
||||
end
|
||||
assert ok?
|
||||
assert_equal "text/html;charset=utf-8", response['Content-Type']
|
||||
end
|
||||
|
||||
it 'defaults allows setting content type globally' do
|
||||
scss_app(:scss => { :content_type => 'html' }) do
|
||||
scss "#scss {\n background-color: white; }\n"
|
||||
end
|
||||
assert ok?
|
||||
assert_equal "text/html;charset=utf-8", response['Content-Type']
|
||||
end
|
||||
|
||||
it 'renders .scss files in views path' do
|
||||
scss_app { scss :hello }
|
||||
assert ok?
|
||||
|
|
|
@ -15,9 +15,11 @@ class TestTemplate < Tilt::Template
|
|||
end
|
||||
|
||||
class TemplatesTest < Test::Unit::TestCase
|
||||
def render_app(base=Sinatra::Base, &block)
|
||||
def render_app(base=Sinatra::Base, options = {}, &block)
|
||||
base, options = Sinatra::Base, base if base.is_a? Hash
|
||||
mock_app(base) {
|
||||
set :views, File.dirname(__FILE__) + '/views'
|
||||
set options
|
||||
get '/', &block
|
||||
template(:layout3) { "Layout 3!\n" }
|
||||
}
|
||||
|
@ -156,6 +158,24 @@ class TemplatesTest < Test::Unit::TestCase
|
|||
assert_equal 'bar', body
|
||||
end
|
||||
|
||||
it 'allows setting default content type per template engine' do
|
||||
render_app(:str => { :content_type => :txt }) { render :str, 'foo' }
|
||||
assert_equal 'text/plain;charset=utf-8', response['Content-Type']
|
||||
end
|
||||
|
||||
it 'setting default content type does not affect other template engines' do
|
||||
render_app(:str => { :content_type => :txt }) { render :test, 'foo' }
|
||||
assert_equal 'text/html;charset=utf-8', response['Content-Type']
|
||||
end
|
||||
|
||||
it 'setting default content type per template engine does not override content_type' do
|
||||
render_app :str => { :content_type => :txt } do
|
||||
content_type :html
|
||||
render :str, 'foo'
|
||||
end
|
||||
assert_equal 'text/html;charset=utf-8', response['Content-Type']
|
||||
end
|
||||
|
||||
it 'uses templates in superclasses before subclasses' do
|
||||
base = Class.new(Sinatra::Base)
|
||||
base.template(:foo) { 'template in superclass' }
|
||||
|
|
Loading…
Reference in New Issue