1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

SinatraのerbメソッドでContent negotiationをサポートする

Last updated at Posted at 2012-11-06

Sinatraのerbメソッドは標準ではContent negotiationをサポートしていません。そこで、ユーザエージェント(Webブラウザ)がリクエストに指定したAccept-Languageヘッダの値をもとに、テンプレートを自動的に選択することができるメソッド(erb_l)を新たに定義します。

多分、sinatra-r18nかSinatra本家がサポートするまでの間の暫定対応。

準備

以下のgemが必要です。適当にgem installしておいて下さい。

  • i18n
  • rack-contrib

コード

アプリ

test_app.rb
# coding: utf-8
require 'rack/contrib'
require 'sinatra/base'

class TestApp < Sinatra::Base
  use Rack::Locale

  helpers do
    # erb with content negotiation support
    def erb_l(template, options = {}, locals = {})
      locale = request.env['rack.locale']
      if locale.nil? or locale.to_s !~ /^\w+$/
        erb(template, options, locals)
      end

      tmpl = "#{template.to_s}_#{locale}".to_sym

      begin
        erb(tmpl, options, locals)
      rescue Errno::ENOENT
        erb(template, options, locals)
      end
    end
  end

  get '/' do
    erb_l :index
  end
end

erb_lメソッドは、Accept-Languageヘッダの値に基いて、読み込むテンプレートのファイルを決定します。上記の例の場合、日本語を優先する設定のWebブラウザからのリクエストの場合にはindex_ja.erbを、英語を優先するWebブラウザからのリクエストの場合にはindex_en.erbをテンプレートとして使用します。これらのファイルが存在しない場合、index.erbをテンプレートとして使用します。

テンプレートの例

views/index.erb
<%# coding: utf-8 %>
<html>
  <body>
    <h1>Hello, world</h1>
  </body>
</html>
views/index_ja.erb
<%# coding: utf-8 %>
<html>
  <body>
    <h1>こんにちは世界</h1>
  </body>
</html>

config.ru

config.ru
require 'rubygems'
require File.join(File.dirname(__FILE__), 'test_app.rb')

run TestApp

実行例

テストのため、上記のアプリを起動しておきます。

% rainbows -E production -p 8080 config.ru

Accept-Languageヘッダを指定しない場合、標準のindex.erbが使われます。

% wget -nv -4 -O - http://localhost:8080/
<html>
  <body>
    <h1>Hello, world</h1>
  </body>
</html>

Accept-Language: enの場合。index_en.erbの利用を試みますが、これは存在しませんので、index.erbが使われます。

% wget -nv -4 -O - --header='Accept-Language: en' http://localhost:8080/
<html>
  <body>
    <h1>Hello, world</h1>
  </body>
</html>

Accept-Language: ja,enの場合。index_ja.erbが使われます。

% wget -nv -4 -O - --header='Accept-Language: ja,en' http://localhost:8080/
<html>
  <body>
    <h1>こんにちは世界</h1>
  </body>
</html>

Accept-Language: frの場合。index_fr.erbの利用を試みますが、これは存在しませんので、index.erbが使われます。

% wget -nv -4 -O - --header='Accept-Language: fr' http://localhost:8080/
<html>
  <body>
    <h1>Hello, world</h1>
  </body>
</html>
1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?