Интернационализация Django - ЧАСТЬ 2
{% endblocktrans %}
Для образования множественного числа определите обе формы (единственную и множественную) в теге {% plural %}, который должен находиться между {% blocktrans %} и {% endblocktrans %}. Например:
{% blocktrans count list|length as counter %} There is only one {{ name }} object. {% plural %}
There are {{ counter }} {{ name }} objects. {% endblocktrans %}
В реализации перевода всех блочных и строчных фрагментов применяются функции ugettext/ungettext. Каждый объект RequestContext имеет доступ к трем переменным, касающимся перевода:
• LANGUAGES - список кортежей, в каждом из которых первый элемент - код языка, а второй - название языка (переведенное на язык текущей активной локали).
• LANGUAGE_CODE - код предпочтительного для пользователя языка в виде строки, например: en-us (см. следующий раздел «Как Django определяет языковые предпочтения»).
• LANGUAGE_BIDI - направление чтения в текущей локали. True означает, что язык читается справа налево (например, иврит и арабский), a False - слева направо (английский, французский, немецкий и т. д.).
Если расширение RequestContext не используется, то получить эти значения можно с помощью следующих тегов:
{% get_current_language as LANGUAGE_CODE %} {% get_available_languages as LANGUAGES %} {% get_current_language_bidi as LANGUAGE_BIDI %}
Эти теги требуют, чтобы была указана директива {% load i18n %}.
Подключать механизм перевода можно также внутри любого блочного тега, который принимает литералы строк. В таких случаях для определения переводимой строки можно воспользоваться синтаксисом _():
{% some_special_tag _("Page not found") value|yesno:_("yes,no") %}
В данном случае и тег, и фильтр увидят уже переведенную строку, поэтому нет нужды сообщать им о необходимости перевода.
Примечание ———————————————————————-
В этом примере механизму перевода будет передана строка "yes.no", а не строки "yes" и "по" по отдельности. Переведенная строка должна содержать запятую, иначе код разбора фильтра не будет знать, как выделить аргументы. Например, на русский язык строку "yes.no" можно было бы перевести как "да,нет" с сохранением запятой.
Объекты отложенного перевода
Функции ugettext_lazy() и ungettext_lazy() очень часто применяются для перевода строк в моделях и служебных функциях. При работе с такими объектами в других местах кода необходимо следить за тем, чтобы случайно не преобразовать их в строки, поскольку перевод должен быть произведен как можно позже (когда активна нужная локаль). Чтобы помочь в решении этой задачи, существуют две вспомогательные функции.
Конкатенация строк: string_concat()
Функция объединения строк из имеющейся стандартной библиотеки Python (".join([…])) не годится для списков, содержащих объекты с отложенным переводом. Вместо нее можно использовать функцию django. utils.translation.string_concat(), создающую объект отложенного вызова, который объединяет свои аргументы и преобразует их в строки, только когда результат вычисляется в строковом контексте. Например:
from django.utils.translation import string_concat
tt . . .
name =’ ugettext_lazy(u’John Lennon’)
instrument = ugettext_lazy(u’guitar’)
result = string_concat([name, ‘: ‘, instrument])
В данном случае объекты отложенного перевода, сохраненные в переменной result, будут преобразованы в строки, только когда result встретится внутри строки (обычно на этапе отображения шаблона).
Декоратор allowJazy()
В Django имеется множество служебных функций (особенно в пакете django.utils), которые принимают строку в первом аргументе и что- то с ней делают. Эти функции используются в шаблонных фильтрах, а также непосредственно в коде.
Если вы сами будете писать подобные функции, то столкнетесь со следующей проблемой: что делать, когда первый аргумент - объект отложенного перевода. Преобразовывать его в строку немедленно нежелательно, так как функция может использоваться вне представления (когда в текущем потоке выполнения установлена неправильная локаль).
В подобных случаях можно использовать декоратор django.utils. functional.allow_lazy(). Он модифицирует функцию таким образом, что если при ее вызове в первом аргументе передается объект отложенного перевода, то выполнение откладывается до того момента, когда его будет необходимо преобразовать в строку. Например:
from django.utils.functional import allow_lazy
def fancy_utility_function(s, …): tt Какие-то операции со строкой ‘ s’
tt …
fancy_utility_function = allow_lazy(fancy_utility_function, Unicode)
Помимо декорируемой функции, allow_lazy() принимает дополнительные аргументы (*args), определяющие, какие типы может возвращать исходная функция. Обычно достаточно включить в этот список Unicode и гарантировать, что исходная функция будет возвращать только строки Unicode.
Наличие такого декоратора означает, что можно написать функцию в предположении, что на вход поступает обычная строка, а поддержку объектов с отложенным переводом добавить в самом конце.
Как создавать файлы переводов
После того как будут отмечены строки для перевода, нужно перевести их (или получить перевод от третьего лица). Ниже мы опишем, как это делается.
Ограничения на локаль
Django не поддерживает локализацию приложения для локали, на которую не был переведен сам фреймворк. В таких случаях файл перевода игнорируется. В противном случае пользователь неизбежно увидел бы мешанину переведенных строк (из вашего приложения) и английских строк (из самого Django).
Если вы хотите поддержать свое приложение для локали, еще не вошедшей в Django, то придется перевести хотя бы минимально необходимую часть ядра Django.
Файлы сообщений
Первым делом необходимо создать файл сообщений для нового языка. Это обычный текстовый файл, содержащий все переводимые строки и их перевод на один язык. Файлы сообщений имеют расширение ро.
В состав Django входит инструмент, django-admin.py makemessages, который автоматизирует создание и сопровождение таких файлов. Чтобы создать или обновить файл сообщений, выполните следующую команду (здесь de - код языка, для которого создается файл сообщений):
django-admin.py makemessages -1 de
Код языка задается в формате локали. Например, pt_BR - бразильский диалект португальского языка, a de_AT - австрийский диалект немецкого.
Сценарий следует запускать в одном из трех мест:
• Корневой каталог проекта Django.
• Корневой каталог приложения Django.
• Корневой каталог Django (не тот, что был извлечен из Subversion, а тот, на который указывает ссылка, включенная в SPYTHONPATH). Это относится только к случаю, когда вы переводите сам фреймворк Django.
Этот сценарий выполнит обход всего дерева каталогов проекта или приложения и извлечет строки, отмеченные для перевода. Затем он создаст (или обновит) файл сообщений в каталоге locale/LANG/LC_MESSAGES. Для примера выше файл будет называться locale/de/LC_MESSAGES/django.po.
По умолчанию django-admin.py makemessages просматривает все файлы с расширением .html. Чтобы изменить это соглашение, укажите расширения после флага -extension или -е:
django-admin.py makemessages -1 de -е txt
Если потребуется указать несколько расширений, их можно перечислить через запятую или повторив флаг -extension (или -е) несколько раз:
django-admin.py makemessages -1 de -е html,txt -e xml
При создании каталогов переводов для JavaScript (см. ниже) следует использовать специальный флаг djangojs, а не -е js.
Gettext не установлен?
Если пакет gettext не установлен, то сценарий django-admin.py makemessages создаст пустые файлы.
В таком случае либо установите gettext, либо скопируйте английский файл сообщений (locale/en/LC_MESSAGES/django.po), если таковой имеется, и используйте его в качестве отправной точки. Это просто пустой файл сообщений.
Работаете в Windows?
Если вы работаете на платформе Windows и хотите установить утилиту GNU gettext, чтобы обеспечить нормальную работу сценария django-admin makemessages, то обратитесь к разделу «gettext для Windows» ниже.
Формат ро-файлов достаточно прост. В каждом ро-файле присутствует небольшой раздел метаданных, где указывается, например, информация о способе связи с переводчиком, а основная часть - это список сообщений. Каждое сообщение - это пара, состоящая из переводимой строки и ее перевода на выбранный язык.
Например, если приложение Django содержит переводимую строку
"Welcome to my site.":
_("Welcome to my site.")
то django-admin.py makemessages создаст ро-файл, в котором будет такое сообщение:
tt: path/to/python/module, ру:23 msgid "Welcome to my site." msgstr ""
Поясним:
• msgid - это переводимая строка, взятая из текста оригинала. Ее изменять не следует.
• msgstr - место, где должен быть перевод. Изначально там ничего нет, а переводчик должен ввести текст. Не забывайте заключать перевод в кавычки.
• В качестве дополнительного удобства в состав каждого сообщения включен комментарий (строка, начинающаяся со знака #), в котором указаны имя файла и номер строки, где встречается данная переводимая строка.
Длинные сообщения - это особый случай, когда строка, следующая сразу за msgstr (или msgid), должна быть пустой. Собственно текст размещается в нескольких следующих строках, по одной строке текста в каждой строчке файла. В конечном итоге эти строки будут конкатенированы. Не забывайте ставить в конце строк пробелы, иначе после конкатенации образуется сплошной текст!
Чтобы заново просмотреть исходный код и шаблоны после модификации и обновить файлы сообщений для всех языков, выполните команду:
django-admin.ру makemessages -а
Компиляция файлов сообщений
После создания (и после каждого изменения) файла сообщений его необходимо откомпилировать, преобразовав в эффективный формат, который понимает gettext. Для этого служит утилита django-admin.ру compilemessages.
Она перебирает все имеющиеся ро-файлы и создает из них mo-файлы - двоичные файлы, оптимизированные для gettext. Команду django-admin. ру compilemessages следует запускать из того же каталога, что и django- admin.ру makemessages:
django-admin.ру compilemessages
Вот и все. Перевод готов.
Как Django определяет языковые предпочтения
После подготовки собственных переводов (или если вы просто хотите использовать переводы, входящие в комплект поставки Django) необходимо активировать перевод приложения.
Фреймворк Django имеет очень гибкую внутреннюю модель определения подходящего языка: для всего фреймворка в целом, для отдельного пользователя или то и другое вместе.
Чтобы определить языковые настройки для фреймворка в целом, следует установить значение параметра LANGUAGE_CODE. По умолчанию Django будет выполнять перевод на указанный язык, если не окажется более подходящего перевода.
Если вы всего лишь хотите, чтобы Django разговаривал на вашем родном языке и для этого языка имеется перевод, то, кроме установки LANGUAGE_CODE, больше ничего делать не нужно.
Если же требуется, чтобы каждый пользователь мог определить предпочтительный для себя язык, то понадобится дополнительный процессор LocaleMiddleware. Он выбирает язык в зависимости от данных, пришедших в запросе.
Чтобы воспользоваться процессором LocaleMiddleware, добавьте строку ‘django.middleware.locale.LocaleMiddleware’ в параметр MIDDLEWARE_CLASSES. Так как порядок следования процессоров важен, придерживайтесь следующих рекомендаций:
• Этот процессор должен быть как можно ближе к началу списка.
• Он должен располагаться после SessionMiddleware, так как для его работы необходимы данные сеанса.
• Если используется процессор CacheMiddleware, то LocaleMiddleware должен располагаться после него.
Например, параметр MIDDLEWARE_CLASSES мог бы выглядеть так:
MIDDLEWARE_CLASSES = (
‘django.contrib.sessions.middleware.SessionMiddleware’, ‘django.middleware.locale.LocaleMiddleware’, ‘django.middleware.common.CommonMiddleware’,
)
Подробнее о дополнительных процессорах см. в главе 17.
Процессор LocaleMiddleware пытается определить языковые предпочтения пользователя, применяя следующий алгоритм:
1. Сначала он отыскивает ключ django_language в сеансе текущего пользователя.
2. Если такого ключа нет, производится попытка отыскать cookie.
3. Если cookie не найден, анализируется HTTP-заголовок Accept- Language. Этот заголовок посылается броузером, чтобы сообщить серверу о предпочитаемых языках в порядке их следования. Django пробует каждый из перечисленных в заголовке языков, пока не найдет тот, для которого есть перевод.
4. Если подходящий язык не найден, используется значение параметра LANGUAGE_CODE.
Отметим следующие моменты:
• На каждом из этих шагов ожидается, что язык будет определен в виде стандартной строки. Например, бразильский диалект португальского языка определяется строкой pt-br.
• Если имеется перевод на основной язык, а на диалект отсутствует, то Django будет использовать основной язык. Например, если пользователь указал язык de-at (австрийский диалект немецкого), но имеется только перевод на язык de, то будет использован de.
• Допускаются только языки, перечисленные в параметре LANGUAGES. Если вы хотите ограничить выбор языка некоторым подмножеством языков (потому что приложение переведено не на все языки), то оставьте в списке LANGUAGES только разрешенные языки. Например:
LANGUAGES = (
(‘de’, _(‘German’)), (‘en’, _(‘English’)),
)
В этом примере разрешено выбирать только английский и немецкий языки (и их диалекты, например, de-ch или en-us).
• Если вы задали LANGUAGES, как описано в предыдущем пункте, то будет правильно отмечать названия языков как переводимые строки, но при этом следует пользоваться функцией-заглушкой ugettextO, а не функцией из пакета django.utils.translation. Никогда не следует импортировать пакет django.utils.translation из файла параметров, поскольку он сам зависит от параметров, и импортирование этого пакета создаст циклическую зависимость.
Чтобы решить эту проблему, следует использовать функцию-заглушку ugettext(), как это сделано в следующем примере файла параметров:
ugettext = lambda s: s
LANGUAGES = (
(‘de’, ugettext(‘German’)), (‘en’, ugettext(‘English’)),
)
При этом сценарий django-admin.ру makemessages все равно найдет и извлечет эти строки в файл перевода, но на этапе выполнения они переводиться не будут. Не забудьте обернуть названия языков настоящей функцией ugettext() всюду, где во время выполнения используется параметр LANGUAGES.
• Процессор LocaleMiddleware может выбрать только те языки, на которые переведено ядро Django. Если вы хотите перевести свое приложение на еще не поддерживаемый язык, то нужно будет перевести на него хотя бы минимальное подмножество строк ядра Django. Например, в Django используются технические сообщения для перевода форматов времени и даты, поэтому их обязательно нужно перевести, чтобы система работала правильно.
Для начала достаточно просто скопировать ро-файл для английского языка и перевести хотя бы технические сообщения (и, может быть, сообщения о результатах контроля данных).
Распознать технические сообщения несложно - они набраны заглавными буквами. Переводить их, как другие сообщения, не нужно; требуется лишь ввести правильный местный вариант для предложенного английского значения. Например, для строки DATETIME_ FORMAT (или DATE_FORMAT, или TIME_FORMAT) это будет строка формата, принятая в вашем родном языке. Формат определяется так же, как в шаблонном теге now.
После того как процессор LocaleMiddleware определит язык, он сохранит его в атрибуте request.LANGUAGE_CODE объекта HttpRequest. Вы можете обращаться к этому атрибуту в своих представлениях. Например:
def hello_world(request):
if request.LANGUAGE_CODE == ‘de-at’:
return HttpResponse("You prefer to read Austrian German.") else:
return HttpResponse("You prefer to read another language.")
Обратите внимание, что статический код языка (который не был обработан дополнительным процессором) можно получить из атрибута settings.LANGUAGE_CODE, тогда как динамический - из атрибута request. LANGUAGE_CODE.
Применение механизма перевода в собственных проектах
При поиске переводов Django применяет следующий алгоритм:
1. Сначала просматривается подкаталог locale в каталоге приложения, которому принадлежит вызванное представление. Если там присутствует перевод на выбранный язык, то используется он.
2. Далее просматривается подкаталог locale в каталоге проекта. Если перевод найден там, используется он.
3. Наконец, просматривается основной каталог переводов django/conf/ locale.
Таким образом, вы можете разрабатывать приложения, у которых будет собственный перевод, а также переопределять базовые переводы для своего проекта. Или можете составить один большой проект из нескольких приложений и поместить все переводы в один файл сообщений для проекта в целом. Выбор за вами.
Структура всех репозиториев файлов сообщений одинакова:
• $APPPATH/locale/<language>/LC_MESSAGES/django.(po|mo)
• $PROJECTPATH/locale/<language>/LC_MESSAGES/django.(po|no)
• Поиск всех файлов <language>/LC_MESSAGES/django.(po|mo) производится во всех каталогах, перечисленных в параметре LOCALE_PATHS, в порядке их следования в списке
• $PYTHONPATH/django/conf/locale/<language>/LC_MESSAGES/django.(po|no)
Для создания файлов сообщений используется та же утилита django- admin.py makemessages, что и для файлов сообщений самого Django. От вас требуется только запустить ее из нужного места - из каталога, где находится подкаталог conf/locale (в случае дерева исходных текстов) или locale/ (в случае сообщений приложения или проекта). А для создания то-файлов, с которыми работает gettext, запустите ту же утилиту django-admin.py compilemessages, о которой упоминалось выше.
Можно также выполнить команду django-admin.py compilemessages -settings=path.to.settings, которая откомпилирует ро-файлы, находящиеся во всех каталогах, перечисленных в параметре LOCALE_PATHS.
Поиск файлов сообщений приложения организован несколько сложнее, для этого требуется дополнительный процессор LocaleMiddleware. Если вы не хотите его использовать, то будут обрабатываться только файлы сообщений самого Django и проекта.
Наконец, вы должны заранее продумать структуру файлов с переводом. Если вы предполагаете передавать свои приложения другим пользователям и использовать их в других проектах, то имеет смысл создать перевод на уровне приложения. Но одновременное использование переводов на уровне приложения и на уровне проекта может приводить к неприятным проблемам при работе утилиты makemessages: она обходит все подкаталоги текущего каталога, поэтому может поместить в файлы сообщений проекта те сообщения, которые уже имеются в файлах сообщений приложения.
Простейший выход из этой ситуации - разместить приложения, не являющиеся частью проекта (и следовательно, сопровождаемые собственными переводами), вне дерева проекта. В таком случае при запуске django-admin.py makemessages из каталога проекта будут переведены только строки, явно связанные с проектом, а строки, распространяемые независимо от него, останутся непереведенными.
Представление set Janguage
В качестве дополнительного удобства в состав Django включено представление django.views.i18n.set_language, которое принимает языковую настройку пользователя и выполняет переадресацию на предыдущую страницу.
Для активации этого представления добавьте в конфигурацию URL такую строку:
(г’~i18n/’, include(‘django.conf.urls.i18n’ )),
Примечание —————————————————————————-
В этом примере представление будет доступно по адресу /i18n/setlang/.
Ожидается, что это представление будет вызываться методом POST и в запросе будет присутствовать параметр language. Если включена поддержка сеансов, то представление сохранит выбранный язык в сеансе пользователя. В противном случае выбранный язык по умолчанию будет сохраняться в cookie с именем django_language. (Имя можно изменить, определив параметр LANGUAGE_COOKIE_NAME.)
После того как язык будет определен, Django произведет переадресацию пользователя, руководствуясь следующим алгоритмом:
• Django проверит наличие параметра next в POST-запросе.
• Если такого параметра не существует или он пуст, то Django проверит наличие URL в заголовке Referer.
• Если этот заголовок отсутствует (например, его формирование подавлено в броузере), то пользователь будет переадресован в корень сайта^).
Ниже приводится пример HTML-разметки в шаблоне:
<form action="/i18n/setlang/" method="post">
cinput name="next" type="hidden" value="/next/page/" />
<select name="language">
{% for lang in LANGUAGES %}
coption value="{{ lang.0 }}">{{ lang.1 }}</option> {% endfor %} </select>
<input type=»submit» value=»Go» /> </form>
Переводы и JavaScript
Добавление переводов в JavaScript-сценарии порождает некоторые проблемы:
• Программный код на языке JavaScript не обладает доступом к реализации gettext.
• Программный код на языке JavaScript не обладает доступом к ро- и mo-файлам; они должны быть предоставлены сервером.
• Каталоги переводов для JavaScript должны иметь как можно меньший размер.
Django предлагает интегрированное решение этих проблем: он передает переводы в JavaScript таким способом, что внутри сценария JavaScript можно использовать gettext и все остальное.
Представление javascript_catalog
Основой решения является представление javascript_catalog; оно отправляет библиотеку JavaScript-кода, которая содержит функции, имитирующие интерфейс gettext, а также массив переводимых строк. Эти строки извлекаются из приложения, проекта или ядра Django в зависимости от того, что задано в словаре info_dict или в URL.
Интерфейс с этой библиотекой устроен так:
js_info_dict = {
‘packages’: (‘your.арр.package’,),
}
urlpatterns = patternsC’,
(r’~jsi18n/$’, ‘django.views.i18n.javascript_catalog’, js_info_dict),
)
Все строки в массиве packages должны быть записаны с соблюдением синтаксиса путей к пакетам в Python (через точку, точно так же строки записываются в параметре INSTALLED_APPS) и должны ссылаться на пакеты, которые содержат каталог locale. Если указано несколько пакетов, то все каталоги объединяются в один. Это полезно, когда в JavaScript- сценарии используются строки из разных приложений.
Представление можно сделать динамическим, поместив пакеты в образец URL:
urlpatterns = patternsC’,
(г’ ~jsi18n/(?P<packages>\S+)/$’, ‘django.views.i18n.javascript_catalog’),
)
В этом случае пакеты определяются в виде списка имен пакетов, разделенных в URL знаком +. Это особенно полезно, когда на страницах используется код из разных приложений, эти страницы часто изменяются, а сводить все в один большой файл вам не хочется. В качестве меры безопасности элементом списка может быть только django.conf или путь к пакету, присутствующему в параметре INSTALLED_APPS.
Использование каталога переводов в JavaScript
Чтобы воспользоваться каталогом, достаточно загрузить динамически сгенерированный сценарий:
<script type="text/javascript" src="/path/to/jsi18n/"x/script>
Именно так административный интерфейс получает каталог переводов с сервера. После того как каталог будет загружен, JavaScript-код сможет обращаться к нему с помощью стандартного интерфейса gettext:
document.write(gettext(‘this is to be translated’));
Имеется также функция ngettext:
var object_cnl = 1 // или 0, или 2, или 3, … s = ngettextC literal for the singular case’,
‘literal for the plural case’, objc-ct_cnt);
И даже функция строковой интерполяции:
function interpolate(fmt, obj, named);
Синтаксис интерполяции заимствован у Python, поэтому функция interpolate поддерживает как позиционные, так и именованные аргументы:
• Позиционная интерполяция: obj содержит JavaScript-объект Array, элементы которого используются для замещения шаблонных символов в порядке их следования. Например:
fmts = ngettext(‘There is %s object Remaining: %s’,
‘There are %s objects. Remaining: %s’, 11); s = interpolate(fmts, [11, 20]); // s - строка ‘There are 11 objects. Remaining: 20’
• Именованная интерполяция: этот режим устанавливается, когда необязательный параметр named равен true. В этом случае obj содержит объект JavaScript или ассоциативный массив. Например:
d - {
count: 10 total: 50
};
fmts = ngettext(‘Total: %(total)s, there is %(count)s object’, ‘there are %(count)s of a total of %(total)s objects’, d.count); s = interpolate(fmts, d, true);
Однако не следует злоупотреблять строковой интерполяцией; это все- таки JavaScript, а подстановка фактических значений выполняется с помощью регулярных выражений. Они не такие быстрые, как строковая интерполяция в Python, так что приберегите эту технику для случаев, когда она действительно необходима (например, в сочетании с ngettext для правильного образования множественного числа).
Создание каталогов переводов для JavaScript
Каталоги переводов создаются и обновляются точно так же, как все остальные каталоги переводов в Django: с помощью утилиты django- admin. ру makemessages. Единственная разница заключается в том, что нужно указать флаг -d djangojs:
django-admin.ру makemessages -d djangojs -1 de
В результате этой команды будет создан каталог переводов на немецкий язык для использования в JavaScript. Обновив каталоги переводов, запустите команду django-admin.ру compilemessages точно так же, как для обычных каталогов переводов в Django.
Замечания для пользователей, знакомых с gettext
Если вы знакомы с gettext, то, вероятно, обратили внимание на следующие особенности переводов в Django:
• Домен строк определен как django или djangojs. Домен необходим, чтобы различать программы, которые хранят данные в общей библиотеке файлов сообщений (обычно /usr/share/locale/). Домен django применяется для переводимых строк в коде на Python и в шаблонах, а строки, принадлежащие этому домену, загружаются в глобальный каталог переводов. Домен djangojs используется только для каталогов переводов JavaScript, поэтому старайтесь, чтобы их размер был минимален.
• В Django xgettext не используется напрямую. Для удобства применяются обертки вокруг xgettext и msgfmt, написанные на Python.
gettext для Windows
Это необходимо только тем, кто хочет извлечь идентификаторы сообщений или откомпилировать файлы сообщений (ро-файлы). Собственно перевод сводится к редактированию существующих ро-файлов, но если вы захотите создать собственные файлы сообщений, протестировать или откомпилировать измененный файл сообщений, то вам понадобится набор утилит gettext.
1. Загрузите следующие ZIP-файлы со страницы http://sourceforge.net/ projects/gettext:
• gettext-runtime-X.bin.woe32.zip
• gettext-tools-X.bin.woe32.zip
• libiconv-X.bin.woe32.zip
2. Распакуйте все три файла в один каталог (C:\Program Files\gettext- utils).
3. Измените системную переменную окружения PATH:
a. Панель управления -> Система -» Дополнительно -» Переменные среды.
b. В списке Системные переменные выберите переменную Path и затем щелкните на кнопке Изменить.
c. Добавьте в конец поля Значение переменной строку ;C:\Prog ran Files\ gettext-utils\bin.
Загрузить двоичный код gettext можно и из других мест, лишь бы команда xgettext -version работала правильно. Известно, что некоторые двоичные дистрибутивы версии 0.14.4 не поддерживают эту команду. Не пытайтесь использовать утилиты перевода Django в сочетании с пакетом gettext, если после ввода команды xgettext -version в окне команд Windows появляется окно с сообщением «Приложение xgettext. ехе допустило ошибку и будет закрыто».
Источник: Головатый А., Каплан-Мосс Дж. Django. Подробное руководство, 2-е издание. - Пер. с англ. - СПб.: Символ- Плюс, 2010. - 560 е., ил.
Похожие посты:
- Вывод текста с отступом (0)
- Изменение фонового цвета строки при наведении на нее указателя мыши (0)
- Введение в Django (0)
- Шаблон проектирования MVC (0)
- Второе представление: динамическое содержимое (0)
- Справочник по API доступа к базе данных Django - ЧАСТЬ 3 (0)
- Справочник по обобщенным представлениям Django (0)