Pull to refresh

Comments 14

Это все хорошо, а если нужен перевод не просто русский-ангийский, а русский-ангийский-немецкий, как быть с оформлением файла django.po? Он ведь по большму счету представляет собой хеш таблицу где строчному ключу соответствует только одно значение.
Спасибо, буду, впредь, более внимательно смотреть доки.
Согласно документации по django, вам нужно иметь по одному файлу django.po для каждого из языков (ну кроме английского, который используется для идентификации сообщений).

Вы размещаете файлы django.po в подкаталогах каталога locale (либо в проекте — для всего проекта, либо в приложении — для конкретного приложения), соответствующих поддерживаемым языкам. Например, для русского — locale/ru/LC_MESSAGES/django.po, для французского locale/fr/LC_MESSAGES/django.po, и так далее.

Подсистема интернационализации django определяет текущий язык по параметрам запроса и отдает содержимое, соответствующее фразам, заготовленным в файле django.po в каталоге для языка пользователя. Если каталог с описанием фраз для данного языка не найден, по умолчанию используются строки msgid.

В контексте статьи, вы можете заготовить файл django.po для русского языка с помощью django-make-i18n, а затем скопировать его в каталоги для других языков и вставить фразы на этих языках.
Что бы не редактировать все в ручную есть батарейка django-rosetta, она расскажет вам какие данные уже переведены, а какие ещё нет, и предоставит удобный интерфейс добавления/удаления переводов

manage.py makemessages
На основе уже имеющихся в проекте ugettext и подобных функций строит .po файлы
Поделюсь и своим опытом создания многоязычных приложений.
Одним из немаловажных моментов является переключатель языка и пара нюансов вокруг этого, которые некоторые не соблюдают(и даже не осознают что они есть)

Допустим пишем мы сайт для русского и английского, в настройках у нас имеется:

...
LANGUAGES = (
    ("ru", "Russian"),
    ("en", "English"),    
)
...


это еще куда не шло, в выпадающем меню языки будут на английском(ну его наверняка знают больше людей).

Но некоторые умудряются еще и так:

from django.utils.translation import ugettext_lazy as _
бла-бла..
LANGUAGES = (
    ("ru", _("Russian")),
    ("en", _("English")),    
)
...

Это зачем вообще так делать? Это значит что если включен русский, тов списке будет: Русский, Английский.
А теперь представьте себе как англоязычным людям искать свой английский? Что если языков много?
Представляете если вы заходите на китайский сайт, там есть русский, но вы не можете об этом знать и переключить! Потомучто в выпадающем меню написано «Русский» — по-китайски!!!

Лучше уж все оставить на английском верно?

А ну на самом деле есть более элегантное решение, штатными средствами Django:

Оставляем это как угодно:

...
LANGUAGES = (
    ("ru", "Russian"),
    ("en", "English"),    
)
...


а дальше создаем форму для переключения зыков:

from django.utils.translation import get_language_info
from django.conf import settings

#Сначала мы формируем нормальный CHOICES:

LANGUAGES = [
    (code, get_language_info(code).get("name_local"))
    for code, lang in settings.LANGUAGES
]

class SettingsForm(forms.Form):
    
    if settings.USE_I18N:
        language = forms.ChoiceField(
            label=_("Language"),
            choices=LANGUAGES,
            required=False
        )


Теперь у нас в списке каждый язык написан на своем собственном языке: Русский, English
И носителю каждого из языков, будет легко и просто найти свой родной язык!
Еще бы прикрутить сюда автоматический перевод с помощью гугло транслейт.
Было бы совсем для лентяев.
Не получится.

Во-первых, строки с форматированием будут содержать placeholders (как ето будет по-рюсски?) вида %(member)s или %s, на которых транслятор сойдет с ума.

Во-вторых, даже на нормальных фразах с чуть более сложной грамматикой, любой известный мне автотранслятор тоже сходит с ума. Я все-таки предпочитаю честно отдать перевод на откуп человеку, чем создавать необоснованную иллюзию сделанной работы. А то получится например, как у китайцев, пытающихся перевести названия своих поделок для андроида (далее цитата из А-Маркета, топ поиска «Игры для детей»):

===========

«Плоды памяти игру для детей»

Описание

«Яблоко, апельсин, клубника… Есть очень много фруктов здесь! И ваша задача найти эти же фрукты и сопоставить их. Эта забавная игра памяти также помогает Вам обучение памяти способности. Удачи!»

===========

Похоже на русский язык? Да, немного :)
Не понял, в чем принципиальное отличие от manage makemessages?
django-rosetta решает большинство описанных здесь проблем.
manage.py makemessages собирает только сообщения, помеченные обращениями к подсистеме i18n (в исходниках — *gettext, в шаблонах — trans и blocktrans).

Данный скрипт собирает сообщения в таком проекте django, в котором нет обращений к подсистеме i18n (не было изначально предусмотрено при разработке), и помечает их обращениями к подсистеме i18n. При этом, собираются только те сообщения, которые содержат локальный язык (распознаются регекспами).

Тем самым, выполняется задача интернационализации такого проекта, который изначально не был предусмотрен к интернационализации. Приведенный скрипт не заменяет собой makemessages, а дополняет его функции.

Это достаточно узкая, одноразовая задача, выполнять которую, тем не менее, вручную на большом проекте достаточно муторно и долго. Обо всем этом написано в преамбуле статьи.

django-rosetta дает лишь графицский интерфейс к редактированию файлов .po, никак не помогая решать поставленную задачу сбора локальных строк.
Ога, но когда я обнаружил что такого еще не было, стало очень грустно. Пришлось смастрячить и поделиться.

Реально я думаю, потребность в таком костыле у каждого программера наверно возникнет два-три раза за всю карьеру. Тем не менее, считаю 4 потраченных дня — потраченными недаром. Список обнаруженных в проекте строк для локализации — 495, я как минимум потратил времени ровно столько, сколько потратил бы, собирая их вручную. Не учитывая внесенных в проект ошибок при ручной правке. Если хотя бы один человек успешно воспользуется моей тулой на достаточно обширном проекте — буду считать, что свою задачу я выполнил.
Sign up to leave a comment.

Articles