Search code examples
pythondjangointernationalizationdjango-i18n

Django i18n_patterns - How to prevent prefixing of non-active languages


In my django settings.py file, I have six active languages:

LANGUAGES = (
('de', gettext_noop('German')),
('en', gettext_noop('English')),
('es', gettext_noop('Spanish')),
('fr', gettext_noop('French')),
('nl', gettext_noop('Dutch')),
('pt', gettext_noop('Portuguese')),
)

These pages work great when using i18n patterns:

 http://exmaple.com/de/main
 http://exmaple.com/nl/main
 etc...

However, if you search my site in Google, you'll see multiple pages for language prefixes. Some for languages that I don't support. Some of which don't even exist:

http://examble.com/ch/main
http://exmaple.com/zz/main
etc..

I'm not sure why these pages are getting indexed. They aren't in my sitemap. However, Django does serve them as pages.

Question, what is the best way to modify i18n_patterns so that it only allows valid, active languages as defined in settings.py? I would like all other 2 char prefixes to 404.


Solution

  • The best solution(I know) is to use solid-i18n-urls.

    Install the package:

    pip install solid_i18n
    

    Modify settings a little bit:

    # Default language, that will be used for requests without language prefix
    LANGUAGE_CODE = 'en'
    
    # supported languages
    LANGUAGES = (
        ('en', 'English'),
        ('ru', 'Russian'),
    )
    
    # enable django translation
    USE_I18N = True
    
    #Add SolidLocaleMiddleware instead of LocaleMiddleware to MIDDLEWARE_CLASSES:
    MIDDLEWARE_CLASSES = (
       'django.contrib.sessions.middleware.SessionMiddleware',
       'solid_i18n.middleware.SolidLocaleMiddleware',
       'django.middleware.common.CommonMiddleware',
    )
    

    Use solid_i18n_patterns instead of i18n_patterns

    from django.conf.urls import patterns, include, url
    from solid_i18n.urls import solid_i18n_patterns
    
    urlpatterns = solid_i18n_patterns('',
        url(r'^main/$', 'about.view', name='about'),
    )
    

    Now, if you go to example.com/en/main it works fine as en is specified in your languages linst but if you go to example.com/ch/main it throws a 404 page not found error.