多言語対応ウェブアプリを作る前に知っておきたい事
はじめに
最近仕事で、他言語対応(主に英語)のアプリを初めて作った訳ですが、事前準備を色々したにもかかわらず、翻訳、コーディング、サーバー構築などあらゆる分野で大変苦労したので気をつけたい点を共有します。ちなみに自分が担当した部分は、日→英→独仏のみで RTLなどの言語は含まれません。
押さえておきたい単語
プログラミング
- 日付のフォーマットは、国毎に表現が違う。Railsの場合、I18n.lで自動変換可能。
- 【日】2014年3月10日
- 【米】03/10/2014
- 【独】10.3.2014
- 国によって小数点や千単位の区切り方が違う。バリエーションが多すぎるので、ライブラリ使っての対応が必須。Railsの場合、number_with_delimiterで実現可能。気になる人に→バリエーションリスト。
- 英語は単数形(Singular)、複数形(Plural)、所有格(Possessive)などで単語が変わる。これらはとにかくルールが多い上に例外も沢山あるのでライブラリ必須。Rails の場合、rails-i18n で対応可能。(Possessive対応には possessive gem)
- 米国だけメートル法ではなくヤード・ポンド法、摂氏ではなく華氏。Railsの場合、rails-unitsで変換可能。
- 英語では例えば、「リンゴ100個」を翻訳した場合、「100 Apples」となり、単位が主語の先頭にくる+助数詞が無い。単位と主語を1つの翻訳データとして扱わないと英語で表現できなくなる。
- 悪い例)コード:
t(".apple") + count
- 良い例)コード:
t(".x_items", item: t(".apple"), count: count)
翻訳の定義(英):x_items: "%{count} %{item}"
翻訳の定義(日):x_items: "%{item}%{count}個"
- 悪い例)コード:
- DBデータは翻訳部分だけ切り出して別のテーブルを作る。国別にサーバーを持つなら、国毎に翻訳データを編集することもでるが、更新作業にかかるコストが高い上に間違えやすいのでお勧めしない。Railsの場合、Globalizeがお勧。
- Javascriptを使う場合、サーバー側の文字列を直接持たせないようにする。handlebarsやunderscoreの_.templateを使って、なるべくロジックをHTML側に書く。
- どうしてもJS側で出力する場合、クオテーション(’)やダブルクオテーション(”)は、エスケープして出力させる必要がある。よく英語圏ユーザーの入力データーで使われているので、要注意。Railsの場合、<%=j %>で簡単にエスケープ可能。
- 英語は基本日本語より文字が長くなる。ドイツ語はもっと長くなる。事前にこうなる事を想定してボタンなどの横幅に余裕を持ったデザインにしておく事が理想的。だが、完全に事前把握するのは困難なので、崩れたデザイン部分は後追いで、CSSでルールを上書いて対処する。例えば、
.title
というルールがあるとする。そして英語版でルールを上書きしたいとする。その場合、body などの要素のヒエラルキーのトップに、.lang-[言語]
(例えば.lang-en
)などのクラス名を追加して、.lang-en .title
というルールを定義することで、英語版専用のプロパティを適応する事ができる。 - あまりに表現が苦しい時は、文字ではなく画像で対応するのもあり。画像にしたら、配置やフォントを自由に行えるので便利。これを実現する場合、言語専用パスを画像にも設ける必要有り。
- ユーザー入力に対するNGワードフィルタなどは、言語毎に特徴が異なるので、慎重に導入する必要がある。下手するとフィルタしたくない言葉まで大量にフィルタしてしまう事になる。
システム設定
- アセット(画像、CSS、JS)はなるべくAkamaiなどのCDNサービスを使う。理由は、日本から米国までの通信は~200msほどかかる。欧州までは、~300msほどかかるため。
- 時間の保存には必ずUTCを必ず使う。間違っても米国とかDST(サマータイム)を使っている国に設定してはいけない。例えば、サーバーの設定をカルフォルニアに設定していると、3月9日から11月2日までは、時差が-7時間だが、それ以外の時は時差が-8時間になるので、時間の計算をする過程で計算がズレる可能性がある。
- サーバーのシステム設定でもUTCを使う。最悪でもDSTを使わない地域に設定しておく。これがDST有りの地域だとcrontabがDSTの切り替わりのタイミングでおかしな動作をする。crontabの仕様としては、1時間以上の感覚で実行されるジョブはDSTで時間が進んだ時には即実行され、時間が遅れた時には2度実行されないようになっていて、1時間以内の感覚で実行されるジョブは普通にスケジュールされる。詳しくは crontab の man page 。
- サーバー、ミドルウェア、アプリケーション全てのタイムゾーンを一致させる。一つでも違う値を使っていると運営がカオスになる。後で発見しても移行後の動作確認が地獄に。
- 【MySQL限定】コラムの utf8 ではなく utf8mb4に設定する。MySQLのutf8は 3バイトまでしか対応していないので、一部の絵文字などに対応できない。ちなみになぜ絵文字対応?と思うかも知しれないが、最近は海外のアンドロイド端末で絵文字がデフォルトで使えるらしい。ちなみにutf8mb4は、MySQL 5.5.3以降のみ対応。
その他豆知識
最後に
如何でしょうか。
自分は上記の内容を把握できずに見積もりを立てたのでプロジェクトがデスマーチとなってしまいました。
皆さんも見積もりを立てる時はお気をつけて。