Переклад модулів¶
У цьому розділі пояснюється, як надати можливість перекладу вашому модулю.
Примітка
Якщо ви хочете зробити внесок у переклад самого Odoo, зверніться до Вікі-сторінки Odoo.
Експорт терміна, який можна перекладати¶
A number of terms in your modules are implicitly translatable. As a result, even if you haven’t done any specific work towards translation, you can export your module’s translatable terms and may find content to work with.
Експорт перекладів виконується через інтерфейс адміністрування, увійшовши в інтерфейс серверної частини та відкривши
залишити мову за замовчуванням (нова мова/порожній шаблон)
виберіть формат 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'),
};