воскресенье, 5 февраля 2012 г.

Интернационализация URL в Django

Интернационализация URL, или, проще говоря, возможность в зависимости от языка подсовывать разные URL, появится в Django 1.4. Эта возможность вряд ли как-то повлияет на пользовательский опыт работы с сайтом, но и создавалась она не для людей. Её цель — поисковая оптимизация. Посмотрим, как мы можем получить такую функциональность в Django 1.3.

Проблема

Сейчас в Django есть LocaleMiddleware, которая определяет текущий язык на основании данных пользовательской сессии, cookies и HTTP заголовков (именно в таком порядке). Используя LocaleMiddleware ничего не стоит выдавать по одному и тому же адресу контент на разных языках в зависимости от языка пользователя. Это удобно для пользователя, но это также может стать причиной неполной индексации сайта. Действительно, ведь поисковый робот проиндексирует ваш сайт только на одном языке.

Решение: django_i18nurls

У нас есть только один выход — сделать URL зависимым от языка. Этот способ рекомендуется и самими поисковиками. Yandex даже советует выносить версии сайта на различных языках на отдельный поддомен (см. пункт 7 в их рекомендациях).

Самый простой способ осуществить задуманное — вставлять код языка в начало каждого URL:

  • http://example.com/ru/
  • http://example.com/en/smth

Собственно этим и занимается django_i18nurls.

Установка

Установка пакета

Установка предельно проста.

pip install -e git+https://github.com/brocaar/django-i18nurls@7d26b48474d8ce44102697cadf9676ce607d7564#egg=django_i18nurls-0.7dev-py2.7-dev

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

Подключение в Django-проекте

Добавляем i18nurls в settings.INSTALLED_APPS, при этом выполнять syncdb не нужно. Затем добавляем i18nurls.middleware.LocaleMiddleware в settings.MIDDLEWARE_CLASSES, обязательно после SessionMiddleware, потому что LocaleMiddleware использует данные из сессий; и до CommonMiddleware, так как CommonMiddleware нужен активированный язык для распознавания URL. Проще говоря, у вас должно получиться так:

MIDDLEWARE_CLASSES = (
    'django.contrib.sessions.middleware.SessionMiddleware',
    'i18nurls.middleware.LocaleMiddleware',
    'django.middleware.common.CommonMiddleware',
    # остальные middleware

Использование

Для интернационализации URL предлагается два варианта:

  1. Использовать вместо стандартной django.conf.urls.defaults.patterns функцию i18nurls.i18n.i18n_patterns. В этом случае ко всем указанным адресам автоматически будет подставляться в начало код языка.
  2. Использовать ugettext_lazy, то есть работать с URL как с переводом обычного текста.

Применение второму способу я пока не нашёл, а вот первым пользуюсь с удовольствием:

from django.conf.urls.defaults import patterns, include, url
from i18nurls.i18n import i18n_patterns

urlpatterns = patterns('',
    (r'^admin/doc/', include('django.contrib.admindocs.urls')),
    (r'^admin/', include(admin.site.urls)),
)

urlpatterns += i18n_patterns('',
    (r'^myapp/', include('myapp.urls')),
)

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

Советую почитать:

  1. Документацию по интернационализации URL в Django 1.4. Так как код один и тот же, то она верна и для django_i18nurls.
  2. Readme на GitHub.
  3. Исходный код django_i18nurls, поможет разобраться в том, как Django работает с URL. Также в коде присутствует интересный способ monkeypatch, который предложил сам Guido van Rossum.

2 комментария:

  1. gettext = lambda s: s
    LANGUAGES = (
    ('ru', gettext('Russian')),
    ('en', gettext('English')),
    )

    Столкнулся с проблемой, активные URL-ы только с приставкой для одно языка, например ru
    ru/myview/1
    ru/mytest
    Когда меняю на en в URL-e то вываливается ошибка что нет такого.

    ОтветитьУдалить
  2. Шаблоны нормативных документов по декларированию https://www.innov.ru/news-it/2009/09/11/3/
    Примеры уставных документов по сертификации https://bankir.ru/novosti/20060725/rashodi-na-iso-9001-2000-ymenshaut-pribil-1124693/
    Шаблоны уставных документов по сертификации https://bankir.ru/novosti/20070801/nalogoviki-kopyat-dolgi-nalogoplatelschikov-1086991/
    Примеры нормативных документов по сертификации https://metrologu.ru/profile/105013-curba/

    ОтветитьУдалить