CodeZine(コードジン)

特集ページ一覧

symfony入門(5):symfonyプログラミング 開発のテクニック(中篇)

symfonyによる実践的なPHPアプリケーション開発

  • LINEで送る
  • このエントリーをはてなブックマークに追加
2007/05/23 08:00
目次

ユーザーインターフェイスの翻訳

 一口に「国際化機能」と言った時、漠然と思い浮かぶのは文面の翻訳でしょう。これは、XMLファイルで言語別の内容を記述し整理することで実現します。XLIFF(XML Localization Interchange File Format)ファイルと言います。具体的には「messages.<言語名>.xml」という名前でアプリケーションフォルダ内の「i18n」フォルダに配置され、次のような内容です。

messages.ja.xml
<?xml version="1.0" ?>
<xliff version="1.0">
  <file orginal="global" source-language="en_US" datatype="plaintext">
  (元テキストの言語を設定)
    <body>
      <trans-unit id="1">
      (この括りで、原文と訳文をセットにする。
      idはXLIFF作成ツール等によってつけられるユニークな識別属性)
        <source>Welcome to our website.</source>
        (原文。「__()」ヘルパー(後述)内の原文がこの要素内の原文と
        一致すれば、その下の<target>要素内の訳文に変換される)
        <target>私たちのウェブサイトへようこそ。</target>  (訳文)
      </trans-unit>
      <trans-unit id="2">
        <source>LATEST NEWS </source>
        <target>最新ニュース </target>
      </trans-unit>
    </body>
  </file>
</xliff>

 <file>要素の属性については次のとおりです。

<file>要素の属性
属性内容
original原文ファイルの場所。この場合の「global」はそのアプリケーション全体という意味
source-language<source>要素内の言語
datatype原文ファイルのテキストの種類。plaintext(プレーンテキスト)の他にhtml(HTML)やphp(PHP)などがある

 このファイルはテンプレートにおいて__()関数が呼び出された時に参照されます。例示したファイルは、下記のメッセージを日本語で表示するためのもので、

Welcome to our website.
LATEST NEWS
...

 これを次のようにして活用します。

<?php use_helper('I18N') ?>       (I18Nヘルパーの使用を宣言)

<?php echo __('Welcome to our website.') ?>
                                  (一つ目のtrans-unitに対応)
<?php echo __("LATEST NEWS ") ?>  (二つ目のtrans-unitに対応)
...

 また、下記のように文字列中に「%1%」などを用い置き換えることも可能です。

<?php __('Your payment is %1%. Are you sure?',
  array('%1%' => $a->getPayment()) ) ?>
複数形の扱い
 form_number_choice()というヘルパーを使うと、単数系/複数形を使い分けたい箇所の数字から条件分岐をすることが可能になります。
(Definitive Guideより引用)
<?php echo format_number_choice(
  '[0]Nobody is logged|[1]There is 1 person logged|(1,+Inf]
There are%1% persons logged', array('%1%' => count_logged()), count_logged()) ?>
 第3引数が出す数の大小で、第1引数に挙げられた複数のテキスト(「|」で区切られます)の内の1つが選ばれます。第2引数は__()ヘルパーと同様です。
 第1引数のテキストの区切りの最初にある括弧と数字の組み合わせは、そのテキストが選ばれる条件となる(第3引数が示す数の)範囲を示します。上記の例では、count_logged()が0なら最初のテキストが、1なら2つ目のテキストが、それ以上なら3つめのテキストが選ばれます。他の例を以下に示します。
第1引数の範囲表記
表記範囲
[1,5]1以上5以下
(1,5)1より大きく5未満
{1,5,7,15}1・5・7・15のいずれか
(5,15]5より大きく15以下
[-Inf,5)5未満

 messages.XX.xmlファイルが長すぎる場合などには、テーマに応じた任意の名前(<テーマ名>.<言語名>.xml)でファイルを分割することができます。具体的には、messages.fr.xmlファイルを次のようなファイルに分割して、「i18n/」フォルダに配置します。

  • contents.fr.xml
  • news.fr.xml
  • weather.fr.xml

 この場合は__()ヘルパーの第3引数でどのファイルを使うのかを明記します。

<?php echo __('LATEST NEWS', null,
  'news(「XXXXX.YY.xml」のXXXXXの部分)') ?>

 また、messages.XX.xmlファイルをモジュールごとに、つまり「modules/<モジュール名>/i18n/」フォルダにそれらを配置することもできます。

国際化機能を利用したサンプル

 これまで紹介した機能を一部用いて、実際に国際化に対応した簡単なアプリケーションを作成してみます。

 国名と言語と現在時刻を表示し、選択ボックスでカルチャを選べる(updateアクション)ようにします。

 以下にテンプレートとアクション、XLIFFファイルを示します。

indexSuccess.php
<?php use_helper('I18n', 'Date') ?>
<?php echo __('こんにちは!') ?>
  (XLIFFファイルの<trans-unit id="1">の部分)
<br />
<?php echo __('国:').format_country(substr($sf_user->getCulture(),-2)) ?>
  (id="2"の部分。カルチャの末尾2文字を持ってきている)
<br />
<?php echo __('言語:').format_language(substr($sf_user->getCulture(),0,2)) ?>
  (id="3"の部分。カルチャの先頭2文字を持ってきている)
<br />
<?php echo __('ただ今 %1% です', array('%1%' => format_datetime(time()))) ?>
  (id="4"の部分)
<br />

<?php echo form_tag('i18n_test/update') ?>
<?php echo select_country_tag('country', 'JP') ?>
  (国の選択ボックス)
<br />
<?php echo select_language_tag('language', 'ja') ?>
  (言語の選択ボックス)
<br />
<?php echo submit_tag('Go') ?>
</form>
actions.class.php
<?php

/**
 * i18n_test actions.
 *
 * @package    sym5
 * @subpackage i18n_test
 * @author     Your name here
 * @version    SVN: $Id: actions.class.php 2692 2006-11-15 21:03:55Z fabien $
 */
class i18n_testActions extends sfActions
{
  /**
   * Executes index action
   *
   */
  public function executeIndex()
  {
  }

  public function executeUpdate()
  {
    $l = $this->getRequestParameter('language');
    $c = $this->getRequestParameter('country');

    $this->getUser()->setCulture($l.'_'.$c);

    $this->redirect('i18n_test/index');
  }

}
messages.en.xml
<?xml version="1.0" ?>
<xliff version="1.0">
  <file orginal="global" source-language="ja_JP" datatype="plaintext">
    <body>
      <trans-unit id="1">
        <source>こんにちは!</source>
        <target>Hello!</target>
      </trans-unit>
      <trans-unit id="2">
        <source>国:</source>
        <target>country:</target>
      </trans-unit>
      <trans-unit id="3">
        <source>言語:</source>
        <target>language:</target>
      </trans-unit>
      <trans-unit id="4">
        <source>ただ今 %1% です</source>
        <target>Today's date is %1%.</target>
      </trans-unit>
    </body>
  </file>
</xliff>

 結果は次のようになります。英語を選択すると英語が表示されるのが分かります(なお、選択した国と言語の組み合わせが妥当でない場合には例外が発生します)。

i18nアプリケーション例
i18nアプリケーション例
英語での表示
英語での表示

 また、フォームヘルパーのリストについてはXLIFFファイルなしに既に国際化されているのが分かります。

選択ボックスの言語も変わる
選択ボックスの言語も変わる
選択ボックスの中身はxmlファイルを用意していなくても対応
選択ボックスの中身はxmlファイルを用意していなくても対応

  • LINEで送る
  • このエントリーをはてなブックマークに追加

バックナンバー

連載:symfony入門

著者プロフィール

  • WINGSプロジェクト 川北 季(カワキタ ミノル)

    <WINGSプロジェクトについて> 有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂...

  • 山田 祥寛(ヤマダ ヨシヒロ)

    静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for ASP/ASP.NET。執筆コミュニティ「WINGSプロジェクト」代表。 主な著書に「入門シリーズ(サーバサイドAjax/XM...

あなたにオススメ

All contents copyright © 2005-2021 Shoeisha Co., Ltd. All rights reserved. ver.1.5