Login

Multilingual site based on domain - not accept header and django_session

Author:
hermansc
Posted:
January 7, 2012
Language:
Python
Version:
1.3
Tags:
internationalization middleware multilingual locale domain localeurl
Score:
2 (after 2 ratings)

On our site Fornebuklinikken - A cosmetic surgeon in Norway we also have a domain http://fornebuklinikken.com which should be using the 'en' language.

We didn't wan't to use the standard locale lib, and wrote our own middleware which lookups the correct language corresponding to the domain (.no or .com)

Any questions? Contact me on herman.schistad (at) gmail.com

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
# Settings.py

# If you set this to False, Django will make some optimizations so as not
# to load the internationalization machinery.
USE_I18N = True

gettext = lambda s: s
LANGUAGES = (
	('nb', gettext('Norwegian')),
	('en', gettext('English'))
)

LANGUAGES_BY_DOMAIN = {
	# These must match the codes given in LANGUAGES
	'no'  : 'nb',
	'com' : 'en',
}
 
DOMAIN_BY_LANGUAGE = {
	# The reverse of languages by domain, may be a better method for this.
	'nb'  : '.no',
	'en'  : '.com',
}

MIDDLEWARE_CLASSES = {
	(...)
	'app.middleware.locale.CustomLocaleMiddleware',
	#'django.middleware.locale.LocaleMiddleware',
	(...)
}

----------------------------------------------------------------------
# app.middleware.locale.py

from django.conf import settings
from django.http import HttpResponseRedirect

class CustomLocaleMiddleware(object):
   def validate_language(self, request):
      # On the form: www.fornebuklinikken.no
      host = request.META['HTTP_HOST']

      # Creates ['www', 'fornebuklinikken', 'no']. Gets 'no'
      domain = ''.join(host.split('.')[-1:])

      # Lookup which language code to use
      if domain not in settings.LANGUAGES_BY_DOMAIN:
		# We add www to the request (this is done in DNS with CNAME, but whatever..)	
        return HttpResponseRedirect('http://www.%s%s' % (host, request.path))
	  # Gets lang_code corresponding to the domain
      lang_code = settings.LANGUAGES_BY_DOMAIN[domain]

      # Set the language
      translation.activate(lang_code)
      request.LANGUAGE_CODE = lang_code

    def process_request(self, request):
      if request.META.has_key('HTTP_ACCEPT_LANGUAGE'):
		# Totally ignore the browser settings... 
        del request.META['HTTP_ACCEPT_LANGUAGE']

      if settings.DEBUG:
		# If debug is on we don't do redirects and we rather use the original
		# locale.py from django 1.3 which uses sessions.
        language = translation.get_language_from_request(request)
        translation.activate(language)
        request.LANGUAGE_CODE = translation.get_language()
      else:
        return self.validate_language(request)

    def process_response(self, request, response):
      response['Content-Language'] = translation.get_language()
      translation.deactivate()
      return response
---------------------------------------------------------------------------
# In some view (do the actual language changing)
def set_language(request):
    """ 
    Redirect to a given url while setting the chosen language in the URL

    Since this view changes how the user will see the rest of the site, it must
    only be accessed as a POST request. If called as a GET request, it will
    redirect to the page in the request (the 'next' parameter) without changing
    any state.
    """
    next = request.REQUEST.get('next', None)
    if not next:
        next = request.META.get('HTTP_REFERER', None)
    if not next:
        next = '/' 
    response = HttpResponseRedirect(next)
    if request.method == 'POST':
        lang_code = request.POST.get('language', None)
        if lang_code and check_for_language(lang_code):
            if settings.DEBUG:
              if hasattr(request, 'session'):
                request.session['django_language'] = lang_code
              else:
                response.set_cookie(settings.LANGUAGE_COOKIE_NAME, lang_code)
            else:
              # Return the URL without domain
              base_url = '.'.join(request.META['HTTP_HOST'].split('.')[:-1])

              # Get the domain from settings based on lang_code
              domain = settings.DOMAIN_BY_LANGUAGE[lang_code]
    
              # Return the base_url + domain + reffering URL (needs http:// in order to do the redirect)
              response = HttpResponseRedirect('http://' + base_url + domain + next)
    return response

More like this

  1. locale based on domain by zeeg 7 years, 9 months ago
  2. Localized URLs (www-en) by zeeg 8 years ago
  3. Read settings from local_settings.py by statico 5 years, 1 month ago
  4. Dynamic SITE_ID thread-safe by jhg 10 months, 3 weeks ago
  5. Ignore HTTP Accept-Language headers by fonso 7 years, 10 months ago

Comments

klemens (on July 13, 2012):

2 upvotes but still a NameError ("translation" is not defined)...

#

Please login first before commenting.