Déterminer en Python la langue du visiteur avec le header Accept-Language
Ayant l'intention de lancer deux versions de ce blog, une version française (vous êtes dessus) et une anglaise (qui arrive bientôt), je me suis penché sur les différents moyens de detecter la langue de l'utilisateur. J'ai d'abord regardé du côté du JavaScript, mais je me suis vite rabattu sur la variable Accept-Language
qui est passée par le navigateur en header de chaque requête envoyé au serveur.
Voici l'allure du header envoyé par les navigateurs : Accept-Language: fr, fr-fr;q=0.8, en-us;q=0.7,en;q=0.5
. Je vous invite à lire la RFC2616 (spécifications HTTP1.1), et plus particulièrement la section 14 sur la définition des champs Header afin de comprendre par quel moyen nous pouvons prioriser la liste reçue. J'ai donc développé une petite fonction qui me retourne une liste comprenant, par ordre de préférence, la liste des langues acceptées par le navigateur. Etant donné que ce blog tourne sur Google AppEngine, c'est en Python, voici le code :
def parse_accept_header(accept_header):
"""Determines the user's locale from Accept-Language header value passed
as a parameter.
Note: It should work fine for getting Accept, Accept-Charset or
Accept-Encoding headers but you will need to take care of special values
such as */*, /*, and "level=X" to prioritizing your results. See
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.4 for
more details on Accept-Languages and
http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.1 to
check all available Accept headers.
"""
accepts = []
for line in accept_header.replace(' ','').split(','):
values = line.split(';q=')
if len(values) > 1:
try:
prio = float(values[1])
except (ValueError, TypeError):
prio = 0.0
else:
prio = 1.0
accepts.append((values[0], prio))
accepts.sort(key=lambda (l, s): s, reverse=True)
accept_headers = [l[0] for l in accepts]
return accept_headers