Python アプリケーション
ai-i18n-toolsは、Python、Jinja、Django、Qtの.uiファイルからUI文字列を抽出し、ソース言語の文字列をキーとするフラットなJSON、GNU gettextカタログ、またはその両方を書き込みます。sourceLocaleはどの言語でもかまいません。ランタイムヘルパーは、標準ライブラリのi18n.pyです(Python 3.10以降)。Streamlit、Tkinter、PyQt、PySide、PyWebView、Flask、Pyramid、FastAPIがそのヘルパーを呼び出します。DjangoはDjango独自のgettextを使用します。
既存の単一言語アプリにロケールを追加する:i18n.pyプロンプトとDjango / gettextプロンプトを含むPythonアプリにi18nを追加する。フレームワーク選択:Python統合。関数リスト:Pythonランタイム(i18n.py)。
実行可能なコピーは examples/python-streamlit、examples/python-flask、examples/python-fastapi、および examples/python-gettext に存在します。これらは Python プロジェクトです。最初の 3 つは virtualenv と pip install -r requirements.txt を使用します。python-gettext は標準ライブラリのみを使用します。これらは npm パッケージではありません。リリースアーカイブ ai-i18n-tools-python-examples.zip には同じ 4 つのディレクトリが含まれています。npm tarball およびスタンドアロン実行可能ファイルには含まれていません。
スキャフォールド
ai-i18n-tools init -t ui-python -P cheaperinference
ai-i18n-tools init -t ui-python-gettext -P anthropic
ai-i18n-tools init -t ui-python-flask -P groq
ai-i18n-tools init -t ui-python-django -P ollamaui-python はフラットな JSON と i18n.py を書き込みます。ui-python-gettext は JSON と .po / .mo を書き込みます。ui-python-flask は translations/ および i18n.py 配下に gettext カタログを書き込みます。ui-python-django は locale/<lang>/LC_MESSAGES/django.po を書き込み、i18n.py は書き込みません。
リポジトリのREADMEも翻訳します:上記のinitコマンドに--with-readmeを追加してください。READMEとMarkdownドキュメントにi18nを追加するを参照してください。
スキャンルートは node_modules、.git、.venv、venv、env、site-packages、__pycache__、.tox、.nox、.pytest_cache、.mypy_cache、.ruff_cache、および .eggs をスキップします。
翻訳用の呼び出し
最初にカタログエントリを検索し、次に補間を行います。
ポータブル:
t("Hello, {name}!", name=name)
t("Total: {price:,.2f}", price=price)
_("Hello, %s!") % name
_("Total: {price:,.2f}").format(price=price)Python 3.14 では、ヘルパーはテンプレート文字列も受け入れます:
translate(t"Hello, {name}!")translate は t のエイリアスです。キーワード引数は、テンプレート文字列から取得された値をオーバーライドします。
ネイティブの gettext。テンプレートが引数であるため、依然として安全です:
_("Hello, %s!") % name
ngettext("1 file", "{count} files", count, count=count)
pgettext("menu", "Open")これらはカタログ検索の前に評価されるため、抽出ツールはこれらを安全ではないとマークし、migrate-python-i18n がそれらを書き換えます:
_(f"Hello, {name}!")
_("Hello, %s!" % name)
_("Hello, {name}!".format(name=name))migrate-python-i18n は --write を渡すまでドライランとして動作します。これは migrate-python-i18n-report.md を書き込みます。{value=} などのデバッグフィールドやネストされたフォーマット指定は報告され、そのまま残されます。
{% trans %} と {% blocktrans %} は gettext %(name)s プレースホルダーになります。Jinja は空白を削除して折りたたみます。Django はタグが trimmed と指定しない限り、内部の空白を保持します。
カタログ
フラットなJSONのキーは、ソース言語の文字列、つまりsourceLocale内のテキストです。その言語はどの言語でもかまいません。コンテキストは、context + U+0004 + そのソース文字列を使用します。複数形のスロットは、translate-uiがすでに書き込む{md5}_one、{md5}_other、およびその他のCLDR形式のままです。ヘルパーは、トリミングされた単数形をMD5でハッシュ化し、最初の8桁の16進文字を読み取ります。
Gettext ファイルはコンテキストに msgctxt を、複数形に msgid / msgid_plural を使用します。ui.gettext.compileMo は .mo を .po の隣に書き込みます。purge-locale はそのロケールの .po と .mo を削除します。flatOutput が false の場合、フラットな JSON ファイルは書き込まれていないため、そのまま残されます。
英語のソースロケールと明示的な複数形ソースを持つ t(..., plurals=True) は、モデルをスキップし、ソース文字列から one / other を保存します。
各フレームワークのロケール
set_locale は ContextVar トークンを返します。FastAPI や Flask のミドルウェアを含め、finally でリセットしてください。これにより、同時リクエスト間でロケールが漏洩するのを防ぎます。
- Streamlit。
streamlit_language_selector(sidebar=True, key="lang_selector")はst.session_state.localeとst.query_params["lang"]を書き込みます。すべてのウィジェットに固定のkeyを指定してください。examples/python-streamlitを参照してください。 - FastAPI。 ミドルウェアで
?lang=またはAccept-Languageを読み取り、set_localeを呼び出し、finally内でreset_localeを実行します。ルートはt()と_()を呼び出します。examples/python-fastapiを参照してください。 - FlaskおよびPyramid。 リクエストからロケールを設定し、
_、t、current_locale、ui_languages、およびdirectionをテンプレートコンテキストに注入します。examples/python-flaskを参照してください。 - 既存のgettext。
_()、gettext()、およびngettext()をそのままにします。ui.gettextを現在のlocales/ツリーに向け、extractを実行してからtranslate-uiを実行します。examples/python-gettextを参照してください。 - Django。
gettext、ngettext、および{% blocktrans %}を使用します。初期化テンプレートui-python-djangoは、Djangoのlocale/ディレクトリおよびdjangoドメインと一致します。 - Tkinter。 各ウィジェットの作成時に
t()または_()を呼び出し、set_localeの後に表示テキストを再構築します。 - PyQt / PySide。
self.tr("...")が抽出されます。notr="true"でない限り、.uiファイルが<string>要素を提供します。comment属性はgettextコンテキストになります。 - PyWebView / PyWebKit。 上記のPythonテンプレートを使用してPythonシェルを抽出します。
data-i18nマーカーを使用するか、ロケールごとに1つのHTMLドキュメントを使用してHTMLページを抽出します。