Multilingual site based on domain - not accept header and django_session

  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 6 years, 10 months ago
  2. Localized URLs (www-en) by zeeg 7 years, 1 month ago
  3. Read settings from local_settings.py by statico 4 years, 3 months ago
  4. Ignore HTTP Accept-Language headers by fonso 6 years, 11 months ago
  5. Dynamic SITE_ID thread-safe by jhg 2 days, 8 hours ago

Comments

klemens (on July 13, 2012):

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

#

(Forgotten your password?)