Переклад модулів

У цьому розділі пояснюється, як надати можливість перекладу вашому модулю.

Примітка

Якщо ви хочете зробити внесок у переклад самого Odoo, зверніться до Вікі-сторінки Odoo.

Експорт терміна, який можна перекладати

Низка термінів у ваших модулях неявно перекладається. Як результат, навіть якщо ви не виконали жодної конкретної роботи з перекладу, ви можете експортувати перекладні терміни вашого модуля та знайти контент для роботи.

Експорт перекладів виконується через інтерфейс адміністрування, увійшовши в інтерфейс серверної частини та відкривши Налаштування ‣ Переклади ‣ Імпорт / Експорт ‣ Експорт перекладів

  • залишити мову за замовчуванням (нова мова/порожній шаблон)

  • виберіть формат PO файл

  • виберіть свій модуль

  • натисніть Експорт і завантажте файл

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

Це дає вам файл під назвою 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'),
};