モジュールの翻訳

このセクションでは、モジュールに翻訳機能を提供する方法を説明します。

注釈

Odoo 自体の翻訳に貢献したい場合は、 Odoo Wiki ページ を参照してください。

翻訳可能な用語のエクスポート

モジュール内の多くの用語は暗黙的に翻訳可能です。 結果として、翻訳に対して具体的な作業を行っていない場合でも、 モジュールの翻訳可能な用語をエクスポートして、コンテンツを見つけることができます。

Translations export is perform via the administration interface by logging into the backend interface and opening Settings ‣ Translations ‣ Import / Export -> Translations

  • 言語を既定のままにする (新しい言語/空のテンプレート)

  • PO File format を選択します

  • モジュールを選択してください

  • Export をクリックしてファイルをダウンロードします

../../_images/po-export.png

This gives you a file called yourmodule.pot which should be moved to the yourmodule/i18n/ directory. The file is a PO Template which simply lists translatable strings and from which actual translations (PO files) can be created. PO files can be created using msginit, with a dedicated translation tool like POEdit or by simply copying the template to a new file called language.po. Translation files should be put in yourmodule/i18n/, next to yourmodule.pot, and will be automatically loaded by Odoo when the corresponding language is installed (via Settings ‣ Translations ‣ Languages)

注釈

モジュールのインストールまたは更新時に、読み込まれたすべての言語の翻訳もインストールまたは更新されます。

暗黙のエクスポート

Odoo automatically exports translable strings from "data" type content:

  • 非QWebビューでは、すべてのテキストノードがエクスポートされ、stringhelpsumconfirmationplaceholder 属性の内容がエクスポートされます。

  • QWeb テンプレート (サーバーサイドとクライアントサイドの両方) は、t-translation="off" ブロック内を除くすべてのテキストノードがエクスポートされます。 title, alt, label および placeholder 属性の内容もエクスポートされます

  • for Field の場合、モデルが _translate = False でマークされていない限り:

    • stringhelp 属性がエクスポートされます

    • selection が存在し、リスト(またはタプル)がエクスポートされます。

    • translate 属性が True に設定されている場合、すべての既存の値がエクスポートされます

  • _constraints_sql_constraints のヘルプ/エラーメッセージがエクスポートされます

明示的なエクスポート

PythonコードやJavascriptコードの中で、より多くの「命令的」な状況になるとき。 Odoo は翻訳可能な用語を自動的にエクスポートできないため、エクスポート用に明示的にマークする必要があります。 これは、文字列を関数呼び出しでラップすることによって行われます。

Python では、ラッピング関数は odoo.api.Environment._()odoo.tools.translate._() です:

title = self.env._("Bank Accounts")

# old API for backward-compatibility
from odoo.tools import _
title = _("Bank Accounts")

JavaScript では、ラッピング関数は odoo.web._t():

title = _t("Bank Accounts");

警告

エクスポートには、文字列のみをマークでき、式や変数ではありません。 文字列がフォーマットされる場合、フォーマットされた文字列ではなくフォーマット文字列を選択する必要があります。

_`と`_t`の怠惰なバージョンは、Pythonの :class:`odoo.tools.translate.LazyTranslate ファクトリで、javascriptの:js:func:odoo.web._lt です。 翻訳ルックアップはレンダリング時にのみ実行され、グローバル変数のクラスメソッドで翻訳可能なプロパティを宣言するために使用できます。

from odoo.tools import LazyTranslate
_lt = LazyTranslate(__name__)
LAZY_TEXT = _lt("some text")

注釈

モジュールの翻訳はデフォルトでフロントエンドに公開されていないため、JavaScriptからはアクセスできません。 そのためには、モジュール名に website を付ける必要があります(website_salewebsite_event`などと同じように)。 または `ir.http モデルに _get_translation_frontend_modules_name() を実装することで明示的に登録します。

これは以下のようになります。

from odoo import models

class IrHttp(models.AbstractModel):
    _inherit = 'ir.http'

    @classmethod
    def _get_translation_frontend_modules_name(cls):
        modules = super()._get_translation_frontend_modules_name()
        return modules + ['your_module']

コンテキスト

翻訳するには、翻訳関数は languagemodule の名前を知っている必要があります。``Environment を使用する場合。 `` 言語は知られており、パラメータとしてモジュール名を渡すことができます。それ以外の場合は、呼び出し元から抽出されます。

odoo.tools.translate._ の場合、言語とモジュールはコンテキストから抽出されます。この場合、呼び出し元のローカル変数を調べます。 このメソッドの欠点は、コンテキスト変数や self を見つけようとすることです。 しかし、nv`` はモデルメソッド以外で翻訳を使用している場合には存在しない場合があります。すなわち、通常の関数やPython内では動作しません。

遅延翻訳は作成時にモジュールにバインドされ、str() を使用して評価するときに言語が解決されます。 魔法の言語を解決せずに Envionrment._ に遅延翻訳を渡すこともできます。

変数

しない 抽出は動作するかもしれませんが、テキストを正しく翻訳しません:

_("Scheduled meeting with %s" % invitee.name)

**Do**は、動的変数を翻訳ルックアップのパラメータとして設定します(これは翻訳でプレースホルダが見つからない場合はソースにフォールバックします)。

_("Scheduled meeting with %s", invitee.name)

ブロック

翻訳を複数のブロックまたは複数の行に分割しない

# bad, trailing spaces, blocks out of context
_("You have ") + len(invoices) + _(" invoices waiting")
_t("You have ") + invoices.length + _t(" invoices waiting");

# bad, multiple small translations
_("Reference of the document that generated ") + \
_("this sales order request.")

Do は1つのブロックに入れて、翻訳者にフルコンテキストを与えます:

# good, allow to change position of the number in the translation
_("You have %s invoices wainting") % len(invoices)
_.str.sprintf(_t("You have %s invoices wainting"), invoices.length);

# good, full sentence is understandable
_("Reference of the document that generated " + \
  "this sales order request.")

複数形

しない 英語の方法用語を複数化する:

msg = _("You have %(count)s invoice", count=invoice_count)
if invoice_count > 1:
  msg += _("s")

Do はすべての言語に異なる複数形があることを覚えておいてください::

if invoice_count > 1:
  msg = _("You have %(count)s invoices", count=invoice_count)
else:
  msg = _("You have one invoice")

読み込み対実行時間

実行しない サーバ起動時の翻訳ルックアップを呼び出す:

ERROR_MESSAGE = {
  # bad, evaluated at server launch with no user language
  'access_error': _('Access Error'),
  'missing_error': _('Missing Record'),
}

class Record(models.Model):

  def _raise_error(self, code):
    raise UserError(ERROR_MESSAGE[code])

JavaScriptファイルが読み込まれているときに、翻訳の検索を実行しない :

# bad, js _t is evaluated too early
var core = require('web.core');
var _t = core._t;
var map_title = {
    access_error: _t('Access Error'),
    missing_error: _t('Missing Record'),
};

Do lazy translation lookup methodを使う:

ERROR_MESSAGE = {
  'access_error': _lt('Access Error'),
  'missing_error': _lt('Missing Record'),
}

class Record(models.Model):

  def _raise_error(self, code):
    # translation lookup executed at error rendering
    raise UserError(ERROR_MESSAGE[code])

または**実行** 翻訳可能なコンテンツを動的に評価する

# good, evaluated at run time
def _get_error_message(self):
  return {
    access_error: _('Access Error'),
    missing_error: _('Missing Record'),
  }

JSファイルが*read*である場合、翻訳の検索が行われる場合は**やります** `_t`の代わりに`_lt`を使用して、*使用される*時の用語を翻訳します。

# good, js _lt is evaluated lazily
var core = require('web.core');
var _lt = core._lt;
var map_title = {
    access_error: _lt('Access Error'),
    missing_error: _lt('Missing Record'),
};