Экспорт переводимых терминов
Ряд терминов в модулях "косвенно переводимые", даже если Вы специально не выделяли какие-нибудь термины для перевода можно экспортировать переводимые термины модуля. В файле экспорта будут все слова и выражения, которые можно перевести.
Экспорт переводов осуществляется через интерфейс администрирования путем входа в интерфейс бэкэнда и открытия
Оставьте язык по умолчанию (новый язык / пустой шаблон)
Выберите формат PO File
Выберите свой модуль
Нажмите Export и загрузите файл

Это даст вам файл с именем ваш_модуль.pot
, который должен быть перемещен в каталог ваш_модуль/i18n/
. Файл представляет собой Шаблон PO, который просто перечисляет переводимые строки и из которых могут быть созданы фактические переводы (PO-файлы). PO-файлы могут быть созданы с помощью msginit, с помощью специального инструмента перевода, такого как POEdit, или путем простого копирования шаблона в новый файл с именем language.po
. Файлы перевода должны быть перенесены в директорию ваш_модуль/i18n/
, рядом с файлом ваш_модуль.pot
, и они будут автоматически загружены Odoo при установке соответствующего языка (через )
Примечание
Переводы для всех загруженных языков также устанавливаются или обновляются при установке или обновлении модуля
Неявный экспорт
Odoo автоматически экспортирует переводимые строки из содержимого типа "data":
В представлениях, отличных от QWeb, экспортируются все текстовые узлы, а также атрибуты
string
,help
,sum
,confirm
иplaceholder
Шаблоны QWeb (как на стороне сервера, так и на стороне клиента), все текстовые узлы экспортируются, кроме блоков
t-translation = "off"
, также экспортируются содержимое атрибутовtitle
,alt
,label
иplaceholder
.For
Field
, если их модель не отмечена_translate = False
:Их атрибуты
string
иhelp
экспортируютсяЕсли
selection
присутствует и список (или кортеж), он экспортируетсяЕсли их атрибут
translate
установлен вTrue
, все их существующие значения (во всех записях) экспортируются
Сообщения о помощи и об ошибках
_constraints
и_sql_constraints
экспортируются
Явный экспорт
Когда дело доходит до более "императивных" ситуаций в коде Python или кодексе Javascript, Odoo не может автоматически экспортировать переводимые термины, поэтому они должны быть отмечены явно для экспорта. Это делается путем упаковки литеральной строки в вызов функции.
В Python функция обертывания - odoo._()
:
title = _("Bank Accounts")
В JavaScript функция обертывания обычно odoo.web._t()
:
title = _t("Bank Accounts");
Предупреждение
Only literal strings can be marked for exports, not expressions or variables. For situations where strings are formatted, this means the format string must be marked, not the formatted string
Variables
Don't the extract may work but it will not translate the text correctly:
_("Scheduled meeting with %s" % invitee.name)
Do set the dynamic variables outside of the translation lookup:
_("Scheduled meeting with %s") % invitee.name
Blocks
Don't split your translation in several blocks or multiples lines:
# 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 keep in one block, giving the full context to translators:
# 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.")
Plural
Don't pluralize terms the English-way:
msg = _("You have %s invoice") % invoice_count
if invoice_count > 1:
msg += _("s")
Do keep in mind every language has different plural forms:
if invoice_count > 1:
msg = _("You have %s invoices") % invoice_count
else:
msg = _("You have %s invoice") % invoice_count
Read vs Run Time
Don't invoke translation lookup at server launch:
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])
Don't invoke translation lookup when the javascript file is read:
# 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 evaluate dynamically the translatable content:
# good, evaluated at run time
def _get_error_message():
return {
access_error: _('Access Error'),
missing_error: _('Missing Record'),
}
Do in the case where the translation lookup is done when the JS file is
read, use _lt
instead of _t
to translate the term when it is used:
# 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'),
};