読者です 読者をやめる 読者になる 読者になる

脳みそスワップアウト

揮発性なもので。おもにPHPのこととか。

CakePHP2のi18n

CakePHP2 の国際化機能を初めて使ったのでメモ。

  • Cake2 の i18n は、gettext に倣っている。
    • gettext を知っていればとくに違和感なく使える
  • gettext, php-gettext 拡張がなくても動作する
    • __(), __d() 等のCake専用関数が設けられていて、php-gettext とほぼ同等のことが可能
    • 開発のためには gettext はあったほうが便利(msgmerge、msgfmt)
  • MO も読めるが、MO が存在しない場合 PO を読んで動作する
  • 訳を変更した場合はキャッシュクリアをしたほうがいい

テンプレート変更のたびに発生する一括マージ、
リリース時の PO の一括コンパイルの仕方がCakeのi18nシェルでどうやるのかよくわからなかったので、
gettext(msgmerge) を使ってマージをすることにした。

extractとマージ

POT への extract はCakeの機能を使って、POT -> PO マージには msgmerge を使っている。
env.shlib はディレクトリの定義。

#!/bin/bash
####
# ソース中から多言語箇所を抽出してPOTを上書き(like a gettext)、
# 新しいPOTと各言語のPOをマージする。
#
# マージ後、POを編集、MOを作成、リリースの流れになる。
####
source $(cd $(dirname $0);pwd)/../env.shlib
MSGMERGE_BIN=/usr/bin/msgmerge

if [ ! -f $MSGMERGE_BIN ]; then
  echo "msgmerge not found. ($MSGMERGE_BIN)"
  echo "Please install gettext."
  exit 1;
fi


pushd $APP_DIR
echo "Extracting(like a xgettext)..."
../Vendor/bin/cake i18n extract --paths $APP_DIR --output $APP_DIR/Locale --merge no --overwrite --extract-core no
echo "Extract Done."

echo "Merging(msgmerge)..."
for FULLPATH in `find $APP_DIR/Locale -name "*.po"`
do
  $MSGMERGE_BIN -U "$FULLPATH" "$APP_DIR/Locale/$(echo $(basename $FULLPATH) | sed s/\.po/\.pot/)"
done
echo "Merge Done."
popd

POコンパイル

PO の一括コンパイルには msgfmt を使った。

#!/bin/bash
####
# POからMOを作成する。
####
source $(cd $(dirname $0);pwd)/env.shlib
MSGFMT_BIN=/usr/bin/msgfmt

if [ ! -f $MSGFMT_BIN ]; then
  echo "msgmerge not found. ($MSGFMT_BIN)"
  echo "Please install gettext."
  exit 1;
fi

for FULLPATH in `find $APP_DIR/Locale -name "*.po"`
do
  $MSGFMT_BIN -o "$(echo $FULLPATH | sed s/\.po/\.mo/)" "$FULLPATH"
done
echo Done.