symfonyのアドミンジェネレーターをもっと日本語化する

以前にsfFormの表示を日本語化する方法について記事にかきました*1が、今回はそのsfFormを利用しているアドミンジェネレーターでも日本語化してみようとふと思い立ったのでその記録です。

あまり知られていませんが、symfony1.2以降のsymfonyのアドミンジェネレーターは標準で日本語化できます。(翻訳ファイル(カタログ)が不完全なので全部ではありませんが)

手順は至って簡単です。

標準の日本語化

apps/<アプリケーション名>/config/settings.ymlに記述を追加
all:
  .settings:
    default_culture:        ja
    i18n:                   on
キャッシュとCookieの消去
  • キャッシュを消去する
  • Cookieの影響でcultureの変更が効かない場合があるので、日本語化にならないときはCookieも削除してみる

たったこれだけです。以前書いた記事のようにカタログファイルを用意しなくて良いのでもっと簡単です。

フィルターやフォームも日本語する

「すべてが日本語になったわけでないのでいまいちだなぁー」という場合は翻訳ファイルを用意し、そのファイルをsetTranslationCatalogueで指定すればいいだけです。

というわけで、基となるカタログファイル(/lib/plugins/sfDoctrinePlugin/i18n/sf_admin.ja.xml)を<アプリケーション>/i18n/sf_admin.ja.xmlとしてコピーし追加していきます。

とりあえず翻訳してみたsf_admin.ja.xmlファイル

このサンプルはsymfony1.4のソースから翻訳対象となる部分をgrepし追加したものです。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE xliff PUBLIC "-//XLIFF//DTD XLIFF//EN" "http://www.oasis-open.org/committees/xliff/documents/xliff.dtd" >
<xliff version="1.0">
  <file original="global" source-language="en" datatype="plaintext">
    <header />
    <body>
      <!-- Actions -->
      <trans-unit>
        <source>New</source>
        <target>新規作成</target>
      </trans-unit>
      <trans-unit>
        <source>Edit</source>
        <target>編集</target>
      </trans-unit>
      <trans-unit>
        <source>Delete</source>
        <target>削除</target>
      </trans-unit>
      <trans-unit>
        <source>List</source>
        <target>一覧</target>
      </trans-unit>
      <trans-unit>
        <source>Save</source>
        <target>保存</target>
      </trans-unit>
      <trans-unit>
        <source>Save and add</source>
        <target>保存して更に追加</target>
      </trans-unit>
      <trans-unit>
        <source>Cancel</source>
        <target>キャンセル</target>
      </trans-unit>
      <trans-unit>
        <source>Choose an action</source>
        <target>アクションを選択</target>
      </trans-unit>
      <trans-unit>
        <source>go</source>
        <target>実行</target>
      </trans-unit>
      <trans-unit>
        <source>Back to list</source>
        <target>リストに戻る</target>
      </trans-unit>

      <!-- Filters -->
      <trans-unit>
        <source>Reset</source>
        <target>リセット</target>
      </trans-unit>
      <trans-unit>
        <source>Filter</source>
        <target>検索</target>
      </trans-unit>

      <!-- List -->
      <trans-unit>
        <source>No result</source>
        <target>データがありません</target>
      </trans-unit>
      <trans-unit>
        <source>Actions</source>
        <target>操作</target>
      </trans-unit>
      <trans-unit>
        <source>(page %%page%%/%%nb_pages%%)</source>
        <target>(ページ %%page%%/%%nb_pages%%)</target>
      </trans-unit>
      <trans-unit>
        <source>asc</source>
        <target>降順</target>
      </trans-unit>
      <trans-unit>
        <source>desc</source>
        <target>昇順</target>
      </trans-unit>
      <trans-unit>
        <source>[0] no result|[1] 1 result|(1,+Inf] %1% results</source>
        <target>[0] 0件|[1] 1件|(1,+Inf] %1% 件</target>
      </trans-unit>

      <!-- Pagination -->
      <trans-unit>
        <source>First page</source>
        <target>最初のページ</target>
      </trans-unit>
      <trans-unit>
        <source>Previous page</source>
        <target>前のページ</target>
      </trans-unit>
      <trans-unit>
        <source>Next page</source>
        <target>次のページ</target>
      </trans-unit>
      <trans-unit>
        <source>Last page</source>
        <target>最後のページ</target>
      </trans-unit>

      <!-- Form -->
      <trans-unit>
        <source>The item was created successfully.</source>
        <target>アイテムを作成しました</target>
      </trans-unit>
      <trans-unit>
        <source>The item was updated successfully.</source>
        <target>アイテムを更新しました</target>
      </trans-unit>
      <trans-unit>
        <source>The item was created successfully. You can add another one below.</source>
        <target>アイテムを作成しました。以下で別のアイテムを追加できます。</target>
      </trans-unit>
      <trans-unit>
        <source>The item was updated successfully. You can add another one below.</source>
        <target>アイテムを更新しました。以下で別のアイテムを追加できます。</target>
      </trans-unit>
      <trans-unit>
        <source>The item has not been saved due to some errors.</source>
        <target>エラーのためアイテムを保存できませんでした</target>
      </trans-unit>
      <trans-unit>
        <source>The item was deleted successfully.</source>
        <target>アイテムを削除しました</target>
      </trans-unit>
      <trans-unit>
        <source>You must at least select one item.</source>
        <target>最低でも1つを選択してください。</target>
      </trans-unit>
      <trans-unit>
        <source>You must select an action to execute on the selected items.</source>
        <target>選択されたアイテムを処理するためにアクションを選択してください。</target>
      </trans-unit>
      <trans-unit>
        <source>A problem occurs when deleting the selected items as some items do not exist anymore.</source>
        <target>すでに存在しないアイテムを削除しようとしてエラーが発生しました。</target>
      </trans-unit>
      <trans-unit>
        <source>The selected items have been deleted successfully.</source>
        <target>選択されたアイテムを削除しました。</target>
      </trans-unit>
      <trans-unit>
        <source>A problem occurs when deleting the selected items.</source>
        <target>選択されたアイテムを削除するときにエラーが発生しました。</target>
      </trans-unit>
      <trans-unit>
        <source>is empty</source>
        <target>空の値も含む</target>
      </trans-unit>
      <trans-unit>
        <source>yes or no</source>
        <target>全て</target>
      </trans-unit>
      <trans-unit>
        <source>yes</source>
        <target>はい</target>
      </trans-unit>
      <trans-unit>
        <source>no</source>
        <target>いいえ</target>
      </trans-unit>
      <trans-unit>
        <source><![CDATA[from %from_date% to %to_date%]]></source>
        <target><![CDATA[%from_date% から %to_date%]]></target>
      </trans-unit>
      <trans-unit>
        <source><![CDATA[from %from_date%<br />to %to_date%]]></source>
        <target><![CDATA[%from_date% から<br /> %to_date%]]></target>
      </trans-unit>

      <!-- Form Error Messages -->
      <trans-unit>
        <source>Required.</source>
        <target>必須項目です。</target>
      </trans-unit>
      <trans-unit>
        <source>Invalid.</source>
        <target>無効な値です。</target>
      </trans-unit>
      <trans-unit>
        <source>"%value%" is not an integer.</source>
        <target>"%value%" は数値でありません。</target>
      </trans-unit>
      <trans-unit>
        <source>"%value%" is not an number.</source>
        <target>"%value%" は数字でありません。</target>
      </trans-unit>
      <trans-unit>
        <source>At least %min% values must be selected (%count% values selected).</source>
        <target>%min% 個以上選択してください(現在 %count% が選択されています)。</target>
      </trans-unit>
      <trans-unit>
        <source>At most %max% values must be selected (%count% values selected).</source>
        <target>%min% 個以内で選択してください(現在 %count% が選択されています)。</target>
      </trans-unit>
      <trans-unit>
        <source>CSRF attack detected.</source>
        <target>画面遷移が確認できませんでした</target>
      </trans-unit>
      <trans-unit>
        <source>"%value%" does not match the date format (%date_format%).</source>
        <target>"%value%" が日付のフォーマット (%date_format%)に一致しません</target>
      </trans-unit>
      <trans-unit>
        <source>The date must be before %max%.</source>
        <target>日付は %max% より前を指定してください</target>
      </trans-unit>
      <trans-unit>
        <source>The date must be after %min%.</source>
        <target>日付は %min% より後を指定してください</target>
      </trans-unit>
      <trans-unit>
        <source>The begin date must be before the end date.</source>
        <target>開始日は終了日より前でなければなりません。</target>
      </trans-unit>
      <trans-unit>
        <source>File is too large (maximum is %max_size% bytes).</source>
        <target>ファイルのサイズが大きすぎます(アップロードできるファイルサイズは%max_size%バイトです)。</target>
      </trans-unit>
      <trans-unit>
        <source>Invalid mime type (%mime_type%).</source>
        <target>無効なmimeタイプです(%mime_type%)。</target>
      </trans-unit>
      <trans-unit>
        <source>The uploaded file was only partially uploaded.</source>
        <target>アップロードされたファイルは不十分な状態でアップロードされました。</target>
      </trans-unit>
      <trans-unit>
        <source>Missing a temporary folder.</source>
        <target>テンポラリフォルダーがありません。</target>
      </trans-unit>
      <trans-unit>
        <source>Failed to write file to disk.</source>
        <target>ディスクへのファイル書き込みに失敗しました。</target>
      </trans-unit>
      <trans-unit>
        <source>File upload stopped by extension.</source>
        <target>ファイルの拡張子の制限でアップロードは中止しました。</target>
      </trans-unit>
      <trans-unit>
        <source>Unexpected extra form field named "%field%".</source>
        <target>"%field%" という不明のフィールドがあります</target>
      </trans-unit>
      <trans-unit>
        <source>"%value%" is too long (%max_length% characters max).</source>
        <target>入力文字数がオーバーしています (%max_length%文字以下)</target>
      </trans-unit>
      <trans-unit>
        <source>"%value%" is too short (%min_length% characters min).</source>
        <target>入力文字数が不足しています (%min_length%文字以上)</target>
      </trans-unit>
      <trans-unit>
        <source>"%value%" does not match the time format (%time_format%).</source>
        <target>"%value%"が時刻のフォーマット (%time_format%)に一致しません</target>
      </trans-unit>
      <trans-unit>
        <source>"%value%" must be at most %max%.</source>
        <target>"%value%" は %max% より小さくなければなりません。</target>
      </trans-unit>
      <trans-unit>
        <source>"%value%" must be at least %min.</source>
        <target>"%value%" %min% より大きくなければなりません。</target>
      </trans-unit>
      <trans-unit>
        <source>The date must be before %max%.</source>
        <target>日付は %max% より前の日付でなければなりません。</target>
      </trans-unit>
      <trans-unit>
        <source>The date must be after %min%.</source>
        <target>日付は %mix% より後の日付でなければなりません。</target>
      </trans-unit>
      <trans-unit>
        <source>The form submission cannot be processed. It probably means that you have uploaded a file that is too big.</source>
        <target>フォームの処理ができませんでした。アップロードしたファイルのサイズが大きすぎるのかもしれません。</target>
      </trans-unit>

      <!-- Old -->
      <trans-unit>
        <source>"%value%" must be less than %max%.</source>
        <target>"%value%" は %max% より小さい値を指定してください</target>
      </trans-unit>
      <trans-unit>
        <source>"%value%" must be greater than %min%.</source>
        <target>"%value%" は %min% より大きい値を指定してください</target>
      </trans-unit>
      <trans-unit>
        <source>An object with the same "%column%" already exist.</source>
        <target>既に登録されています</target>
      </trans-unit>
    </body>
  </file>
</xliff>
新しい辞書がフォームとフィルターで利用されるようにsetupで追記する

アドミンジェネレーターの画面そのものではなくフォームフレームワークによってメッセージが処理されるので、フォームクラス側にカタログの指定を行う必要があります。追加するのはフォームクラスとフィルター(検索用)クラスです。

  • lib/form/doctrine/BaseFormDoctrine.class.php
<?php
abstract class BaseFormDoctrine extends sfFormDoctrine
{
  public function setup()
  {
    parent::setup();
    $this->widgetSchema->getFormFormatter()->setTranslationCatalogue('sf_admin');
  }
}
  • lib/filter/doctrine/BaseFormFilterDoctrine.class.php
<?php
abstract class BaseFormFilterDoctrine extends sfFormFilterDoctrine
{
  public function setup()
  {
    parent::setup();
    $this->widgetSchema->getFormFormatter()->setTranslationCatalogue('sf_admin');
  }
}

これで最初の画面キャプチャのような日本語化されたアドミンジェネレーターの完成です。
次は新しいジェネレーターとテーマでもつくるかな。。

追記

ぶくまでコメントいただきましたが、もう少し使い込んでから本家にパッチを送ろうかと思ってます。もし、「もっといいカタログファイル持ってる」という方は是非本家に投げてください :-)

さらに追記

本家にパッチを送り無事取り込んでもらいました。時期リリースには含まれるはずです。また、trunkからDEV版をとってきているのであればすでに新しいカタログファイルが取得できます。この記事ではdoctrineを例にしていますが、propel, doctrineどちらのアドミンジェネレーターでも利用できるはずです。:-)

さらにさらに追記

無事symfony1.3.1, 1.4.1から含まれました。間違いや漏れ等はコメントかつぶやいてください。