4

In some Django applications I encountered URL patterns with gettext such as:

from django.utils.translation import ugettext as _

urlpatterns = patterns('',
    ...
    url(r'^%s$' % _('about/'), about, name='about'),
    ...
)

At first, it seemed to be a good idea to have internationalized URLs in a uniform way with the rest of the project but I have doubts.

AFAIK, URL patterns are loaded at application start-up. So I suspect they will be build according to the language preferences of the user who makes the first request to the application. This may get even more unpredictable when threads are in the play too.

This approach may be reasonable for cases where an installation will be in single language but there may be other installations in other languages, like forum applications.

Do you think this is a problem or just my imagination? Can this approach be used for multilingual sites? Can ugettext_lazy avoid this problem?

onurmatik
  • 5,105
  • 7
  • 42
  • 67

4 Answers4

3

Have a read of the django docs: https://docs.djangoproject.com/en/dev/topics/i18n/translation/#url-internationalization

Basically, you can use ugettext_lazy to translate your patterns and it will work provided a language is set for every request. To ensure this, you should use LocaleMiddleware. https://docs.djangoproject.com/en/dev/ref/middleware/#django.middleware.locale.LocaleMiddleware

fabspro
  • 1,639
  • 19
  • 29
1

This approach will not work. Your translation takes place when the application loads. This means your URL patterns will be of a single language, the default language of your app.

Translations only work when the context they are called from have access to a user's language preference.

For your URLs to be multilingual, you have to use some run-time url definitions. These would be loaded based on the user's current language.

Dimitry
  • 6,545
  • 2
  • 20
  • 21
  • This approach actually works in for example [OSQA](http://osqa.net), but their assumption is I guess the whole project would be in a single language. When the site language is something different than English, the URLs are in that other language, of course provided they have translations. Models do not have access to the context of the request but with `gettext_lazy` field names, help_text attributes, etc. are translated fine. But for URLs, this won't do I suppose. – onurmatik Mar 06 '11 at 23:44
  • You're right about the models. But when you do '/' + gettext_lazy('Label'), the result of the gettext_lazy() method is evaluated right away. – Dimitry Mar 06 '11 at 23:51
  • The question is, are you translating when the apps code is first evaluated or when a thread is spawned? In the former case, you're probably translating the app. In the latter case, you're probably translating in run time for the user's chosen language. – Dimitry Mar 06 '11 at 23:55
0

You are right about ugettext_lazy is evaluated right away when concatenating strings.

Sth like that works: url(_(r'^contact/'), include('contact.urls')),

But you have to translate patterns what could be erroneus.

okrutny
  • 1,070
  • 10
  • 16
  • I am looking for something to check that it will not be erroneus. Is it possible to process every patterns ? – Natim Apr 17 '13 at 08:19
0

You could do it like this:

import six
from django.utils.functional import lazy


def lazy_url_pattern(pattern):
    return lazy(pattern, six.text_type)()

And then in your dispatcher:

urlpatterns = [
    url(lazy_url_pattern(lambda: r'^{n}/$'.format(n=ugettext_lazy(u'foo'))), MyView.as_view(), name='...'),

But it's still error-prone though....

Paul

Paul Bormans
  • 1,292
  • 16
  • 22