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
May 29: Paris (Web Development with Symfony2 - Français)
May 31: Paris (Mastering Symfony2 - Français)
Jun 06: Paris (Introduction to Symfony2 - Français)
Jun 06: Paris (Introduction to Symfony2 - English)
Jun 06: Paris (Going Further with Symfony2 - English)
and more...

Search


powered by google
You are currently browsing "symfony Forms in Action" in Japanese for the 1.4 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.

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

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

フォームの国際化

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

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

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

class ContactForm extends BaseForm
{
  public function configure()
  {
    $this->setWidgets(array(
      'name'  => new sfWidgetFormInputText(),    // デフォルトのラベルは "Name"
      'email' => new sfWidgetFormInputText(),    // デフォルトのラベルは "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 の国際化フレームワークの機能を利用する場合、フォームを特定のカタログにバインドできます(カタログは「A Gentle Introduction to symfony」の「国際化とローカライゼーションの章」をご参照ください) 。 リスト8-3において、ContactForm フォームを contact_form カタログに関連づけます。ですので、フォーム要素の翻訳は contact_form.fr.xml ファイルで捜索されます。

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

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

カタログを使うことで、たとえばフォームごとに1つのファイルを使った翻訳の組織化が改善されます。

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

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

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

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

class ContactForm extends BaseForm
{
  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'); // => 「Suject」を表示します

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

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

class ContactForm extends BaseForm
{
  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) いくつかのウィジェットを搭載しています。ユーザーカルチャにしたがってウィジェットをローカライズするためにこれらのウィジェットを使うことができます。

日付セレクタ

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

カントリ (国コード) セレクタ

sfWidgetFormI18nChoiceCountry ウィジェットは国コードのリストで満たされたセレクトボックスを表示します。国コードの名前は指定された言語に翻訳されます。

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

countries オプションのおかげで、セレクトボックス内の国コードを制限することもできます。

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

カルチャセレクタ

sfWidgetFormI18nChoiceLanguage ウィジェットは言語コードの一覧で満たされたセレクトボックスを表示します。言語コードの名前は指定された言語に翻訳されます。

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

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

$languages = array('fr', 'en', 'es', 'de', 'nl');
$this->widgetSchema['language'] = new sfWidgetFormI18nChoiceLanguage(array('culture'   => 'fr',
                                                                           'languages' => $languages));
                                                                           ### タイムゾーンセレクタ

sfWidgetFormI18nChoiceTimezone ウィジェットはタイムゾーンで満たされたセレクトボックスを表示します。

$this->widgetSchema['timezone'] = new sfWidgetFormI18nChoiceTimzione();

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.