Как перевести django на русский

Django: краткое руководство по интернационализации

Перевод приложения на разные языки и его локализация — это нечто такое, чем приходится заниматься всем разработчикам. В материале, перевод которого мы сегодня публикуем, представлено краткое руководство по интернационализации Django-приложений.

Часть того, о чём тут пойдёт речь, применимо к локализации любых Python-проектов. Разобрав основы, мы поговорим об ускорении работ по интернационализации. В частности — о применении платформы Phrase.

Как перевести django на русский

Предполагается, что у читателя этого материала имеется работающее Django-приложение, и то, что у него установлен пакет gettext (установить его можно, например, командой pip install gettext ). Если вы раньше не пользовались Django (популярным веб-фреймворком, основанным на Python), то вам, возможно, будет полезно сначала взглянуть на это официальное руководство, а потом вернуться к данной статье.

Базовые настройки рабочей среды

Первый шаг нашей работы заключается в проверке того, активирована ли опция интернационализации в конфигурации проекта. Для того чтобы это сделать, нужно внести следующие изменения в mysite/settings.py :

Интернационализация шаблонов

Теперь нужно пометить все строки, которые должны быть переведены на разные языки. Представим, что у вас имеется следующий файл шаблона polls/templates/polls/index.html :

Этот файл нужно переработать следующим образом:

Интернационализация в Python-коде

Создание файлов перевода

Теперь нужно создать файлы перевода для каждого варианта языковых настроек, которые мы хотим поддерживать. Для того чтобы это сделать, создадим директорию polls/locale и в директории polls выполним следующую команду:

Теперь в этот файл можно ввести переводы строк:

Когда перевод будет готов — нужно всё скомпилировать, выполнив следующую команду:

Если теперь открыть приложение в браузере, оно должно быть переведено на немецкий язык.

Ускорение процесса локализации приложений с использованием Phrase

Если вы используете Phrase для организации работ по локализации приложений, то вам, на самом деле, не нужно вручную создавать и редактировать *.po-файлы! Вам достаточно создать и перевести ключи WelcomeHeading и WelcomeMessage в Phrase и использовать функцию экспорта для загрузки *.po-файлов.

Затем надо выполнить в корневой директории проекта следующую команду:

Благодаря этому будут обновлены все переводы проекта.

Кроме того, ещё больше упростить работу может использование в вашем Django-проекте нашего редактора In-Context Editor. Для этого достаточно установить django-phrase с помощью pip :

Затем достаточно отредактировать шаблоны, при работе с которыми вы планируете использовать In-Context-Editor :

И наконец, в конфигурационный файл нужно добавить следующее:

После этого всё будет готово к работе.

Выбор локалей

Обычно разработчики приложений устанавливают локали, основываясь на параметрах браузера пользователя. Для того чтобы это сделать, нужно привести файл mysite/settings.py к следующему виду:

Эта команда должна вернуть примерно следующее:

Итоги

В этом материале мы рассмотрели основы интернационализации Django-приложений. Здесь же мы рассказали о сервисе Phrase, который способен ускорить и упростить работу. Надеемся, то, о чём вы узнали, вам пригодится.

Уважаемые читатели! Как вы подходите к интернационализации ваших Python-проектов?

Источник

Документация Django 1.5.2

Введение¶

Для наделения вашего Django проекта возможностью представлять контент на разных языках потребуется немного доработать код и шаблоны. Под доработкой имеется в виду добавление переводимых строк. Они говорят Django: “Этот текст должен быть переведён на язык конечного пользователя, если для этого языка предоставлен перевод.” Вашей задачей является маркировка соответствующих строк, как подлежащих переводу. Система может обеспечивать перевод только тех строк, на которые вы ей указали.

Django предоставляет утилиты для извлечения переводимых строк в файл сообщений. Этот файл является удобным средством, которое позволяет переводчикам делать свою работу. После того, как перевод строк этого файла завершён, файл должен быть скомпилирован. Этот процесс обеспечивает набор средств GNU gettext.

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

Интернационализация в коде¶

Обычный перевод¶

Модуль gettext стандартной библиотеки языка Python определяет _() в качестве псевдонима для gettext() в глобальном пространстве имён. В Django мы решили не следовать этой практике по следующим причинам:

Символ подчёркивания ( _ ) используется в интерактивном интерпретаторе Python и в доктестах в качестве “результата предыдущей операции”. Определение глобальной функции _() приведёт к путанице. Явное импортирование ugettext() в виде _() решает эту проблему.

В данном примере, текст «Welcome to my site.» помечается как переводимая строка:

Очевидно, что вы можете делать тоже самое без использования псевдонима. Этот пример идентичен предыдущему:

Перевод работает с вычисляемыми значениями. Этот пример идентичен предыдущим двум:

Перевод работает с переменными. И снова, аналогичный пример:

По этой причине, вы должны использовать именованные заполнители (т.е., %(day)s ) вместо позиционных (т.е., %s или %d ), в случае, если в строку подставляется больше одного параметра. При использовании позиционных заполнителей переводчики не будут иметь возможность изменять оригинальный порядок слов.

Комментарии для переводчиков¶

Если необходимо дать переводчикам подсказку по переводимой строке, вы можете добавить комментарий с префиксом Translators в строке предшествующей переводимой, например:

Этот подход также работает в шаблонах. Обратитесь к Комментарии для переводчиков шаблонов для подробностей.

Пометка строк как no-op¶

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

Множественное число¶

Функция ungettext принимает три аргумента: строка в единственном числе, строка во множественном числе и количество объектов.

Эта функция очень полезна, когда требуется локализовать Django приложение на языки, в которых количество и сложность множественных форм превышает два варианта как в английском языке (‘object’ для единственного числа и ‘objects’ для всех остальных случаем, когда count отличается от единицы, независимо от своего значения.)

Давайте рассмотрим более сложный пример:

Здесь мы используем локализованные и, надеюсь, уже переведённые строки (описанные в полях verbose_name и verbose_name_plural модели Meta ) для других частей предложения.

При использовании данного подхода, проверьте, что вы используете уникальные имена для каждой переменной, указанной в строке. В вышеприведённом примере, обратите внимание на то, как мы используем переменную name в обоех строках. Следующий пример выдаст ошибку:

Контекстные маркеры¶

Ленивый перевод¶

Эти функции хранят ленивую ссылку на строку, не на её перевод. Сам перевод будет выполнен во время использования строки в строковом контексте, например, во время обработки шаблона.

Это полезно, когда функция перевода вызывается при загрузке модуля.

Такое может легко произойти во время определения моделей, форм или модельных форм, так как в Django их поля реализованы в виде атрибутов класса. По этой причине, надо использовать ленивый перевод в следующих случаях:

Поля модели и связанные с ними значения атрибутов verbose_name и help_text ¶

Например, для перевода подсказки для поля name в следующей модели, действуйте так:

Значения для подписи модели¶

Значения атрибута short_description у методов модели¶

Для методов модели вы можете с помощью атрибута short_description предоставить перевод для Django и интерфейса администратора:

Работа с ленивыми объектами перевода¶

Результат вызова ugettext_lazy() может быть использован везде, где требуется юникодная строка (объект типа unicode ). Если вы попытаетесь использовать её там, где ожидается обычная строка (объект типа str ), то не получите ожидаемый результат, так как объект ugettext_lazy() не знает, как преобразовать себя в обычную строку. Вы не можете использовать юникодную строку внутри обычной, что, в общем, является обычным поведением в Python. Например:

Использование ugettext_lazy() и ungettext_lazy() для пометки строк в моделях и в прикладных функциях является обычной операцией. Работая с этими объектами в вашем коде, вы должны быть уверены, что вы не преобразоваете их случайно в строки, так как это преобразование должно происходить как можно позже (и будет приниматься во внимание правильная локаль). Это потребует использования вспомогательной функции, описанной далее.

Объединение строк: string_concat()¶

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

Другое использование ленивости в отложенных переводах¶

Для остальных случаев, когда вам надо отсрочить перевод, но приходится передавать переводимую строку в качестве аргумента другой функции, вы можете обернуть эту функцию в ленивый вызов. Например:

Источник

Мультиязычность и перевод в Django

5 марта 2016 г. 6:40

Краткая шпаргалка по тому, как сделать мультиязычный сайт в Django.

1. Настраиваем settings.py

Несколько простых строк в settings.py позволят добавить многоязычность сайту:

2. Подготавливаем слова и фразы для перевода

Пример работы с уже переведёнными словами другими приложениями, например, Name

Чтобы использовался наш перевод, нужно выполнить один из вариантов:

Немного подробнее про pgettext_lazy

По контексту (первый аргумент функции pgettext_lazy ) Django определяет вариант перевода.

3. Создаём файлы для перевода и компилируем

Возможен запуск с конкретного приложения:

Данная команда с указанного места проходит по всем файлам, папкам и подпапкам, ищет слова и фразы, подготовленные для перевода, и формирует единый файл с переводом для указанного языка. Но здесь есть один нюанс. Вышеописанная команда по разным причинам может не сработать. У меня, допустим, для одного проекта появлялась следующая ошибка:

Я держу папку виртуального окружения в корне проекта, поэтому команда makemessages обошла все установленные зависимости для проекта и встретила проблему с переводом пакета xlwt. Для решения проблемы нужно исключить ненужные папки для команды, например, так:

Команда исключит папки env и services.

После того как папки с языками создались для обновления перевода всех языков можно воспользоваться командой:

Ключ -a указывает, чтобы команда обновила перевод для всех существующих языков.

Фрагмент файла ‘ru/LC_MESSAGES/django.po’:

Обратите внимание, что если мы использовали pgettext_lazy, то в файле django.po будет ещё добавлен msgctxt для переводимого слова, например:

Иногда django может пометить фразы как fuzzy. Например:

Чтобы Django начала использовать перевод, нужно его скомпилировать (и так делать каждый раз после обновления файлов перевода):

Если вызов команды compilemessages происходит из корня проекта, то будут компилироваться файлы перевода всех приложений. Если же вызов команды происходит с конкретного приложения:

то будут компилироваться файлы только этого приложения, что существенно быстрее по сравнению компиляции файлов всех приложений.

4. Добавляем в шаблон код смены языка

Начиная с Django 1.9 переключатель языка можно добавить так:

Затем можно добавить сам html-код переключателя в шаблон:

Это пример взят из документации и немного изменён (добавил перевод кнопки).

Если вы используете django-cms, то всё ещё проще: достаточно просто использовать в шаблоне следующий код (без дополнительных подключений django.conf.urls.i18n урлов):

Как видите, здесь используется шаблонный тег page_language_url приложения menus, поэтому, если вы не используете django-cms, то, в принципе, можно подключить только приложение menus для упрощения переключения между языками.

Дополнительные материалы по теме

Решение возможных ошибок

1. Не подгружается китайский язык

Спасибо loujessler за совет: /it/translate-django/#comment_435:

Попробуйте вместо знака тире «-» ставить «_» и вместо нижнего регистра буквы «h» на «H». Таким образом, это будет выглядеть так:

Источник

Полная русификация админки

Как перевести django на русский
Здравствуйте. На днях возникла задача русифицировать админку django включая названия моделей, полей и приложений. Основной целью было избежать модифицирования кода django. Продолжительное гугление не дало целостной картины этого процесса. Поэтому я решил собрать все в одном месте.
Сразу скажу, что еще в самом начале проекта поставил django-admin-tools и тем самым сохранил себе некоторое количество нервных клеток. А все манипуляции проводились над django 1.3.

Подготовка

Для начала пропишем в конфигурационном файле

Затем создадим свои классы для приборной панели и меню django-admin-tools. Для этого выполним последовательно команды

python manage.py custommenu
python manage.py customdashboard

В результате выполнения этих комманд у вас в корневой директории проекта появятся два файла dashboard.py и menu.py. Далее в конфигурационном файле проекта нужно указать где находятся нужные классы. Для этого допишем в него следующие строчки

Путь может быть любой. Главное чтоб по нему находились нужные классы

При выполнении этой команды будут просканированы все файлы на предмет обращения к словарю и составлен файл django.po, который появится в папке locale/ru/LC_MESSAGES. Можно выполнять эту команду регулярно после добавлений новых обращений к словарю в коде или же править файл django.po руками.
Чтоб изменения в словаре вступили в силу нужно выполнить команду

python manage.py compilemessages

после завершения которой рядом с файлом django.po появится django.mo.

Перевод имени приложения

Первым делом нужно заставить админку отображать русское название для имени приложения. На одном из форумов советовали просто прописать в поле app_label подкласса Meta в модели нужное значение, но от этого я отказался сразу. Так как меняется url приложения и с syncdb начались проблемы. Перекрытие метода title у str тоже не помогло так как слетал фильтр и admin-tools начинал лепить все модели в один бокс.
Я обычно запускаю команду makemessages в процессе работы над проектом, а значит нам нужно место, где будет обозначено обращение к словарю. Проще говоря я вписываю в файл __init__.py своего приложения следующий код

Здесь мы импортируем модуль ugettext_lazy и делаем обращение к словарю за переводом. Если после этого запустить команду makemessages еще раз, то в файл django.po будут добавлены следующие строки

#: feedback/__init__.py:2
msgid «Feedback»
msgstr «»

и мы сможем подставить в msgstr свой перевод. В данном случае «Обратная связь». Теперь нам нужно сделать так чтоб при отображении шаблона названия приложения бралось из нашего словаря. Для этого сначала переопределим шаблон app_list.html. Этот шаблон используется при выводе модуля AppList.
В нашей директории templates создадим определенную структуру директорий и положим туда файл app_list.html так чтоб у нас получился путь

templates/admin_tools/dashboard/modules/add_list.html

Этот файл должен иметь то же содержание что и оригинальный app_list.html. Теперь изменим код в строке 5 на следующий

Таким образом при отображении названия приложения в общем списке будет браться наше значение из словаря.
В общем списке название отображается нормально, но когда мы заходим в само приложение, то заголовок модуля все еще не переведен. Для того чтоб исправить это заглянем в наш файл dashboard.py, который мы создавали в начале, и найдем там класс CustomAppIndexDashboard. Он отвечает за формирования страницы приложения в админке. В его методе __init__ исправим код чтоб получить следующее

Здесь мы завернули self.app_title в функцию ugettext_lazy и теперь на странице приложения название будет так же переведено.
Остались только хлебные крошки. Там по-прежнему отображается оригинальное название.
Модуль breadcrumbs используется в большом количестве шаблонов, поэтому за мыслями я полез потрошить файлы django.contrib.admin. Результатом чего стал вот такой класс. Его надо прописать в файле admin.py вашего приложения до регистрации модулей админки. Забегая вперед скажу, что здесь мы так же переводим и заголовки страниц просмотра, редактирования и добавления модели c помощью библиотеки, о которой расскажу чуть ниже.

При помощи него мы заменяем контекст для рендеринга шаблона на вызов функции ugettext_lazy. Таким образом мы перевели название приложения в хлебных крошках и заголовке страницы. Но это еще не все. Для полноты картины нам надо перегрузить еще один шаблон admin/app_index.html И строку 11 заменим на

Осталось только перевести имя приложения в выпадающем меню. Для этого достаточно перегрузить шаблон admin_tools/menu/item.html и поправить пару строк. В блок load второй строки добавляем i18n, а в конец 5й строки вместо << item.title >> пишем <% trans item.title %>.
Теперь все названия нашего приложения будут отображаться из словаря django.mo. Можем идти дальше

Перевод названия модели и полей

Если название приложения нам нужно просто выводить в переведенном виде, то название модели хорошо бы выводить с учетом падежа, рода и числа. В поисках красивого решения я наткнулся на великолепный модуль pymorphy от kmike, за который ему огромное спасибо. Он очень удобен в использовании и прекрасно делает свою работу! К тому же для админки нам большая скорость не нужна. Все что нам остается — это установить модуль pymorphy и интегрировать его в django руководствуясь шагами из документации.
Теперь нам нужно переопределить несколько шаблонов в админке и расставить там фильтры pymorphy при этом все переводы строк должны оставаться в одном месте. А именно в файле django.po.
Дальше будем для примера русифицировать модель Picture чтоб она отображалась как «Картинка». Первым делом в этой модели пропишем

И добавим в файл django.po

msgid «picture»
msgstr «картинка»

msgid «pictures»
msgstr «картинки»

msgid «title»
msgstr «заголовок»

Теперь осталось сделать чтоб переведенные слова отображались с учетом падежа и числа
Начнем с шаблона admin/change_list.html. Он отвечает за вывод списка элементов модели. Для начала добавим в блок load модуль pymorphy_tags. Например в строку 2. Чтоб получилось

Далее находим там строку 64, которая отвечает за вывод кнопки добавления

Здесь мы добавили изменение названия модели в винительный падеж. И получили правильную надпись «Добавить картинку». Подробнее о формах изменения можно почитать здесь.
Заголовки страниц уже переведены в нужной форме с помощью класса I18nLabel так что можно двигаться дальше.
Теперь перегрузим шаблон admin/change_form.html. Сначала нужно добавить модуль pymorphy_tags в блок load, а затем исправить там хлебные крошки заменив в строке 22

Далее во списку идет шаблон admin/delete_selected_confirmation.html. В нем все правки делаем тем же способом, что и в предыдущих случаях. Здесь нужно сначала исправить хлебные крошки вот так

К сожалению функция delete_selected, которая отвечает за вывод этой страницы не поддерживает extra_context, что меня очень печалит. Поэтому я сделал свой фильтр, который изменяет форму числа в зависимости от величины объекта.

Теперь во всех местах надо расширить блок blocktrans примерно так

<% blocktrans %>Are you sure you want to delete the selected << objects_name >>? All of the following objects and their related items will be deleted: <% endblocktrans %>
исправить на
<% blocktrans with objects_name|inflect:"вн"|plural_from_object:deletable_objects as objects_name %>Are you sure you want to delete the selected << objects_name >>? All of the following objects and their related items will be deleted:

После всего этого остается лишь перегрузить шаблон admin/pagination.html, подключить в нем модуль pymorphy_tags и заменить в нем строку 9 на

фильтр lower я добавил потому что возникала ошибка при преобразовании прокси объекта gettext в фильтре plural. Но, возможно, это у меня в окружении такой глюк и у вас не будет необходимости его добавлять.

Следующий по плану шаблон admin/filter.html Тут просто первые две строки заменить на

Остались только пользовательские сообщения, которые все еще выводятся без учета числа. Для того чтоб исправить эту досадную несправедливость нужно переопределить метод message_user у класса ModelAdmin. Можно вставить это в admin.py. У меня получилось делать следующим образом

Здесь мы разбираем сообщение по словам и склоняем их в нужную форму. Отдельно отличаются сообщения для групп объектов и для единиц.

Вот теперь мы можем наблюдать примерно такую картинку
Как перевести django на русский

Заключение

Отсутствие предусмотренных решений в архитектуре django, безусловно, расстраивает, но все в наших руках. Возможно некоторые решения могут показаться вам кривыми, но я пока не нашел способа сделать это изящнее.
При написании статьи я старался изложить кратко и по пунктам, и не смотря на количество текста получается не так много движений для достижения результата. Это при условии использования приведенного выше кода.

Основная цель этой работы была перевести административный интерфейс и сохранить все переведенные строки в одном месте, а именно в языковом файле. Что мы и получили.

Буду благодарен за любые замечания и предложения. Спасибо за внимание.

P.S. Уже готовые шаблоны вы можете забрать здесь. Вам нужно будет распаковать содержимое архива в вашу директорию templates.

[UPD]: Михаил (kmike) завел проект на bitbucket под названием django-russian-admin для автоматизации всех приведенных выше действий.

Источник

документация Django 3.0

Введение¶

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

Механизм интернационализации Django включен по умолчанию, т.е. в определённых местах фреймворка всегда присутствует небольшая трата ресурсов на его работу. Если вы не используете интернационализацию, то вам следует потратить пару секунд на установку USE_I18N = False в файле конфигурации. Это позволит Django выполнять некоторую оптимизацию, не подгружая библиотеки интернационализации.

Интернационализация в коде¶

Обычный перевод¶

The u prefixing of gettext functions was originally to distinguish usage between unicode strings and bytestrings on Python 2. For code that supports only Python 3, they can be used interchangeably. A deprecation for the prefixed functions may happen in a future Django release.

Модуль gettext стандартной библиотеки языка Python определяет _() в качестве псевдонима для gettext() в глобальном пространстве имён. В Django мы решили не следовать этой практике по следующим причинам:

Because of how xgettext (used by makemessages ) works, only functions that take a single string argument can be imported as _ :

В данном примере, текст «Welcome to my site.» помечается как переводимая строка:

You could code this without using the alias. This example is identical to the previous one:

Перевод работает с вычисляемыми значениями. Этот пример идентичен предыдущим двум:

Перевод работает с переменными. И снова, аналогичный пример:

The strings you pass to _() or gettext() can take placeholders, specified with Python’s standard named-string interpolation syntax. Example:

По этой причине, вы должны использовать именованные заполнители (т.е., %(day)s ) вместо позиционных (т.е., %s или %d ), в случае, если в строку подставляется больше одного параметра. При использовании позиционных заполнителей переводчики не будут иметь возможность изменять оригинальный порядок слов.

Комментарии для переводчиков¶

Если необходимо дать переводчикам подсказку по переводимой строке, вы можете добавить комментарий с префиксом Translators в строке предшествующей переводимой, например:

Этот подход также работает в шаблонах. Обратитесь к Комментарии для переводчиков шаблонов для подробностей.

Пометка строк как no-op¶

Use the function django.utils.translation.gettext_noop() to mark a string as a translation string without translating it. The string is later translated from a variable.

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

Множественное число¶

Use the function django.utils.translation.ngettext() to specify pluralized messages.

ngettext() takes three arguments: the singular translation string, the plural translation string and the number of objects.

Эта функция очень полезна, когда требуется локализовать Django приложение на языки, в которых количество и сложность множественных форм превышает два варианта как в английском языке („object“ для единственного числа и „objects“ для всех остальных случаем, когда count отличается от единицы, независимо от своего значения.)

Следует отметить, что приведение существительного к множественному числу является непростой задачей и работает по-разному в каждом языке. Сравнение count с 1 не всегда будет корректным правилом. Следующий код выглядит разумно, но будет выдавать неверный результат для некоторых языков:

Don’t try to implement your own singular-or-plural logic; it won’t be correct. In a case like this, consider something like the following:

Множественная форма и файлы перевода

Контекстные маркеры¶

Ленивый перевод¶

Используйте ленивые версии функций перевода из django.utils.translation (их легко опознать по суффиксу lazy в их именах) для отложенного перевода строк – перевод производится во время обращения к строке, а не когда вызывается функция.

Эти функции хранят ленивую ссылку на строку, не на её перевод. Сам перевод будет выполнен во время использования строки в строковом контексте, например, во время обработки шаблона.

Это полезно, когда функция перевода вызывается при загрузке модуля.

Такое может легко произойти во время определения моделей, форм или модельных форм, так как в Django их поля реализованы в виде атрибутов класса. По этой причине, надо использовать ленивый перевод в следующих случаях:

Поля модели и связанные с ними значения атрибутов verbose_name и help_text ¶

Например, для перевода подсказки для поля name в следующей модели, действуйте так:

Значения для подписи модели¶

Значения атрибута short_description у методов модели¶

Для методов модели вы можете с помощью атрибута short_description предоставить перевод для Django и интерфейса администратора:

Работа с ленивыми объектами перевода¶

The result of a gettext_lazy() call can be used wherever you would use a string (a str object) in other Django code, but it may not work with arbitrary Python code. For example, the following won’t work because the requests library doesn’t handle gettext_lazy objects:

You can avoid such problems by casting gettext_lazy() objects to text strings before passing them to non-Django code:

If you don’t like the long gettext_lazy name, you can alias it as _ (underscore), like so:

Using gettext_lazy() and ngettext_lazy() to mark strings in models and utility functions is a common operation. When you’re working with these objects elsewhere in your code, you should ensure that you don’t accidentally convert them to strings, because they should be converted as late as possible (so that the correct locale is in effect). This necessitates the use of the helper function described next.

Ленивый перевод и перевод множественного числа¶

Используя ленивый перевод для срок с множественным числом ( [u]n[p]gettext_lazy ), вы не знаете значение аргумента number при определении строки. Однако, вы можете использовать аргумент number вместо числа. При определении перевода number будет определяться из переданных аргументов. Например:

Если строка принимает только один аргумент, вы можете передать непосредственно number :

Formatting strings: format_lazy() ¶

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

Другое использование ленивости в отложенных переводах¶

Для остальных случаев, когда вам надо отсрочить перевод, но приходится передавать переводимую строку в качестве аргумента другой функции, вы можете обернуть эту функцию в ленивый вызов. Например:

Локализованные названия языков¶

Функция get_language_info() предоставляет детальную информацию о языках:

Интернационализация: в коде шаблонов¶

Translated strings will not be escaped when rendered in a template. This allows you to include HTML in translations, for example for emphasis, but potentially dangerous characters (e.g. » ) will also be rendered unchanged.

Шаблонный тег trans ¶

Шаблонный тег <% trans %>может переводить как обычную строку, заключенную в одинарные или двойные кавычки, так и содержимое переменой:

Internally, inline translations use an gettext() call.

В случае передачи шаблонной переменой (см. выше myvar ) в тег, тег сначала преобразовывает её в строку, а затем ищет для неё перевод в каталогах сообщений.

Если требуется получать переведённые строки без их отображения, то вы можете использовать следующий синтаксис:

На практике вы будете применять это для получения строк, которые используются во множестве мест шаблона или должны быть использованы в качестве аргументов для других шаблонных тегов или фильтров:

Тег <% trans %>также поддерживает контекстные маркеры с помощью атрибута context :

Шаблонный тег blocktrans ¶

Для перевода шаблонных выражений, скажем, с доступом к атрибутам объекта или с использованием шаблонных фильтров, потребуется связать выражение с локальной переменной для использования внутри переводимого блока. Примеры:

Вы можете использовать несколько выражений внутри одного тега blocktrans :

Как и прежде, тег поддерживает старое форматирование:

Внутри тега blocktrans запрещается использовать другие блочные теги (например <% for %>или <% if %>).

If resolving one of the block arguments fails, blocktrans will fall back to the default language by deactivating the currently active language temporarily with the deactivate_all() function.

Этот тег также поддерживает склонение, например:

Более сложный пример:

When you use both the pluralization feature and bind values to local variables in addition to the counter value, keep in mind that the blocktrans construct is internally converted to an ngettext call. This means the same notes regarding ngettext variables apply.

Обратное разрешение URL не можно быть выполнено внутри blocktrans и должно выполняться заранее:

Если требуется получать переведённые строки без их отображения, то вы можете использовать следующий синтаксис:

На практике вы будете применять это для получения строк, которые используются во множестве мест шаблона или должны быть использованы в качестве аргументов для других шаблонных тегов или фильтров:

Тег <% blocktrans %>также поддерживает контекстные маркеры с помощью атрибута context :

Например, следующий тег <% blocktrans %>:

Строки передаваемые в шаблонные теги и фильтры¶

Для перевода строк, передаваемых в теги и фильтры, можно использовать _() :

В этом случае, и тег, и фильтр увидят заранее переведённую строку, т.е. им не надо будет беспокоиться о переводе.

Комментарии для переводчиков шаблонов¶

Переключения языка в шаблоне¶

Если вы хотите выбрать язык в шаблоне, используйте тег language :

Первая фраза «Welcome to our page» будет использовать текущий язык, в то время как вторая будет на Английском.

Другие теги¶

Эти теги также требуют наличия <% load i18n %>в шаблоне.

get_available_languages ¶

get_current_language ¶

get_current_language_bidi ¶

i18n context processor¶

get_language_info ¶

Вы также можете получить информацию о любом доступном языке, используя предоставленные шаблонные теги и фильтры. Для получения информации об одном языке используйте тег <% get_language_info %>:

Затем вы можете узнать следующее:

get_language_info_list ¶

Также вы можете использовать шаблонный тег <% get_language_info_list %>для получения информации о списке языков (т.е. об активных языках, которые указаны в параметре конфигурации LANGUAGES ). Обратитесь к разделу, описывающему представление для переключения языков для получения примера тог, как показать элемент для выбора языка с помощью <% get_language_info_list %>.

In addition to LANGUAGES style list of tuples, <% get_language_info_list %>supports lists of language codes. If you do this in your view:

вы можете по очереди пройтись по этим языкам в шаблоне:

Шаблонные фильтры¶

There are also some filters available for convenience:

Интернационализация на уровне кода JavaScript¶

Добавление переводов в JavaScript вызывает ряд проблем:

Django предоставляет интегрированное решение для этих проблем. Перевод внедряется в JavaScript, т.е. вы можете использовать gettext и остальные функции в JavaScript коде.

The main solution to these problems is the following JavaScriptCatalog view, which generates a JavaScript code library with functions that mimic the gettext interface, plus an array of translation strings.

The JavaScriptCatalog view¶

A view that produces a JavaScript code library with functions that mimic the gettext interface, plus an array of translation strings.

Attributes

Example with default values:

Example with custom packages:

Example with i18n_patterns() :

The precedence of translations is such that the packages appearing later in the packages argument have higher precedence than the ones appearing at the beginning. This is important in the case of clashing translations for the same literal.

If you use more than one JavaScriptCatalog view on a site and some of them define the same strings, the strings in the catalog that was loaded last take precedence.

Использование каталога переводов JavaScript¶

To use the catalog, pull in the dynamically generated script like this:

Здесь используется запрос на поиск URL для представления, генерирующего JavaScript-каталог. После загрузки каталога, ваш JavaScript код может использовать следующие методы:

gettext ¶

Функция gettext работает аналогично стандартной функции gettext Python:

ngettext ¶

Функция ngettext позволяет получать слова и предложения в множественной формеы:

interpolate ¶

Функция interpolate поддерживает динамическое форматирование строк. Синтаксис интерполяции заимствован из Python, т.е. функция interpolate поддерживает как позиционные, так и именованные интерполяции:

Не злоупотребляйте интерполяцией строк, помните: это всё JavaScript, и для проверки используются регулярные выражения. Интерполяция в JavaScript выполняется не так быстро, как на Python, так что используйте её только при реальной необходимости.

get_format ¶

Функция get_format предоставляет доступ к настройкам форматирования интернационализации:

Предоставляет доступ к следующим настройкам:

Важно использовать форматирование аналогичное форматированию значений в Python.

gettext_noop ¶

Полезно при написании кода, который будет использовать перевод в будущем.

pgettext ¶

Функция pgettext работает как и аналогичная функция Python ( pgettext() ), позволяя указать контекст для переводимых строк:

npgettext ¶

Функция npgettext работает как и аналогичная функция Python ( npgettext() ), позволяя указать контекст при переводе строк в множественном числе:

pluralidx ¶

В самом простом варианте возвращает false для 1 и true для остальных значений.

Однако, множественная форма не такая простая для всех языков. Если язык не поддерживает множественные формы, будет возвращено пустое значение.

Также, если правила множественного числа сложные, каталог будет содержать выражение для их определения. В этом случае будет возвращено true (множественное число) или false (не множественное).

The JSONCatalog view¶

In order to use another client-side library to handle translations, you may want to take advantage of the JSONCatalog view. It’s similar to JavaScriptCatalog but returns a JSON response.

See the documentation for JavaScriptCatalog to learn about possible values and use of the domain and packages attributes.

Формат ответа следующий:

Комментарий о производительности¶

Server-side caching will reduce CPU load. It’s easily implemented with the cache_page() decorator. To trigger cache invalidation when your translations change, provide a version-dependent key prefix, as shown in the example below, or map the view at a version-dependent URL:

Также вы можете заранее создавать javascript-каталог во время процесса выкладывания кода на сервер и использовать его как статичный файл. Такой подход используется в django-statici18n.

Интернационализация: в шаблонах URL¶

Django предоставляет два способа интернационализации шаблонов URL:

Using either one of these features requires that an active language be set for each request; in other words, you need to have django.middleware.locale.LocaleMiddleware in your MIDDLEWARE setting.

Языковой префикс в шаблонах URL¶

Setting prefix_default_language to False removes the prefix from the default language ( LANGUAGE_CODE ). This can be useful when adding translations to existing site so that the current URLs won’t change.

Example URL patterns:

i18n_patterns() is only allowed in a root URLconf. Using it within an included URLconf will throw an ImproperlyConfigured exception.

Удостоверьтесь, что у вас нет таких шаблонов URL, которые могут конфликтовать с автоматически добавленным префиксом.

Перевод шаблонов URL¶

URL patterns can also be marked translatable using the gettext_lazy() function. Example:

After you’ve created the translations, the reverse() function will return the URL in the active language. Example:

In most cases, it’s best to use translated URLs only within a language code prefixed block of patterns (using i18n_patterns() ), to avoid the possibility that a carelessly translated URL causes a collision with a non-translated URL pattern.

Генерация URL в шаблонах¶

Шаблонный тег language принимает в качестве аргумента код языка.

Локализация: как создать языковые файлы¶

После того, как текстовые ресурсы приложения были помечены для перевода, следует выполнить (или получить) сам перевод. Вот как это работает.

Файлы сообщений¶

Минимальной поддерживаемой версией утилит gettext является 0.15.

Для создания или обновления файла сообщений запустите эту команду:

… где de является названием локали для создаваемого файла сообщений. Например, это pt_BR для бразильского варианта португальского языка и de_AT для австрийского варианта немецкого языка или id для индонезийского.

Этот скрипт должен быть запущен из одного из двух мест:

Разделяйте множество расширений с помощью запятой и/или используйте опцию многократно:

Использование шаблонов Jinja2?

makemessages не понимает синтаксис шаблонов Jinja2. Чтобы получить строки для перевода из шаблонов Jinja2, используйте из Babel.

Пример файла настроек babel.cfg :

Не забудьте указать все расширения, которые вы используете! Иначе Babel не сможет определить теги из этих расширений и полностью проигнорирует шаблоны Jinja2, которые их содержат.

If you don’t have the gettext utilities installed, makemessages will create empty files. If that’s the case, either install the gettext utilities or copy the English message file ( locale/en/LC_MESSAGES/django.po ) if available and use it as a starting point, which is an empty translation file.

Работаете на Windows?

Длинные сообщения являются особым случаем. Так, первая строка сразу после msgstr (или msgid ) всегда пустая. Затем идёт длинный перевод, разбитый на несколько строк. Эти строки будут собраны в одну. Не забывайте вставлять завершающие пробелы, иначе итоговая строка будет собрана без них!

Укажите свою кодировку

Из-за особенностей внутренней работы утилит пакета gettext и нашего желания позволить использование не-ASCII символов в строках кода Django и ваших приложений, вы должны использовать UTF-8 в качестве кодировки ваших PO файлов (по умолчанию при их создании). Это означает, что все будут использовать одинаковую кодировку, что очень важно в момент, когда Django обрабатывает PO файлы.

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

Компиляция файлов с сообщениями¶

Вот и всё. Ваш перевод готов к использованию.

Работаете на Windows?

.po файлы: Кодировка и использование BOM

Troubleshooting: gettext() incorrectly detects python-format in strings with percent signs¶

To workaround this, you can escape percent signs by adding a second percent sign:

Or you can use no-python-format so that all percent signs are treated as literals:

Создание файлов сообщений из JavaScript кода¶

This would create or update the message file for JavaScript for German. After updating message files, run django-admin compilemessages the same way as you do with normal Django message files.

gettext на Windows¶

Настройка команды makemessages ¶

Если вам необходим больший контроль, вы также можете добавить новый аргумент в вашу реализацию команды makemessages :

Разное¶

Перенаправляющее представление set_language ¶

Активируйте это представление, добавив следующую строку в конфигурацию URL:

The view expects to be called via the POST method, with a language parameter set in request. If session support is enabled, the view saves the language choice in the user’s session. It also saves the language choice in a cookie that is named django_language by default. (The name can be changed through the LANGUAGE_COOKIE_NAME setting.)

Приведём пример HTML кода шаблона:

Явное указание активного языка¶

You would typically want to use both: django.utils.translation.activate() changes the language for this thread, and setting the cookie makes this preference persist in future requests.

In older versions, you could set the language in the current session.

Использование перевода вне представлений и шаблонов¶

Несмотря на то, что Django предоставляет богатый набор инструментов интернационализации представлений и шаблонов, она не ограничивает их использование в другом коде. Механизмы перевода Django могут быть использованы для перевода отдельных текстов на любой из языков, поддерживаемых Django (т.е. соответствующий каталог с переводами есть в наличии). Вы можете загрузить каталог переводов, активировать его и переводить текст на нужный язык, но не забудьте вернуться на оригинальный язык, так как активация каталога переводов выполняется на уровне потока и такое изменение будет влиять на код, работающий в том же потоке.

Кука для языка¶

Ряд настроек может быть использован для управления опциями куки языка:

Замечания по реализации¶

Особенности перевода Django¶

Как Django определяет языковую настройку¶

Once you’ve prepared your translations – or, if you want to use the translations that come with Django – you’ll need to activate translation for your app.

Django обладает очень гибкой моделью принятия решения о том, какой язык следует использовать: на уровне проекта, для отдельного пользователя или в обоих случаях.

For example, your MIDDLEWARE might look like this:

LocaleMiddleware пытается определить язык пользователя, используя следующий алгоритм:

Сначала, проверяется наличие префикса в запрошенном URL. Эта проверка выполняется только если вы используете функцию i18n_patterns в корневом URLconf. Обратитесь к Интернационализация: в шаблонах URL для получения подробностей по языковым префиксам и интернационализации шаблонов URL.

Если и с сессией не сложилось, то принимается за cookie.

This example restricts languages that are available for automatic selection to German and English (and any sublanguage, like de-ch or en-us ).

If you define a custom LANGUAGES setting, as explained in the previous bullet, you can mark the language names as translation strings – but use gettext_lazy() instead of gettext() to avoid a circular import.

Приведёт пример файла настроек:

Как Django находит переводы¶

The translations for literals included in JavaScript assets are looked up following a similar but not identical algorithm. See JavaScriptCatalog for more details.

This way, you can write applications that include their own translations, and you can override base translations in your project. Or, you can build a big project out of several apps and put all translations into one big common message file specific to the project you are composing. The choice is yours.

Все репозитории с файлами сообщений имеют одинаковую структуру:

Using a non-English base language¶

Django makes the general assumption that the original strings in a translatable project are written in English. You can choose another language, but you must be aware of certain limitations:

Источник

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *