sinatra-r18nというgemを使うと、Sinatraアプリを簡単にi18n(国際化)できるようになるので、NekostagramとInustagramに英語版のテキストも用意して、ブラウザーの言語設定で日本語or英語に分岐するようにした時の備忘録。ただし、このやり方だと後述するクローラー関連の問題がある。
sinatra-r18nのインストール
普通にgemをインストールする。
$ gem install sinatra-r18n
または、Bundlerを使っている場合は、Gemfileファイルにsinatra-r18n
を追加する。
gem 'sinatra-r18n'
i18n用のYAMLファイルの作成
プロジェクトフォルダ直下にi18n
フォルダを作成して、ja.yml
とen.yml
を用意する。ファイル名からお察しのとおり、それぞれ日本語版でのテキストと、英語版でのテキストを書いておく。例えば以下のような感じ。
site:
title: 'Nekostagram - ねこ大好き専用Instagram'
site:
title: 'Nekostagram - Cat Lovers Instagram Viewer'
上記のsite:
とかtitle:
は自分で勝手に付けた属性名なので、特に決まりはなく適当でおk
Nekostagramでは、それぞれja.yml
とen.yml
がこの部分に該当する。
使い方
まずrequire
する。ハイフンじゃなくてスラッシュなので注意。
require 'sinatra/r18n'
sinatra/r18n
をrequire
してあれば、t
オブジェクトから上記で設定した情報を参照できる。以下は、実際にNekostagramのソースコード内で使われているSlimコードの断片を簡略化したもの。r18n.locale.code
は現在表示している言語を取得でき、下記のコードでは日本語ならlogo.gif
、それ以外ならlogo_en.gif
のロゴ画像を読み込むように分岐している。img srcの文字列内での変数展開で、波カッコが二重になっているのは、Slimで変数展開する値をHTMLエンコードしない時の記法。
h1
a href='/'
- image_name = (r18n.locale.code == 'ja') ? 'logo' : 'logo_en'
img src="images/#{{image_name}}.gif" title="#{{t.site.title}}" alt="#{{t.site.title}}"
また、その後のtitle
属性・alt
属性でt
オブジェクトから、上述のYAMLで指定した属性を経由して、現在の言語の文字列を取得している。この分岐は自動でしてくれるので、単に参照するだけでおk
クローラー関連の問題
詳しくはこの記事にまとめてあって、まだ解決もしていないんだけど、推測では「クローラーのブラウザーの言語設定が英語になっているから」が原因だと思っている。なぜなら、最初は日本語版しかなかったNekostagramも、今は上記ライブラリを使用したi18n化が済んでおり、今GoogleでNekostagramを検索すると英語版のタイトルが表示されるようになっている。最初は日本語タイトルだったけど、時間経過で更新され、その時には既にi18n化していたことにより、英語版タイトルに更新されたものと思われる。はてブの場合も同様に、タイトルを取得するサーバーの言語設定が英語になっているからなんじゃないかなぁと。自動で分岐させる場合は、これは仕方ないのかもしれないと半ば諦めている。