[web] fix language negotiation
authorJulien Cristau <julien.cristau@logilab.fr>
Fri, 04 Apr 2014 17:32:12 +0200
changeset 9601 e5a80bd337e8
parent 9585 3f5b59527d31
child 9602 9fb2f15d5e85
[web] fix language negotiation Regression caused by commit 6fd0ac6506cb "[web-request] handle default language earlier". We would handle language negotiation at request init time, but overwrite the selected language with the site default when calling set_cnx.
web/request.py
web/test/unittest_web.py
--- a/web/request.py	Mon Mar 24 18:14:22 2014 +0100
+++ b/web/request.py	Fri Apr 04 17:32:12 2014 +0200
@@ -122,19 +122,9 @@
         self.setup_params(form)
         #: received body
         self.content = StringIO()
-        # use header to set default language (may ne overwriten by user one later)
-        if vreg.config.get('language-negociation', False):
-            # http negociated language
-            accepted_languages = self.header_accept_language()
-        else:
-            accepted_languages = ()
-        for lang in accepted_languages:
-            if lang in self.translations:
-                self.set_language(lang)
-                break
-        else:
-            self.set_default_language(vreg)
-        # 3. default language
+        # set up language based on request headers or site default (we don't
+        # have a user yet, and might not get one)
+        self.set_user_language(None)
         #: dictionary that may be used to store request data that has to be
         #: shared among various components used to publish the request (views,
         #: controller, application...)
@@ -986,6 +976,25 @@
     def html_content_type(self):
         return 'text/html'
 
+    def set_user_language(self, user):
+        vreg = self.vreg
+        if user is not None:
+            try:
+                # 1. user-specified language
+                lang = vreg.typed_value('ui.language', user.properties['ui.language'])
+                self.set_language(lang)
+                return
+            except KeyError:
+                pass
+        if vreg.config.get('language-negociation', False):
+            # 2. http accept-language
+            for lang in self.header_accept_language():
+                if lang in self.translations:
+                    self.set_language(lang)
+                    return
+        # 3. site's default language
+        self.set_default_language(vreg)
+
 
 class DBAPICubicWebRequestBase(_CubicWebRequestBase, DBAPIRequest):
 
@@ -995,11 +1004,7 @@
         """
         super(CubicWebRequestBase, self).set_session(session)
         # set request language
-        user_lang = self.user.properties.get('ui.language')
-        if user_lang is not None:
-            lang = self.vreg.typed_value('ui.language', user_lang)
-            self.set_language(lang)
-
+        self.set_user_language(session.user)
 
 
 def _cnx_func(name):
@@ -1030,12 +1035,7 @@
         self.cnx = cnx
         self.session = cnx._session
         self._set_user(cnx.user)
-        # set user language
-        user_lang = self.user.properties.get('ui.language')
-        if user_lang is not None:
-            lang = self.vreg.typed_value('ui.language', user_lang)
-            self.set_language(lang)
-
+        self.set_user_language(cnx.user)
 
     def execute(self, *args, **kwargs):
         rset = self.cnx.execute(*args, **kwargs)
--- a/web/test/unittest_web.py	Mon Mar 24 18:14:22 2014 +0100
+++ b/web/test/unittest_web.py	Fri Apr 04 17:32:12 2014 +0200
@@ -92,6 +92,16 @@
         self.assertEqual(webreq.status_code, 200)
         self.assertDictEqual(expect, loads(webreq.content))
 
+class LanguageTC(CubicWebServerTC):
+
+    def test_language_neg(self):
+        headers = {'Accept-Language': 'fr'}
+        webreq = self.web_request(headers=headers)
+        self.assertIn('lang="fr"', webreq.read())
+        headers = {'Accept-Language': 'en'}
+        webreq = self.web_request(headers=headers)
+        self.assertIn('lang="en"', webreq.read())
+
 
 if __name__ == '__main__':
     unittest_main()