Search code examples
pythondjangolocalizationdjango-i18n

i18n and l10n in Django with different views


I'm trying to localize my application for internationalization purposes, but I'm having a problem developing a URL for the views once a language is chosen.

I have these relevant entries in my settings.py

...

USE_I18N = True

USE_L10N = True

LOCALE_PATHS = (
    os.path.join(BASE_DIR, 'locale'),
)

from django.utils.translation import ugettext_lazy as _

LANGUAGES = (
    ('en', _('English')),
    ('es', _('Spanish')),
    ('zh', _('Chinese')),
)

...

And my urls.py looks like this...

# -*- coding: utf-8 -*-

from django.conf.urls import include, url, patterns
from django.contrib import admin
from django.conf import settings
from django.conf.urls.i18n import i18n_patterns


urlpatterns = patterns('', 
    url(r'^$', 'myApp.views.home', name='home'),
    url(r'^admin/', include(admin.site.urls)),
    url(r'^downloads/$', 'myApp.views.downloads'),
    # etc. etc.
)

urlpatterns += i18n_patterns('',
    url(r'^$', 'myApp.views.home', name='home'),
    url(r'^admin/', include(admin.site.urls)),
    url(r'^downloads/$', 'myApp.views.downloads'),
    # etc. etc.
)

So this "works" locally. I go to localhost:8080/es/ and see my Spanish page. However, when I click on my application's button to navigate to the Downloads page, I go to localhost:8080/downloads which is in English. If I type localhost:8080/es/downloads, I get an unfound URL error.

How can I make this more naturally localized and internationalized? If there's any information missing, please let me know. I'll add it.

I'm using Django 1.7.4.

Thanks, erip

EDIT

From home to downloads, I have some HTML that looks like this...

  <a class="navbar-brand" href="/"> {% trans "Home"%}</a>
  <a class="navbar-brand" href="/downloads/"> {% trans "Downloads"%}</a>

Solution

  • Have you added django.middleware.locale.LocaleMiddleware to your MIDDLEWARE_CLASSES (docs)?

    MIDDLEWARE_CLASSES = (       
        'django.contrib.sessions.middleware.SessionMiddleware',      
        'django.middleware.locale.LocaleMiddleware',    
        'django.middleware.common.CommonMiddleware', 
    )
    

    Also, you shouldn't define your patterns twice. All patterns you wish to be handled by I18N should only be defined in the i18n_patterns(...). So if they are identical, this block will be enough:

    # -*- coding: utf-8 -*-
    
    from django.conf.urls import include, url, patterns
    from django.contrib import admin
    from django.conf import settings
    from django.conf.urls.i18n import i18n_patterns
    
    urlpatterns = i18n_patterns('',
        url(r'^$', 'myApp.views.home', name='home'),
        url(r'^admin/', include(admin.site.urls)),
        url(r'^downloads/$', 'myApp.views.downloads'),
        # etc. etc.
    )
    

    Update: Building the URL in the template

    In the url pattern add a name attribute to the downloads pattern:

    urlpatterns = i18n_patterns('',
        # ...
        url(r'^downloads/$', 'myApp.views.downloads', name='downloads'),
        # ...
    )
    

    In the template, resolve the link with the url tag:

    <a class="navbar-brand" href="{% url 'home' %}">{% trans "Home"%}</a>
    <a class="navbar-brand" href="{% url 'downloads' %}">{% trans "Downloads"%}</a>
    

    This way Django builds the url respecting the current language.


    How to debug if resolving works correctly

    For debugging what Django currently resolves a URL to, you could try the following in the shell.

    $ ./manage.py shell
    
    >>> from django.core.urlresolvers import reverse
    >>> from django.utils.translation import activate
    >>> activate('en')
    >>> reverse('downloads')
    '/en/downloads'    
    >>> activate('es')
    >>> reverse('downloads')
    '/es/downloads/'