diff --git a/README.de.rdoc b/README.de.rdoc index 79fe9f99..34c14868 100644 --- a/README.de.rdoc +++ b/README.de.rdoc @@ -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 diff --git a/README.jp.rdoc b/README.jp.rdoc index ad8250a1..7cf6bbe3 100644 --- a/README.jp.rdoc +++ b/README.jp.rdoc @@ -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 diff --git a/README.rdoc b/README.rdoc index b6d00b11..74603d28 100644 --- a/README.rdoc +++ b/README.rdoc @@ -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 diff --git a/lib/sinatra/base.rb b/lib/sinatra/base.rb index 4d004998..97796f62 100644 --- a/lib/sinatra/base.rb +++ b/lib/sinatra/base.rb @@ -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 diff --git a/test/builder_test.rb b/test/builder_test.rb index 04ab3a58..92a0ffe3 100644 --- a/test/builder_test.rb +++ b/test/builder_test.rb @@ -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 %{\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" diff --git a/test/coffee_test.rb b/test/coffee_test.rb index c71f9d25..f9677ae7 100644 --- a/test/coffee_test.rb +++ b/test/coffee_test.rb @@ -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? diff --git a/test/helper.rb b/test/helper.rb index 70699295..2220ebca 100644 --- a/test/helper.rb +++ b/test/helper.rb @@ -1,4 +1,5 @@ ENV['RACK_ENV'] = 'test' +Encoding.default_external = "UTF-8" if defined? Encoding begin require 'rack' diff --git a/test/helpers_test.rb b/test/helpers_test.rb index 57165461..ce58714c 100644 --- a/test/helpers_test.rb +++ b/test/helpers_test.rb @@ -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' "