mcpField
O
odoo-i18n

odoo-i18n

github.com/ahmed-lakosha開発76111 回インストール31 週間前に更新
リポジトリ

odoo-i18n について

odoo-i18nは、Odoo 14~19の翻訳とローカライズを扱う開発者向けスキルです。文字列の抽出、.poファイルの検証と不足レポート、Odoo CLIによる翻訳のインポートやエクスポートを支援します。

主な機能

  1. 01翻訳対象文字列の抽出
  2. 02.poの構文と内容の検証
  3. 03翻訳不足のレポート
  4. 04.poファイルのマージと変換
  5. 05Odoo CLIでのインポートとエクスポート
  6. 06言語別ルールの確認

活用シーン

  1. 01Odooモジュールの翻訳ファイル生成
  2. 02リリース前の.poファイル検証
  3. 03翻訳カバレッジ不足の把握
  4. 04Odooデータベースへの翻訳登録

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/ahmed-lakosha/odoo-plugins --skill odoo-i18n

インストール後、Claude Code で/odoo-i18nを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

scripts/
__init__.py
_common.py
i18n_converter.py
i18n_extractor.py
i18n_reporter.py
i18n_validator.py

詳細

Odoo i18n スキル

Odoo 14~19 の国際化(i18n)とローカライゼーション(l10n)に関する深い専門知識を提供します。

重要な翻訳ルール

  1. 絶対に _() 内で f-string を使わないでください。% 形式を使用します:_('Record %s') % name
  2. 絶対に _() 内で文字列を連結しないでください。翻訳者に文全体を渡します。
  3. クラスレベルの文字列(選択値、クラス属性)には _lt() を使用します
  4. 絶対に string= フィールド属性を _() で囲まないでください。Odoo が自動的に翻訳します。
  5. .po ファイルは BOM なしの UTF-8 として保存します。
  6. アラビア語の .po ファイルでは、Plural-Forms ヘッダーに nplurals=6 が必要です。
  7. .po ファイルを編集した後は、必ずモジュールを更新します:-u module --stop-after-init

ワークフロー 1:翻訳対象の文字列を抽出する

Odoo モジュールをスキャンし、翻訳対象の文字列をすべて抽出して、.pot(テンプレート)ファイルと .po(言語)ファイルを生成します。

使用方法
python ${CLAUDE_PLUGIN_ROOT}/odoo-i18n/scripts/i18n_extractor.py --module <path> --lang <code> [--output <dir>] [--no-pot] [--verbose]
引数必須説明
--moduleはいOdoo モジュールディレクトリのパス
--langはい対象言語コード(例:ar、fr、tr)
--outputいいえカスタム出力ディレクトリ(デフォルト:module/i18n/)
--no-potいいえ.pot テンプレートの生成をスキップ
--verboseいいえ抽出した文字列をすべて表示
抽出対象

Python(*.py) -- _('...') および _lt('...'):

# Extracted:
raise UserError(_('Record %s not found') % name)
state = fields.Selection([('draft', _lt('Draft'))])
# NOT extracted: _(variable), _(f'Hello {name}')

XML(*.xml) -- string=、help=、placeholder= 属性、メニュー/アクションの name=、HTML テキスト:

<field name="state" string="Status"/>      
<h1>Welcome to our website</h1>            
<record id="view_my_form" model="ir.ui.view">  

JavaScript(*.js) -- _t('...') および _lt('...'):

const msg = _t("Save Changes");   // extracted
const msg = _t(someVariable);     // NOT extracted
生成されるファイル構成
# Translation template for my_module
msgid ""
msgstr ""
"Project-Id-Version: Odoo Module my_module\n"
"Content-Type: text/plain; charset=UTF-8\n"

#: models/my_model.py:45
#, python-format
msgid "Record %s not found"
msgstr ""
代替方法:Odoo 組み込みの抽出ツール
python odoo-bin -c conf/myproject.conf -d mydb \
    --i18n-export --modules=my_module --language=ar \
    --output=my_module/i18n/ar.po --stop-after-init

Odoo の CLI 抽出ツールは、プラグインの抽出ツールでは対象とならないデータベース内の文字列(モデル名、アクション名)も含めます。本番環境では、組み込みの抽出ツールのほうがより完全です。

抽出後の手順
  1. .po ファイルを翻訳エディター(Poedit、Virtaal、またはテキストエディター)で開きます
  2. すべての msgstr エントリーに翻訳を入力します
  3. 検証します:i18n_validator.py --po-file path/to/ar.po を実行します
  4. 翻訳率を確認します:i18n_reporter.py --module path/ --lang ar を実行します
  5. Odoo に読み込みます:モジュールを更新するか、エクスポート/インポートのワークフローを使用します

ワークフロー 2:.po ファイルを検証する

.po ファイルの構文エラー、エンコーディングの問題、空の翻訳、fuzzy エントリー、書式指定子の不一致、アラビア語/RTL 固有の問題を検証します。

使用方法
python ${CLAUDE_PLUGIN_ROOT}/odoo-i18n/scripts/i18n_validator.py --po-file <path> [--lang <code>] [--strict] [--output <file>]
引数必須説明
--po-fileはい検証する .po ファイルのパス
--langいいえ言語固有のチェックに使用する言語コード(ファイル名から自動検出)
--strictいいえ未翻訳の文字列を警告ではなくエラーとして扱う
--outputいいえ標準出力ではなく、レポートをファイルに書き込む
検証内容

構文: UTF-8 エンコーディング(BOM/Latin-1 なし)、Content-Type/charset/Language/MIME-Version を含むヘッダー、適切に引用符で囲まれた文字列、解析エラーがないこと。

翻訳: 空の msgstr(未翻訳)、確認が必要な fuzzy フラグ、重複する msgid、廃止済み(#~)エントリー。

書式指定子: %s/%d/%f の数が一致していること、名前付き書式指定子 %(name)s がすべて含まれていること:

# WRONG - missing second %s:
msgid "Invoice %s due on %s"
msgstr "fatura %s"
# CORRECT:
msgid "Invoice %s due on %s"
msgstr "fatura %s vadesi %s"

アラビア語固有(--lang ar): アラビア文字が含まれていること、Latin-1 によるエンコーディングのアーティファクト、方向制御文字、nplurals=6 が必須であること、BIDI 上書きの警告。

よくあるエラーと修正方法

「Charset must be UTF-8」:

python ${CLAUDE_PLUGIN_ROOT}/odoo-i18n/scripts/i18n_converter.py --action convert --po ar.po --output ar_fixed.po

「Fuzzy translation (needs review)」 -- 確認後に fuzzy フラグを削除します:

# Before:                          # After:
#, fuzzy, python-format            #, python-format
msgid "Record %s not found"        msgid "Record %s not found"
msgstr "record not found"          msgstr "record not found"

「Arabic should have nplurals=6」:

"Plural-Forms: nplurals=6; plural=n==0 ? 0 : n==1 ? 1 : n==2 ? 2 : n%100>=3 && n%100<=10 ? 3 : n%100>=11 && n%100<=99 ? 4 : 5;\n"
CI/CD との統合
- name: Validate Arabic translations
  run: python odoo-i18n/scripts/i18n_validator.py --po-file my_module/i18n/ar.po --lang ar --strict

終了コード 0 = 成功(警告がある場合もあります)、1 = 失敗(エラーあり)。


ワークフロー 3:不足している翻訳を見つける

モジュールのソースファイルに含まれる翻訳対象の文字列と既存の .po ファイルを比較し、不足または未完了の翻訳を報告します。

使用方法
python ${CLAUDE_PLUGIN_ROOT}/odoo-i18n/scripts/i18n_reporter.py --module <path> --lang <code> [--format text|json|csv] [--output <file>] [--min-pct <N>]
引数必須説明
--moduleはいOdoo モジュールディレクトリへのパス
--langはいチェックする言語コード(例:ar、fr)
--formatいいえ出力形式:text(デフォルト)、json、csv
--outputいいえ標準出力ではなく、レポートをファイルに書き込みます
--min-pctいいえ翻訳率がしきい値を下回ると終了コード 1 を返します
レポートの見方
  • Missing:ソースコードにはあるものの、.po にエントリがない文字列です
  • Empty in .po:エントリはありますが、msgstr が ""(未翻訳)です
  • Fuzzy:自動照合されたため、人による確認が必要です。ユーザーには表示されません(Odoo はソースにフォールバックします)
  • Completion % = 翻訳済み / 有効な文字列の合計 * 100(空でない、fuzzy でない、廃止されていない文字列)
ワークフロー:未翻訳箇所の修正
  1. i18n_reporter.py を実行して不足箇所を特定します
  2. Poedit、Virtaal、またはテキストエディターで .po を開きます
  3. 不足している msgstr エントリを入力します
  4. 文字列が .po にまったくない場合は、まず i18n_extractor.py を実行します
  5. i18n_validator.py で検証します
  6. i18n_reporter.py を再実行して網羅率を確認します
ソース変更後の .po の更新
# 1. Re-extract new strings
python ${CLAUDE_PLUGIN_ROOT}/odoo-i18n/scripts/i18n_extractor.py --module /path/ --lang ar --no-pot
# 2. Merge (preserves existing translations)
python ${CLAUDE_PLUGIN_ROOT}/odoo-i18n/scripts/i18n_converter.py \
    --action merge --base /path/i18n/ar.po --new /path/i18n/ar.po --output /path/i18n/ar_merged.po
# 3. Check remaining gaps
python ${CLAUDE_PLUGIN_ROOT}/odoo-i18n/scripts/i18n_reporter.py --module /path/ --lang ar

ワークフロー 4:Odoo CLI でのエクスポート/インポート

PostgreSQL と有効なデータベースが必要です。

翻訳のエクスポート
# Single module
python odoo-bin -c conf/myproject.conf -d mydb \
    --i18n-export --modules=my_module --language=ar \
    --output=my_module/i18n/ar.po --stop-after-init

# Export .pot template (no --language = empty msgstr)
python odoo-bin -c conf/myproject.conf -d mydb \
    --i18n-export --modules=my_module \
    --output=my_module/i18n/my_module.pot --stop-after-init

# Multiple modules / all installed
python odoo-bin -c conf/myproject.conf -d mydb \
    --i18n-export --modules=mod1,mod2 --language=ar --output=combined_ar.po --stop-after-init
翻訳のインポート
# Import .po
python odoo-bin -c conf/myproject.conf -d mydb \
    --i18n-import=my_module/i18n/ar.po --language=ar --modules=my_module --stop-after-init

# Import and overwrite existing
python odoo-bin -c conf/myproject.conf -d mydb \
    --i18n-import=my_module/i18n/ar.po --language=ar \
    --modules=my_module --i18n-overwrite --stop-after-init

# Multiple languages
for lang in ar fr tr; do
    python odoo-bin -c conf/myproject.conf -d mydb \
        --i18n-import=my_module/i18n/${lang}.po --language=${lang} \
        --modules=my_module --stop-after-init
done
言語の読み込み
python odoo-bin -c conf/myproject.conf -d mydb --load-language=ar --stop-after-init
python odoo-bin -c conf/myproject.conf -d mydb --load-language=ar,fr,tr --stop-after-init

シェルで確認/有効化します:

# python odoo-bin shell -d mydb
langs = self.env['res.lang'].with_context(active_test=False).search([])
for lang in langs:
    print(f"[{'ACTIVE' if lang.active else 'inactive'}] {lang.code}: {lang.name}")

# Activate
lang = self.env['res.lang'].with_context(active_test=False).search([('code', '=', 'ar')])
lang.active = True
self.env.cr.commit()
モジュールの更新(最も簡単な再読み込み)
python -m odoo -c conf/myproject.conf -d mydb -u my_module --stop-after-init
Odoo 17 以降の仕様

翻訳は内部的に JSON 用語として保存されますが、エクスポート形式は引き続き .po です。キャッシュをクリアします:

# python odoo-bin shell -d mydb
self.env['ir.translation'].clear_caches()
self.env.cr.commit()
Web サイトの翻訳
python odoo-bin -c conf/myproject.conf -d mydb \
    --i18n-export --modules=website,my_theme_module --language=ar \
    --output=website_ar.po --stop-after-init
翻訳ファイルの場所
module/i18n/
  module.pot    <- Template (not loaded by Odoo)
  ar.po         <- Arabic
  ar_SA.po      <- Saudi variant (overrides ar.po entries)
  fr.po         <- French
  tr.po         <- Turkish

ユーティリティ:.po ファイルの統合とクリーンアップ

python ${CLAUDE_PLUGIN_ROOT}/odoo-i18n/scripts/i18n_converter.py --action merge --base ar.po --new ar_new.po --output ar_merged.po
python ${CLAUDE_PLUGIN_ROOT}/odoo-i18n/scripts/i18n_converter.py --action clean --po ar.po
python ${CLAUDE_PLUGIN_ROOT}/odoo-i18n/scripts/i18n_converter.py --action stats --po ar.po
python ${CLAUDE_PLUGIN_ROOT}/odoo-i18n/scripts/i18n_converter.py --action convert --po ar.po --output ar_fixed.po

対応言語のクイックリファレンス

コード言語RTL?複数形
ar / ar_SA / ar_AEアラビア語(バリエーション)はい6
en / en_US英語いいえ2
fr / fr_FRフランス語いいえ2
trトルコ語いいえ2
deドイツ語いいえ2
esスペイン語いいえ2

Odoo のバージョンによる違い

機能Odoo 14-15Odoo 16-17Odoo 18-19
JS 翻訳のインポートimport { _t } from "web.core"import { _t } from "@web/core/l10n/translation"16 と同じ
Bootstrap のバージョン4.x5.1.3(RTL を標準サポート)5.1.3 以降
翻訳の保存先ir.translation テーブルJSON 用語(内部)JSON 用語
リストのビュータイプ<tree><tree><list>(19 のみ)
コントローラータイプtype='json'type='json'type='jsonrpc'(19 のみ)
表示属性attrs={'invisible': ...}attrs={'invisible': ...}インラインの invisible="expr"(19 のみ)

よくある問題

翻訳が表示されない:-u module --stop-after-init でモジュールを更新し、ブラウザーのキャッシュをクリアしてください。

アラビア語のテキストが文字化けする:ファイルが Latin-1 で保存されています。i18n_converter.py --action convert を実行して文字コードを修正してください。

書式指定子のエラー:msgid と msgstr の %s/%d/%(name)s の数が一致していることを確認してください。

アラビア語ユーザーに Web サイトが英語で表示される:(1)アラビア語がインストールされていること、(2)ユーザーの言語が設定されていること、(3)翻訳追加後にモジュールが更新されていることを確認してください。

Fuzzy エントリ:.po を開いて翻訳を確認し、承認済みエントリから #, fuzzy フラグを削除してください。


ブランディングの設定

生成される .pot/.po ファイルでは、作成者名とメールアドレスを設定できます。環境変数を設定します:

export ODOO_I18N_COPYRIGHT="Your Company"
export ODOO_I18N_BUGS_EMAIL="[email protected]"

詳細リファレンス(メモリファイル)

このスキルの概要を超える包括的なパターンについては、プラグインに次のメモリファイルが含まれています。

  • memories/translation_patterns.md -- Python の _() / _lt() パターン、XML 属性の翻訳、JS の _t() パターン、.po ファイルの構造、メールテンプレートの翻訳
  • memories/rtl_patterns.md -- RTL の有効化、Bootstrap RTL、CSS の論理プロパティ、SCSS のオーバーライド、RTL での Flexbox、JS による RTL の検出、QWeb レポートの RTL、一般的な RTL の修正
  • memories/language_codes.md -- 言語コード、日付/時刻の形式、数値の形式、通貨表示、ヒジュラ暦に関する注記、タイムゾーンのリファレンス

コメント