Переклад модулів¶
У цьому розділі пояснюється, як надати можливість перекладу вашому модулю.
Примітка
Якщо ви хочете зробити внесок у переклад самого Odoo, зверніться до Вікі-сторінки Odoo.
Експорт терміна, який можна перекладати¶
Низка термінів у ваших модулях неявно перекладається. Як результат, навіть якщо ви не виконали жодної конкретної роботи з перекладу, ви можете експортувати перекладні терміни вашого модуля та знайти контент для роботи.
Експорт перекладів виконується через інтерфейс адміністрування, увійшовши в інтерфейс серверної частини та відкривши
залишити мову за замовчуванням (нова мова/порожній шаблон)
виберіть формат PO файл
виберіть свій модуль
натисніть Експорт і завантажте файл

Це дає вам файл під назвою yourmodule.pot
, який слід перемістити до каталогу yourmodule/i18n/
. Файл є шаблоном PO, який просто містить перелік рядків, які можна перекладати, і з яких можна створювати фактичні переклади (файли PO). PO-файли можна створити за допомогою msginit, спеціального інструменту перекладу, наприклад POEdit, або просто скопіювавши шаблон у новий файл під назвою language.po
. Файли перекладу слід розміщувати в yourmodule/i18n/
поруч із yourmodule.pot
і автоматично завантажуватиме їх Odoo, коли буде встановлено відповідну мову (через :menuselection:` Налаштування –> Переклади –> Мови`)
Примітка
переклади для всіх завантажених мов також встановлюються або оновлюються під час встановлення або оновлення модуля
Неявний експорт¶
Odoo автоматично експортує перекладені рядки з вмісту типу «data»:
у представленнях, відмінних від QWeb, експортуються всі текстові вузли, а також вміст атрибутів
string
,help
,sum
,confirm
іplaceholder
Шаблони QWeb (як на стороні сервера, так і на стороні клієнта), усі текстові вузли експортуються, за винятком блоків
t-translation="off"
, вмістtitle
,alt
, атрибутиlabel
іplaceholder
також експортуютьсядля
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");
Попередження
Для експорту можна позначати лише літеральні рядки, а не вирази чи змінні. Для ситуацій, коли рядки відформатовано, це означає, що рядок форматування має бути позначено, а не відформатований рядок
Відкладена версія _
і _t
- це odoo._lt()
у python і odoo.web._lt()
у javascript. Пошук перекладу виконується лише під час візуалізації та може використовуватися для оголошення властивостей, які можна перекладати, у методах класу глобальних змінних.
Примітка
Переклади модуля за замовчуванням не доступні для інтерфейсу і тому недоступні з JavaScript. Щоб досягти цього, ім’я модуля має або мати префікс website
(так само, як website_sale
, website_event
тощо), або явно зареєструватися шляхом реалізації _get_translation_frontend_modules_name()
для моделі ir.http
.
Це може виглядати наступним чином:
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']
Змінні¶
Не, витяг може працювати, але він не перекладатиме текст правильно:
_("Scheduled meeting with %s" % invitee.name)
Встановіть динамічні змінні як параметр пошуку перекладу (це дозволить повернутися до вихідного коду у випадку відсутності заповнювача в перекладі):
_("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.")
Зберігайте в одному блоці, надаючи повний контекст перекладачам:
# 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¶
Не використовуйте терміни у множині англійською:
msg = _("You have %(count)s invoice", count=invoice_count)
if invoice_count > 1:
msg += _("s")
Не забувайте, що кожна мова має різні форми множини:
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'),
};
Робити метод пошуку відкладеного перекладу:
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, використовуйте _lt
замість _t
, щоб перекласти термін, коли він використовується:
# 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'),
};