symfony Forms in Action

第8章 - 国際化とローカライゼーション

You are currently browsing
the website for symfony 1

Visit the Symfony2 website


About

You are currently reading "symfony Forms in Action" which is licensed under the Creative Commons Attribution-Share Alike 3.0 Unported License license.

Master symfony

Be trained by SensioLabs experts (2 to 6 day sessions -- French or English).
trainings.sensiolabs.com

Books on symfony

Learn more about symfony with the official guides.
books.sensiolabs.com

L'audit Qualité par SensioLabs

200 points de contrôle de votre applicatif web.
audit.sensiolabs.com

Chapter Content

フォームの国際化

翻訳のために使うカタログを指定する

エラーメッセージの国際化

翻訳オブジェクトのカスタマイズ

パラメータとして受容できる翻訳の callable

Propel のオブジェクトの国際化

ローカライズされたウィジェット

日付セレクタ

国セレクタ

カルチャセレクタ

symfony training
Be trained by symfony experts
Feb 21: Köln (Getting Started with Symfony2 - English)
Feb 27: Köln (Mastering Symfony2 - English)
Mar 05: Köln (Web Development with Symfony2 - Deutsch)
Mar 05: Montreal (Web Development with Symfony2 - English)
Mar 05: Montreal (Getting Started with Symfony2 - English)
and more...

Search


powered by google
You are currently browsing "symfony Forms in Action" in Japanese for the 1.2 version - Switch to version: - Switch to language:
Creative Commons License This work is licensed under a Creative Commons Attribution-Share Alike 3.0 Unported License.
This version of symfony is not maintained anymore.
If some of your projects still use this version, consider upgrading as soon as possible.

人気のある Web アプリケーションの多くはさまざまな言語で利用可能で、ときにはユーザーカルチャに基づいてカスタマイズされます。 symfony はこれらの機能の管理を楽にする組み込みのフレームワークを搭載しています (symfony book の「国際化とローカライゼーション」の章を参照)。

フォームフレームワークはユーザーのインターフェイス用の組み込みサポートを備えており国際化オブジェクトの管理を楽にする方法を提供します。

フォームの国際化

symfony のフォームはデフォルトで国際化が可能です。 翻訳ファイルを編集することでラベルヘルパーテキストエラーメッセージを翻訳できます。 これらは XLIFFgettext もしくは symfony がサポートするその他のフォーマットです。

リスト8-1は以前の章で開発した問い合わせフォームを示します。

リスト8-1 - 問い合わせフォーム

class ContactForm extends sfForm
{
  public function configure()
  {
    $this->setWidgets(array(
      'name'  => new sfWidgetFormInput(),    // デフォルトのラベルは "Name"
      'email' => new sfWidgetFormInput(),    // デフォルトのラベルは "Email"
      'body'  => new sfWidgetFormTextarea(), // デフォルトのラベルは "Body"
    ));
 
    // email ウィジェットのラベルを変更する
    $this->widgetSchema->setLabel('email', 'Email address');
  }
}

リスト8-2で示されるようにラベルのフランス語訳を XLIFF で定義します。

リスト8-2 - XLIFF 翻訳ファイル

// apps/frontend/i18n/messages.fr.xml
<?xml version="1.0" ?>
<xliff version="1.0">
  <file original="global" source-language="en" datatype="plaintext">
    <body>
      <trans-unit>
        <source>Name</source>
        <target>Nom</target>
      </trans-unit>
      <trans-unit>
        <source>Email address</source>
        <target>Adresse email</target>
      </trans-unit>
      <trans-unit>
        <source>Body</source>
        <target>Message</target>
      </trans-unit>
    </body>
  </file>
</xliff>

翻訳のために使うカタログを指定する

symfony の国際化フレームワークの機能を利用する場合 (http://www.symfony-project.org/book/1_2/13-I18n-and-L10n#chapter_13_sub_managing_dictionaries)、フォームを特定のカタログにバインドできます。 リスト8-3において、ContactForm フォームを contact_form カタログに関連づけします。 ですので、フォーム要素の翻訳は contact_form.fr.xml ファイルで捜索されます。

リスト8-3 - 翻訳カタログのカスタマイズ

class ContactForm extends sfForm
{
  public function configure()
  {
    // ...
 
    $this->widgetSchema->getFormFormatter()->setTranslationCatalogue('contact_form');
  }
}

カタログを利用することでたとえばフォームごとに1つのファイルを使用する翻訳の編成がよりベターになります。

エラーメッセージの国際化

ときどき、エラーメッセージにはユーザーによって投稿された値が埋め込まれます(たとえば、 「メールアドレスのuser@domainは有効ではありません。」)。 これをフォームクラスの中でカスタマイズされたエラーメッセージを定義してユーザーが投稿した値を簡単に利用できることを2章ですでに見ました。 これらの参照は %parameter_name% のパターンに従います。

リスト8-4はこの原則を問い合わせフォームの name フィールドに適用する方法を示しています。

リスト8-4 - エラーメッセージの国際化

class ContactForm extends sfForm
{
  public function configure()
  {
    // ...
 
    $this->validatorSchema['name'] = new sfValidatorEmail(
      array('min_length' => 2, 'max_length' => 45),
      array('min_length' => 'Name "%value%" must be at least %min_length% characters.',
            'max_length' => 'Name "%value%" must not exceed %max_length% characters.',
      ),
    );
  }
}

リスト8-5で示されるように XLIFF ファイルを編集することでこれらのエラーメッセージを翻訳できます。

リスト8-5 - エラーメッセージ用の XLIFF 翻訳ファイル

<trans-unit>
  <source>Name "%value%" must be at least %min_length% characters</source>
  <target>Le nom "%value%" doit comporter un minimum de %min_length% caractères</target>
</trans-unit>
<trans-unit>
  <source>Name "%value%" must not exceed %max_length% characters</source>
  <target>Le nom "%value%" ne peut comporter plus de %max_length% caractères</target>
</trans-unit>

翻訳オブジェクトのカスタマイズ

symfony の国際化フレームワークなしで symfony のフォームフレームワークを使いたい場合、翻訳オブジェクトを提供する必要があります。

翻訳オブジェクトは PHP の単なる callable です。これは次の3つのものの1つです:

PHP の callable は関数もしくはメソッドのインスタンスへの参照です。 これは is_callable() 関数に渡されるときに true を返す PHP 変数でもあります。

リスト8-6で示されるクラスによって提供される独自の国際化メカニズムをすでに持つプロジェクトをマイグレートしなければならない場合を考えてみましょう。

リスト8-6 - カスタムの国際化クラス

class myI18n
{
  static protected $default_culture = 'en';
  static protected $messages = array('fr' => array(
    'Name'    => 'Nom',
    'Email'   => 'Courrier électronique',
    'Subject' => 'Sujet',
    'Body'    => 'Message',
  )); 
 
  static public function translateText($text)
  {
    $culture = isset($_SESSION['culture']) ? $_SESSION['culture'] : self::$default_culture; 
    if (array_key_exists($culture, self::$messages)
        && array_key_exists($text, self::$messages[$culture]))
    {
      return self::$messages[$_SESSION['culture']][$text];
    }
    return $text;
  }
}
 
// クラスの使い方
$myI18n = new myI18n();
 
$_SESSION['culture'] = 'en';
echo $myI18n->translateText('Subject'); // => "Subject"を表示する
 
$_SESSION['culture'] = 'fr';
echo $myI18n->translateText('Subject'); // => "Sujet"を表示する

リスト8-7で示されるようにそれぞれのフォームはフォームの要素の国際化を管理する独自のcallableを定義できます。

リスト8-7 - フォームのための国際化メソッドをオーバーライドする

class ContactForm extends sfForm
{
  public function configure()
  {
    // ...
    $this->widgetSchema->getFormFormatter()->setTranslationCallable(array(new myI18n(), 'translateText'));
  }
}

パラメータとして受容できる翻訳の callable

翻訳の callable は3つの引数を取ります:

下記のコードは翻訳の callable を呼び出すために sfFormWidgetSchemaFormatter::translate() メソッドによって使われる呼び出しです:

return call_user_func(self::$translationCallable, $subject, $parameters, $catalogue);

self::$translationCallable は翻訳の callable への参照です。ですので、以前のコードは下記のものと同等です:

$myI18n->translateText($subject, $parameters, $catalogue);

下記のコードはこれらの追加の引数をサポートする MyI18n クラスのアップデートされたバージョンです:

class myI18n
{
  static protected $default_culture = 'en';
  static protected $messages = array('fr' => array(
    'messages' => array(
      'Name'    => 'Nom',
      'Email'   => 'Courrier électronique',
      'Subject' => 'Sujet',
      'Body'    => 'Message',
    ),
  ));
 
  static public function translateText($text, $arguments = array(), $catalogue = 'messages')
  {
    $culture = isset($_SESSION['culture']) ? $_SESSION['culture'] : self::$default_culture; 
    if (array_key_exists($culture, self::$messages) &&
        array_key_exists($messages, self::$messages[$culture] &&
        array_key_exists($text, self::$messages[$culture][$messages]))
    {   
      $text = self::$messages[$_SESSION['culture']][$messages][$text];
      $text = strtr($text, $arguments);
    }   
    return $text;
  }
}

Propel のオブジェクトの国際化

フォームフレームワークは国際化された Propel オブジェクト用の組み込みサポート機能を持ちます。 これが動作する方法を説明するために国際化されたモデルの例を見てみましょう:

propel:
  article:
    id:
    author:     varchar(255)
    created_at:
  article_i18n:
    title:      varchar(255)
    content:    longvarchar

次のコマンドで Propel のクラスと関連するフォームクラスを生成できます:

$ php symfony build:model
$ php symfony build:forms

これらのコマンドはsymfonyのプロジェクトディレクトリの中で次のようなファイルを生成します:

lib/
  form/
    ArticleForm.class.php
    ArticleI18nForm.class.php
    BaseFormPropel.class.php
  model/
    Article.php
    ArticlePeer.php
    ArticleI18n.php
    ArticleI18nPeer.php

リスト8-8は同じフォームでフランス語と英語の記事を編集できるようにするために ArticleForm を設定する方法を示しています。

リスト8-8 - 国際化された Propel オブジェクト用の国際化フォーム

class ArticleForm extends BaseArticleForm
{
  public function configure()
  {
    $this->embedI18n(array('en', 'fr'));
  }
}

リスト8-9で示されるように次のコードを configure() メソッドに追加することでフォームの言語ラベルをカスタマイズすることもできます。

リスト8-9 - 言語ラベルのカスタマイズ

$this->widgetSchema->setLabel('en', 'English');
$this->widgetSchema->setLabel('fr', 'French');

図8-1 - 国際化対応の Propel フォーム

国際化対応の Propel フォーム

これでお終いです。フォームオブジェクトの save() メソッドを呼び出すとき、関連する Propel オブジェクトと国際化オブジェクトは自動的に保存されます。

ローカライズされたウィジェット

symfony のフォームフレームワークは国際化を「認識する」(aware) いくつかのウィジェットを搭載しています。 ユーザーカルチャに従ってウィジェットをローカライズするためにこれらを使うことができます。

日付セレクタ

日付をローカライズするために利用できるウィジェットは下記のとおりです:

国セレクタ

sfWidgetFormI18nSelectCountry ウィジェットは国のリストで満たされた選択ボックスを表示します。 国の名前は指定された言語に翻訳されます:

$this->widgetSchema['country'] = new sfWidgetFormI18nSelectCountry(array('culture' => 'fr'));

countries オプションのおかげで、選択ボックス内の国を制限することもできます:

$countries = array('fr', 'en', 'es', 'de', 'nl');
$this->widgetSchema['country'] = new sfWidgetFormI18nSelectCountry(array('culture'   => 'fr',
                                                                         'countries' => $countries));

カルチャセレクタ

sfWidgetFormI18nSelectLanguage ウィジェットは言語の一覧で満たされた選択ボックスを表示します。 言語の名前は指定された言語に翻訳されます:

$this->widgetSchema['language'] = new sfWidgetFormI18nSelectLanguage(array('culture' => 'fr'));

languages オプションのおかげで、選択ボックスの言語を制限することもできます:

$languages = array('fr', 'en', 'es', 'de', 'nl');
$this->widgetSchema['language'] = new sfWidgetFormI18nSelectLanguage(array('culture'   => 'fr',
                                                                           'languages' => $languages));

Questions & Feedback

If you find a typo or an error, please register and open a ticket.

If you need support or have a technical question, please post to the official user mailing-list.