Login

Multilingual site based on domain - not accept header and django_session

Author:
hermansc
Posted:
January 7, 2012
Language:
Python
Version:
1.3
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. Template tag - list punctuation for a list of items by shapiromatron 11 months, 2 weeks ago
  2. JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 11 months, 3 weeks ago
  3. Serializer factory with Django Rest Framework by julio 1 year, 6 months ago
  4. Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 7 months ago
  5. Help text hyperlinks by sa2812 1 year, 8 months ago

Comments

klemens (on July 13, 2012):

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

#

Please login first before commenting.