From 6d50ff7b618c97d6bc6966024214ca1b9707f519 Mon Sep 17 00:00:00 2001
From: "Dave St.Germain" <dstgermain@edx.org>
Date: Mon, 27 Jan 2014 16:25:13 -0500
Subject: [PATCH] Set the html language to the browser's specified language

---
 cms/envs/common.py                            |  4 ++-
 cms/templates/base.html                       | 10 ++++----
 lms/djangoapps/courseware/tests/test_i18n.py  | 25 +++++++++++++++++++
 lms/envs/common.py                            |  5 ++--
 lms/envs/test.py                              |  1 +
 lms/static/maintenance/index.html             |  2 +-
 lms/templates/course_groups/debug.html        |  2 +-
 lms/templates/extauth_failure.html            |  2 +-
 lms/templates/main.html                       | 10 ++++----
 lms/templates/main_django.html                |  4 +--
 lms/templates/mktg_iframe.html                |  8 +++---
 .../registration/password_reset_complete.html |  2 +-
 .../registration/password_reset_confirm.html  |  2 +-
 lms/templates/wiki/preview_inline.html        |  2 +-
 14 files changed, 54 insertions(+), 25 deletions(-)
 create mode 100644 lms/djangoapps/courseware/tests/test_i18n.py

diff --git a/cms/envs/common.py b/cms/envs/common.py
index c96b1719591..4dc75f87e99 100644
--- a/cms/envs/common.py
+++ b/cms/envs/common.py
@@ -113,6 +113,7 @@ TEMPLATE_CONTEXT_PROCESSORS = (
     'django.core.context_processors.request',
     'django.core.context_processors.static',
     'django.contrib.messages.context_processors.messages',
+    'django.core.context_processors.i18n',
     'django.contrib.auth.context_processors.auth',  # this is required for admin
     'django.core.context_processors.csrf',
     'dealer.contrib.django.staff.context_processor',  # access git revision
@@ -165,12 +166,13 @@ MIDDLEWARE_CLASSES = (
 
     'django.contrib.messages.middleware.MessageMiddleware',
     'track.middleware.TrackMiddleware',
-    'edxmako.middleware.MakoMiddleware',
 
     # Detects user-requested locale from 'accept-language' header in http request
     'django.middleware.locale.LocaleMiddleware',
 
     'django.middleware.transaction.TransactionMiddleware',
+    # needs to run after locale middleware (or anything that modifies the request context)
+    'edxmako.middleware.MakoMiddleware',
 
     # catches any uncaught RateLimitExceptions and returns a 403 instead of a 500
     'ratelimitbackend.middleware.RateLimitMiddleware',
diff --git a/cms/templates/base.html b/cms/templates/base.html
index 6f87c4c5a97..625777fe23d 100644
--- a/cms/templates/base.html
+++ b/cms/templates/base.html
@@ -3,10 +3,10 @@
 <%namespace name='static' file='static_content.html'/>
 
 <!doctype html>
-<!--[if IE 7]><html class="ie7 lte9 lte8 lte7"><![endif]-->
-<!--[if IE 8]><html class="ie8 lte9 lte8"><![endif]-->
-<!--[if IE 9]><html class="ie9 lte9"><![endif]-->
-<!--[if gt IE 9]><!--><html><!--<![endif]-->
+<!--[if IE 7]><html class="ie7 lte9 lte8 lte7" lang="${LANGUAGE_CODE}"><![endif]-->
+<!--[if IE 8]><html class="ie8 lte9 lte8" lang="${LANGUAGE_CODE}"><![endif]-->
+<!--[if IE 9]><html class="ie9 lte9" lang="${LANGUAGE_CODE}"><![endif]-->
+<!--[if gt IE 9]><!--><html lang="${LANGUAGE_CODE}"><!--<![endif]-->
   <head>
     <meta charset="utf-8">
     <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
@@ -32,7 +32,7 @@
     <%block name="header_extras"></%block>
   </head>
 
-  <body class="<%block name='bodyclass'></%block> hide-wip">
+  <body class="<%block name='bodyclass'></%block> hide-wip lang_${LANGUAGE_CODE}">
     <a class="nav-skip" href="#content">${_("Skip to this view's content")}</a>
 
     <script type="text/javascript">
diff --git a/lms/djangoapps/courseware/tests/test_i18n.py b/lms/djangoapps/courseware/tests/test_i18n.py
new file mode 100644
index 00000000000..22331c43994
--- /dev/null
+++ b/lms/djangoapps/courseware/tests/test_i18n.py
@@ -0,0 +1,25 @@
+"""
+Tests i18n in courseware
+"""
+from django.test import TestCase
+from django.test.utils import override_settings
+from courseware.tests.modulestore_config import TEST_DATA_MIXED_MODULESTORE
+import re
+
+
+@override_settings(MODULESTORE=TEST_DATA_MIXED_MODULESTORE, LANGUAGES=(('eo', 'Esperanto'),))
+class I18nTestCase(TestCase):
+    """
+    Tests for i18n
+    """
+    def test_default_is_en(self):
+        response = self.client.get('/')
+        self.assertIn('<html lang="en">', response.content)
+        self.assertEqual(response['Content-Language'], 'en')
+        self.assertTrue(re.search('<body.*class=".*lang_en">', response.content))
+        
+    def test_esperanto(self):
+        response = self.client.get('/', HTTP_ACCEPT_LANGUAGE='eo')
+        self.assertIn('<html lang="eo">', response.content)
+        self.assertEqual(response['Content-Language'], 'eo')
+        self.assertTrue(re.search('<body.*class=".*lang_eo">', response.content))
diff --git a/lms/envs/common.py b/lms/envs/common.py
index 32464e04e3a..9d9ef255913 100644
--- a/lms/envs/common.py
+++ b/lms/envs/common.py
@@ -277,7 +277,7 @@ TEMPLATE_CONTEXT_PROCESSORS = (
     'django.core.context_processors.request',
     'django.core.context_processors.static',
     'django.contrib.messages.context_processors.messages',
-    #'django.core.context_processors.i18n',
+    'django.core.context_processors.i18n',
     'django.contrib.auth.context_processors.auth',  # this is required for admin
     'django.core.context_processors.csrf',
 
@@ -635,7 +635,6 @@ MIDDLEWARE_CLASSES = (
 
     'django.contrib.messages.middleware.MessageMiddleware',
     'track.middleware.TrackMiddleware',
-    'edxmako.middleware.MakoMiddleware',
     'django.middleware.csrf.CsrfViewMiddleware',
 
     'course_wiki.course_nav.Middleware',
@@ -651,6 +650,8 @@ MIDDLEWARE_CLASSES = (
 
     # catches any uncaught RateLimitExceptions and returns a 403 instead of a 500
     'ratelimitbackend.middleware.RateLimitMiddleware',
+    # needs to run after locale middleware (or anything that modifies the request context)
+    'edxmako.middleware.MakoMiddleware',
 
     # For A/B testing
     'waffle.middleware.WaffleMiddleware',
diff --git a/lms/envs/test.py b/lms/envs/test.py
index a3b490c0b41..48782bf46e8 100644
--- a/lms/envs/test.py
+++ b/lms/envs/test.py
@@ -73,6 +73,7 @@ COMMON_TEST_DATA_ROOT = COMMON_ROOT / "test" / "data"
 # Where the content data is checked out.  This may not exist on jenkins.
 GITHUB_REPO_ROOT = ENV_ROOT / "data"
 
+USE_I18N = True
 
 XQUEUE_INTERFACE = {
     "url": "http://sandbox-xqueue.edx.org",
diff --git a/lms/static/maintenance/index.html b/lms/static/maintenance/index.html
index eeaa7b7b0b2..574ad1dbae7 100644
--- a/lms/static/maintenance/index.html
+++ b/lms/static/maintenance/index.html
@@ -1,5 +1,5 @@
 <!doctype html>
-<html>
+<html lang="en">
 <head>
 	<meta charset="utf-8">
 	<link href='http://fonts.googleapis.com/css?family=Open+Sans:300' rel='stylesheet' type='text/css'>
diff --git a/lms/templates/course_groups/debug.html b/lms/templates/course_groups/debug.html
index 7554557f81d..13f27e87fac 100644
--- a/lms/templates/course_groups/debug.html
+++ b/lms/templates/course_groups/debug.html
@@ -1,6 +1,6 @@
 <!DOCTYPE html>
 <%! from django.utils.translation import ugettext as _ %>
-<html>
+<html lang="${LANGUAGE_CODE}">
 <head>
   ## "edX" should not be translated
   <%block name="title"><title>edX</title></%block>
diff --git a/lms/templates/extauth_failure.html b/lms/templates/extauth_failure.html
index adc680a7de0..9c92e39433f 100644
--- a/lms/templates/extauth_failure.html
+++ b/lms/templates/extauth_failure.html
@@ -2,7 +2,7 @@
 
 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
   "http://www.w3.org/TR/html4/strict.dtd">
-<html>
+<html lang="${LANGUAGE_CODE}">
 <head>
     <title>${_("External Authentication failed")}</title>
 </head>
diff --git a/lms/templates/main.html b/lms/templates/main.html
index f7aaafc797e..b2d106cb49b 100644
--- a/lms/templates/main.html
+++ b/lms/templates/main.html
@@ -22,10 +22,10 @@
 </%def>
 
 <!DOCTYPE html>
-<!--[if IE 7]><html class="ie ie7 lte9 lte8 lte7" lang="en-us"><![endif]-->
-<!--[if IE 8]><html class="ie ie8 lte9 lte8" lang="en-us"><![endif]-->
-<!--[if IE 9]><html class="ie ie9 lte9" lang="en-us"><![endif]-->
-<!--[if gt IE 9]><!--><html lang="en-us"><!--<![endif]-->
+<!--[if IE 7]><html class="ie ie7 lte9 lte8 lte7" lang="${LANGUAGE_CODE}"><![endif]-->
+<!--[if IE 8]><html class="ie ie8 lte9 lte8" lang="${LANGUAGE_CODE}"><![endif]-->
+<!--[if IE 9]><html class="ie ie9 lte9" lang="${LANGUAGE_CODE}"><![endif]-->
+<!--[if gt IE 9]><!--><html lang="${LANGUAGE_CODE}"><!--<![endif]-->
 <head>
   <%block name="title">
     % if stanford_theme_enabled():
@@ -102,7 +102,7 @@
 
 </head>
 
-<body class="<%block name='bodyclass'/>">
+<body class="<%block name='bodyclass'/> lang_${LANGUAGE_CODE}">
   <a class="nav-skip" href="#content">${_("Skip to this view's content")}</a>
 
   <%include file="mathjax_accessible.html" />
diff --git a/lms/templates/main_django.html b/lms/templates/main_django.html
index 9190ddab928..f33a51f8bc7 100644
--- a/lms/templates/main_django.html
+++ b/lms/templates/main_django.html
@@ -1,6 +1,6 @@
 <!DOCTYPE html>
 {% load compressed %}{% load sekizai_tags i18n %}{% load url from future %}{% load staticfiles %}
-<html>
+<html lang="{{LANGUAGE_CODE}}">
 <head>
   {# "edX" should *not* be translated #}
   {% block title %}<title>edX</title>{% endblock %}
@@ -28,7 +28,7 @@
   <meta name="path_prefix" content="{{EDX_ROOT_URL}}">
 </head>
 
-<body class="{% block bodyclass %}{% endblock %}">
+<body class="{% block bodyclass %}{% endblock %} lang_{{LANGUAGE_CODE}}">
   <a class="nav-skip" href="#content">{% trans "Skip to this view's content" %}</a>
   {% include "navigation.html" %}
   <section class="content-wrapper" id="content">
diff --git a/lms/templates/mktg_iframe.html b/lms/templates/mktg_iframe.html
index ea1b00f1ad6..e6c0f55acd4 100644
--- a/lms/templates/mktg_iframe.html
+++ b/lms/templates/mktg_iframe.html
@@ -1,9 +1,9 @@
 <%namespace name='static' file='static_content.html'/>
 <!DOCTYPE html>
-<!--[if IE 7]><html class="ie ie7 lte9 lte8 lte7 view-iframe"><![endif]-->
-<!--[if IE 8]><html class="ie ie8 lte9 lte8 view-iframe"><![endif]-->
-<!--[if IE 9]><html class="ie ie9 lte9 view-iframe"><![endif]-->
-<!--[if gt IE 9]><!--><html class="view-iframe"><!--<![endif]-->
+<!--[if IE 7]><html class="ie ie7 lte9 lte8 lte7 view-iframe" lang="${LANGUAGE_CODE}"><![endif]-->
+<!--[if IE 8]><html class="ie ie8 lte9 lte8 view-iframe" lang="${LANGUAGE_CODE}"><![endif]-->
+<!--[if IE 9]><html class="ie ie9 lte9 view-iframe" lang="${LANGUAGE_CODE}"><![endif]-->
+<!--[if gt IE 9]><!--><html class="view-iframe" lang="${LANGUAGE_CODE}"><!--<![endif]-->
 <head>
   <%block name="title"></%block>
 
diff --git a/lms/templates/registration/password_reset_complete.html b/lms/templates/registration/password_reset_complete.html
index 1d592b9df93..c1c53d34b54 100644
--- a/lms/templates/registration/password_reset_complete.html
+++ b/lms/templates/registration/password_reset_complete.html
@@ -2,7 +2,7 @@
 {% load compressed %}
 {% load staticfiles %}
 <!DOCTYPE html>
-<html>
+<html lang="{{LANGUAGE_CODE}}">
 <head>
 
   <title>{% trans "Your Password Reset is Complete" %}</title>
diff --git a/lms/templates/registration/password_reset_confirm.html b/lms/templates/registration/password_reset_confirm.html
index 4ee2defe84a..63db56041a2 100644
--- a/lms/templates/registration/password_reset_confirm.html
+++ b/lms/templates/registration/password_reset_confirm.html
@@ -2,7 +2,7 @@
 {% load compressed %}
 {% load staticfiles %}
 <!DOCTYPE html>
-<html>
+<html lang="{{LANGUAGE_CODE}}">
 <head>
 
 <title>
diff --git a/lms/templates/wiki/preview_inline.html b/lms/templates/wiki/preview_inline.html
index 4f8aafeeff8..98e2a05ccd9 100644
--- a/lms/templates/wiki/preview_inline.html
+++ b/lms/templates/wiki/preview_inline.html
@@ -1,6 +1,6 @@
 <!DOCTYPE html>
 {% load wiki_tags i18n %}{% load compressed %}
-<html>
+<html lang="{{LANGUAGE_CODE}}">
 <head>
   {% compressed_css 'course' %}  
   {% compressed_js 'main_vendor' %}
-- 
GitLab