本文を読み飛ばす

pyramid + Lingua で多言語対応してみる

pyramidでも、Zope用に作ったProductがi18n対応してくれて いたんですが、potファイルの更新方法がわからないままでした。

pyramidのマニュアルを見て更新方法を試してみます。

ついでに古い文書も整形...

  • pyramid + Lingua で多言語対応してみる

  • (旧文書) Zope2のProductを多言語対応してみる: 元id00421

pyramidのマニュアルを見て実行:

$ ./venv/bin/pip install lingua

ふむ...既にインストールされてました。

./venv は pyramid が入っている virtualenv です

早速、実行してみます:

$ cp prod/locales/app.pot{,.org}
$ ./venv/bin/pot-create -s -o prod/locales/app.pot prod
※prod は自分のアプリのディレクトリ名です

お、得に問題なく生成できたみたいです。 結果を確認してみます。:

$ vi -d prod/locales/app.pot app.pot.org

比較してみましたが、ソートしたおかげで出力順序まであってました。 \ 比較するには、:

:s/Default: \(.*\)$/Default: "\1"/

という操作は必要でした。

-s をつけないと、さすがに出力順番は変わってしまいました。 \ これでは、以前のものがすべて抽出されているのかわからずでしたが、 \ ソートされていれば問題ないですね

さて、potができたら次はpoの更新です:

$ cp prod/locales/ja/app.po{,.org}
$ msgmerge --update prod/locales/ja/LC_MESSAGES/app.po prod/locales/app.pot

これも問題なく実行可能 (msgmergeはgettextなんで実績あるはずだし) \ 結果を確認してみます。:

$ vi -d prod/locales/ja/LC_MESSAGES/app.po{,.org}
  • 複数行に渡る長いメッセージが出力おかしくなってる

  • Language: japanese の順番がちょっと変わってます

長いメッセージがこんな感じになってたので直しておきました:

-- from --
msgid "aaa"
msgstr ""
"ながいながい..."

-- to --
msgid "aaa"
msgstr "ながいながい..."

更新して完了:

$ msgfmt -o prod/locales/ja/LC_MESSAGES/app.{mo,.po}

最後に Makefile に今回の処理を書いておきました。:

prod := your-product-name
locpath := $(prod)/locales/
pot := $(locpath)$(prod).pot
po_cmd := $(venv)/pot-create
po_main := ja
po_langs := en $(po_main)

install_i18n:
    for lang in $(po_langs); \
        mkdir -p mkdir $(locpath)$$lang/LC_MESSAGES || echo
    done
    $(venv)/pip install lingua
    $(po_cmd) -s -o $(pot) $$(dirname $(locpath))
    # to debug for UnicodeEncodeError

i18nupdate:
    cp $(pot) $(pot).org
    $(venv)/pot-create -s -o $(pot) $$(dirname $(locpath))
    for lang in en $(po_langs); do \
        msgmerge --update $(locpath)$$lang/LC_MESSAGES/$(prod).po $(pot); \
    done
    editor $(locpath)$(po_main)/LC_MESSAGES/$(prod).po
    for po in $(locpath)/*/*/*.po; do \
        dir=$$(dirname $$po); \
        msgfmt -o $$dir/$$(basename $$po .po).mo $$po; \
    done

面倒なので依存関係とかはやりませんでした。

(旧文書) Zope2のProductを多言語対応してみる

すごい苦労したので、メモしておきます. (古い話ですが)

といってももうすぐZope4も出るみたいなので その際には、もう一回やっておかないとだめでしょうか。

ダメだった方法も含めて書いておきます。

1. i18ndudeを使う方法 1. (失敗) i18nextractを使う方法 (infrae.i18nextractパッケージで) 1. (失敗) i18nextractを使う方法 (lovely.recipe:i18nパッケージで) 1. (失敗) i18nextractを使う方法 (zc.recipe:i18nパッケージで) 1. (失敗) i18nextractを使う方法 (zope.app.localesパッケージで)

失敗が多かった原因としては、 zc.buildout の使用を避けたことでした。 \ 普通に pip などから使えるパッケージではうまく動かせませんでした。

今回初めて buildout 使いましたが、\ 新しいこと覚えるのも余計な手間といえば、手間なので \ 正直使わないでおけるものならそうしたかったのですが...

とはいえ、Zopeは既に依存関係がすごいことになっているので \ buildout必須ですしね. 上のはpipなどではインストールできませんでした...

今回初めてbuildoutに触ることになりました...

あとi18nextractのインストールでは \ productのパッケージ指定が必要なのですが、\ Productsに配置するだけのZope2のパッケージがうまく指定できませんでした。

これは時代遅れ? なので仕方ないのかな...

成功したのはi18ndudeを使う方法だったので それだけコマンドを追って書いていきます。

i18ndudeを使う方法

これを参照に頑張ってみます

zc.buildoutをインストール:

$ mkdir /home/zope/2.13.21
$ cd /home/zope/2.13.21
$ virtualenv venv
$ venv/bin/easy_install zc.buildout

Zope2を取得するbuildout.cfgを作る:

# 追記
[buildout]
parts =
    instance
extends = http://download.zope.org/Zope2/index/2.13.21/versions.cfg

[instance]
user = zope:zope
http-address = 8081
recipe = zc.recipe.egg
eggs = Zope2
interpreter = py
scripts = runzope zopectl
initialization =
    import sys
    sys.argv[1:1] = ['-C',r'${buildout:directory}/etc/zope.conf']

environment-vars =
    zope_i18n_compile_mo_files true

i18ndudeを取得するbuildout.cfgを追記する:

# 追記
[buildout]
parts =
    instance
    i18ndude
extends = http://download.zope.org/Zope2/index/2.13.21/versions.cfg

[instance]
user = zope:zope
http-address = 8081

recipe = zc.recipe.egg
eggs = Zope2
interpreter = py
scripts = runzope zopectl
initialization =
import sys
sys.argv[1:1] = ['-C',r'${buildout:directory}/etc/zope.conf']

environment-vars =
    zope_i18n_compile_mo_files true

# 追記
[i18ndude]
unzip = true
recipe = zc.recipe.egg
eggs = i18ndude

zc.buildoutを実行する:

$ ./venv/bin/buildout

しばらく待つとi18ndudeができています。

自分の作ったProductを持ってくる:

$ mkdir Products
$ cp -rdpv /home/hoge/src/myproducts Products

※myproductsのzcmlは多言語化済みと仮定します.\ (後述 :ref:`configure.zcmlの多言語化 <configure-zcml>` )

※myproductsの*.ptは多言語化済みと仮定します.\ (後述 :ref:`ptの多言語化 <i18ned-pt>` )

多言語化のファイルを作っておく:

$ i18ndude=$(pwd)/bin/i18ndude
$ cd Products/myproducts
$ mkdir locales
$ mkdir locales/ja
$ mkdir locales/en
$ mkdir locales/ja/LC_MESSAGES
$ mkdir locales/ja/LC_MESSAGES

i18ndudeを使う:

$ $i18ndude rebuild-pot --pot locales/myproducts.pot --create myproducts

.potができたら.poにコピー:

$ $i18ndude sync --pot locales/myproducts.pot locales/ja/LC_MESSAGES/myproducts.po
$ $i18ndude sync --pot locales/myproducts.pot locales/en/LC_MESSAGES/myproducts.po

.poのファイルを修正します \ (後述 :ref:`poのファイル修正 <i18ned-pt>` )

実はここまでくれば、後は.moは自動的に作られるそうです。

私の場合はうまくいかなかったので手動で.moを作ります.:

for po in $$(find . -path '*/LC_MESSAGES/*.po'); do
    msgfmt -o $${po/%po/mo} $$po;
done

Zope2を起動すれば多言語化完了です!

sample picture of i18n'ed Zope2 application

configure.zcmlの多言語化

最終的にこんな記述になりました:

<configure
  xmlns="http://namespaces.zope.org/zope"
  xmlns:five="http://namespaces.zope.org/five"
  xmlns:i18n="http://namespaces.zope.org/i18n"
  xmlns:browser="http://namespaces.zope.org/browser"
  i18n_domain="myproduct"
  >
<!-- include package="zope.i18n" file="configure.zcml" / -->
<include package="zope.i18n" file="meta.zcml" />
<i18n:registerTranslations directory="locales" />

zope.i18nを無効にしているのは、これを書くと \ Zope2が起動しなくなるからです。

他のところでも定義があるらしく...よくわかりませんでした。

後でなるかも...という記述は見かけましたが不明です。

ptの多言語化

.ptには以下のように書いています.:

<title metal:fill-slot="title" i18n:translate="hoge">hoge
</title>

<input i18n:attributes="value hoge" value="hoge" />

とにかくi18nで手がつりそうです(補完とかコピペあるから冗談ですが)

poのファイル修正

.poファイルは次のように記述しています:

#. Default: "hoge"
#: ./www/hoge.pt:8
msgid "hoge"
msgstr "仮版の記述"

i18nextractを使う方法

Zope3を使っている方は入れることができた...という記事を見ましたが、\ Zope2のProductを書いている私はi18nextractを \ うまく入れることができませんでした。

次のサイトは、英語なので斜め読みしてたら内容がさっぱり... \ でもmsgfmtの使い方はここを参照しました。

次も英語なので...orz

infrae.i18nextractを見ると zope-products とか extra-paths とかオプションがあって \ Productsフォルダを指定したら動くような気もするが...動かない...

i18nextractは結局のところ、うまく使えずです...

コメント

Comments powered by Disqus
宣伝: