diff --git a/cms/envs/bok_choy.env.json b/cms/envs/bok_choy.env.json index b858d700775fe04c0044ef2564e6f88cc3f8bb59..eb613edafc04aa4403240220e9e1f00cdfad1bef 100644 --- a/cms/envs/bok_choy.env.json +++ b/cms/envs/bok_choy.env.json @@ -75,7 +75,7 @@ "PREVIEW_LMS_BASE": "preview.localhost:8003", "ENABLE_CONTENT_LIBRARIES": true, "ENABLE_SPECIAL_EXAMS": true, - "SHOW_LANGUAGE_SELECTOR": true, + "SHOW_HEADER_LANGUAGE_SELECTOR": true, "ENABLE_EXTENDED_COURSE_DETAILS": true, "CUSTOM_COURSES_EDX": true }, diff --git a/cms/envs/common.py b/cms/envs/common.py index e8579c8f3aad2f9d8c06dca42b9658097de2067f..cef002da59c8e2b130a37b57653dc1949fcbd53f 100644 --- a/cms/envs/common.py +++ b/cms/envs/common.py @@ -227,8 +227,8 @@ FEATURES = { 'ORGANIZATIONS_APP': False, - # Show Language selector - 'SHOW_LANGUAGE_SELECTOR': False, + # Show the language selector in the header + 'SHOW_HEADER_LANGUAGE_SELECTOR': False, # Set this to False to facilitate cleaning up invalid xml from your modulestore. 'ENABLE_XBLOCK_XML_VALIDATION': True, diff --git a/cms/templates/widgets/header.html b/cms/templates/widgets/header.html index 595e21793483e31054e7d51a41dec711199db006..7e4439f617edf15bf0bab60e0b7aba72f8d5bd74 100644 --- a/cms/templates/widgets/header.html +++ b/cms/templates/widgets/header.html @@ -4,6 +4,7 @@ from django.conf import settings from django.core.urlresolvers import reverse from django.utils.translation import ugettext as _ + from openedx.core.djangoapps.lang_pref.api import header_language_selector_is_enabled, released_languages %> <div class="wrapper-header wrapper" id="view-top"> <header class="primary" role="banner"> @@ -183,8 +184,8 @@ </div> <div class="wrapper wrapper-r"> - % if static.show_language_selector(): - <% languages = static.get_released_languages() %> + % if header_language_selector_is_enabled(): + <% languages = released_languages() %> % if len(languages) > 1: <nav class="user-language-selector" aria-label="${_('Language preference')}"> <form action="/i18n/setlang/" method="post" class="settings-language-form" id="language-settings-form"> diff --git a/common/djangoapps/pipeline_mako/templates/static_content.html b/common/djangoapps/pipeline_mako/templates/static_content.html index 69a45d9dcd9fcd1e317f9fc19428bbd60f643b23..1af6ee8a14008e0fc1fa6dc8ddda4c011eef1b43 100644 --- a/common/djangoapps/pipeline_mako/templates/static_content.html +++ b/common/djangoapps/pipeline_mako/templates/static_content.html @@ -18,7 +18,6 @@ from openedx.core.djangoapps.theming.helpers import ( is_request_in_themed_site, ) from certificates.api import get_asset_url_by_slug -from openedx.core.djangoapps.lang_pref.api import released_languages logger = logging.getLogger(__name__) %> @@ -194,11 +193,3 @@ else: <%def name="get_tech_support_email_address()"><% return get_value('email_from_address', settings.TECH_SUPPORT_EMAIL) %></%def> - -<%def name="show_language_selector()"><% - return get_value('SHOW_LANGUAGE_SELECTOR', settings.FEATURES.get('SHOW_LANGUAGE_SELECTOR', False)) -%></%def> - -<%def name="get_released_languages()"><% - return released_languages() -%></%def> diff --git a/lms/envs/bok_choy.env.json b/lms/envs/bok_choy.env.json index 924ed69f714f023113c3e0763fa007f7ce834cc6..2abdf5dc6836d4429576df27abda48c8d90dcf2c 100644 --- a/lms/envs/bok_choy.env.json +++ b/lms/envs/bok_choy.env.json @@ -88,7 +88,7 @@ "AUTOMATIC_VERIFY_STUDENT_IDENTITY_FOR_TESTING": true, "ENABLE_COURSE_DISCOVERY": true, "ENABLE_SPECIAL_EXAMS": true, - "SHOW_LANGUAGE_SELECTOR": true, + "SHOW_HEADER_LANGUAGE_SELECTOR": true, "CUSTOM_COURSES_EDX": true }, "FEEDBACK_SUBMISSION_EMAIL": "", diff --git a/lms/envs/common.py b/lms/envs/common.py index a67449c721a4f4a292fa8dad0890749964bade28..db159c9f8e567ef6a85a4c102fe51ba4d415422c 100644 --- a/lms/envs/common.py +++ b/lms/envs/common.py @@ -345,8 +345,11 @@ FEATURES = { # Enable LTI Provider feature. 'ENABLE_LTI_PROVIDER': False, - # Show Language selector. - 'SHOW_LANGUAGE_SELECTOR': False, + # Show the language selector in the header + 'SHOW_HEADER_LANGUAGE_SELECTOR': False, + + # Show the language selector in the footer + 'SHOW_FOOTER_LANGUAGE_SELECTOR': False, # Write new CSM history to the extended table. # This will eventually default to True and may be diff --git a/lms/envs/devstack_docker.py b/lms/envs/devstack_docker.py index e4c8731ec5af41757849e526b7c81bb4afcf8350..3973f22a1c71d9b5fa9b728ffdb827684e45068f 100644 --- a/lms/envs/devstack_docker.py +++ b/lms/envs/devstack_docker.py @@ -30,8 +30,8 @@ FEATURES.update({ 'ENABLE_COURSEWARE_SEARCH': False, 'ENABLE_COURSE_DISCOVERY': False, 'ENABLE_DASHBOARD_SEARCH': False, - 'SHOW_LANGUAGE_SELECTOR': True, 'ENABLE_DISCUSSION_SERVICE': False, + 'SHOW_HEADER_LANGUAGE_SELECTOR': True }) ENABLE_MKTG_SITE = os.environ.get('ENABLE_MARKETING_SITE', False) diff --git a/lms/templates/footer.html b/lms/templates/footer.html index 860d1d9d2a7f62367a8e95d6ba69d3114130d278..5b25ecb994c651d4cc3cc90bf1c9a58d355b6bc2 100644 --- a/lms/templates/footer.html +++ b/lms/templates/footer.html @@ -4,6 +4,7 @@ from django.core.urlresolvers import reverse from django.utils.translation import ugettext as _ from branding.api import get_footer + from openedx.core.djangoapps.lang_pref.api import footer_language_selector_is_enabled %> <% footer = get_footer(is_secure=is_secure) %> <%namespace name='static' file='static_content.html'/> @@ -28,8 +29,8 @@ </ol> </nav> - % if include_language_selector: - <%include file="widgets/footer-language-selector.html"/> + % if context.get('include_language_selector', footer_language_selector_is_enabled()): + <%include file="${static.get_template_path('widgets/footer-language-selector.html')}"/> % endif <div class="wrapper-logo"> diff --git a/lms/templates/navigation.html b/lms/templates/navigation.html index 5ca116a8c7a551fea8e4c3a00a0da2ccb9424290..90d6156c00a8881dbfb7517ee9b1fc9f10277e49 100644 --- a/lms/templates/navigation.html +++ b/lms/templates/navigation.html @@ -14,6 +14,7 @@ from branding import api as branding_api # app that handles site status messages from status.status import get_site_status_msg from openedx.features.enterprise_support.api import get_enterprise_customer_logo_url +from openedx.core.djangoapps.lang_pref.api import header_language_selector_is_enabled, released_languages %> ## Provide a hook for themes to inject branding on top. @@ -176,8 +177,8 @@ site_status_msg = get_site_status_msg(course_id) </%block> </ol> % endif - % if static.show_language_selector(): - <% languages = static.get_released_languages() %> + % if header_language_selector_is_enabled(): + <% languages = released_languages() %> % if len(languages) > 1: <ol class="user"> <li class="primary"> diff --git a/lms/templates/widgets/footer-language-selector.html b/lms/templates/widgets/footer-language-selector.html index 4a8b44e552264243f8430462f0b1746363f4165b..d18450ddbdf98336e957d3e4a7b2f025666271cc 100644 --- a/lms/templates/widgets/footer-language-selector.html +++ b/lms/templates/widgets/footer-language-selector.html @@ -15,6 +15,7 @@ if not settings.LANGUAGE_COOKIE: raise ValueError('settings.LANGUAGE_COOKIE is required to use footer-language-selector.') %> +<%namespace name='static' file='../static_content.html'/> <div class="footer-language-selector"> <label for="footer-language-select"> @@ -53,8 +54,10 @@ setLanguageCookie: function(value, callback) { var cookie = '${settings.LANGUAGE_COOKIE | n, js_escaped_string}=' + value + ';path=/'; - % if settings.SESSION_COOKIE_DOMAIN: - cookie += ';domain=${settings.SESSION_COOKIE_DOMAIN | n, js_escaped_string}'; + + <% session_cookie_domain = static.get_value('SESSION_COOKIE_DOMAIN', settings.SESSION_COOKIE_DOMAIN) %> + % if session_cookie_domain: + cookie += ';domain=${session_cookie_domain | n, js_escaped_string}'; % endif % if COOKIE_DURATION: cookie += ';max-age=${COOKIE_DURATION | n, js_escaped_string}'; diff --git a/openedx/core/djangoapps/lang_pref/api.py b/openedx/core/djangoapps/lang_pref/api.py index 499033c43edc0d78d3550498e46eed655562500b..9ff43120657131cc078cafc6014874b10fbfd769 100644 --- a/openedx/core/djangoapps/lang_pref/api.py +++ b/openedx/core/djangoapps/lang_pref/api.py @@ -5,7 +5,9 @@ from collections import namedtuple from django.conf import settings from django.utils.translation import ugettext as _ + from openedx.core.djangoapps.dark_lang.models import DarkLangConfig +from openedx.core.djangoapps.site_configuration.helpers import get_value # Named tuples can be referenced using object-like variable @@ -14,6 +16,21 @@ from openedx.core.djangoapps.dark_lang.models import DarkLangConfig Language = namedtuple('Language', 'code name') +def header_language_selector_is_enabled(): + """Return true if the header language selector has been enabled via settings or site-specific configuration.""" + setting = get_value('SHOW_HEADER_LANGUAGE_SELECTOR', settings.FEATURES.get('SHOW_HEADER_LANGUAGE_SELECTOR', False)) + + # The SHOW_LANGUAGE_SELECTOR setting is deprecated, but might still be in use on some installations. + deprecated_setting = get_value('SHOW_LANGUAGE_SELECTOR', settings.FEATURES.get('SHOW_LANGUAGE_SELECTOR', False)) + + return setting or deprecated_setting + + +def footer_language_selector_is_enabled(): + """Return true if the footer language selector has been enabled via settings or site-specific configuration.""" + return get_value('SHOW_FOOTER_LANGUAGE_SELECTOR', settings.FEATURES.get('SHOW_FOOTER_LANGUAGE_SELECTOR', False)) + + def released_languages(): """Retrieve the list of released languages. diff --git a/openedx/core/djangoapps/lang_pref/tests/test_api.py b/openedx/core/djangoapps/lang_pref/tests/test_api.py index cc5826e2b5849f7bbf1b9f638464133b2d3fc081..ca8e9b9a8cf75ad3e2181eb81610bed7585bff45 100644 --- a/openedx/core/djangoapps/lang_pref/tests/test_api.py +++ b/openedx/core/djangoapps/lang_pref/tests/test_api.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- """ Tests for the language API. """ +from mock import patch from django.test import TestCase from django.test.utils import override_settings from django.utils import translation @@ -8,8 +9,8 @@ from django.contrib.auth.models import User import ddt from openedx.core.djangoapps.dark_lang.models import DarkLangConfig - from openedx.core.djangoapps.lang_pref import api as language_api +from openedx.core.djangoapps.site_configuration.tests.test_util import with_site_configuration_context EN = language_api.Language('en', 'English') ES_419 = language_api.Language('es-419', u'Español (Latinoamérica)') @@ -20,6 +21,45 @@ class LanguageApiTest(TestCase): """ Tests of the language APIs. """ + + @ddt.data( + # Should return the base config value + ({'SHOW_HEADER_LANGUAGE_SELECTOR': True}, {}, True), + + # Should return the site config value + ({'SHOW_HEADER_LANGUAGE_SELECTOR': False}, {'SHOW_HEADER_LANGUAGE_SELECTOR': True}, True), + ({'SHOW_HEADER_LANGUAGE_SELECTOR': True}, {'SHOW_HEADER_LANGUAGE_SELECTOR': False}, False), + + # SHOW_LANGUAGE_SELECTOR should supercede SHOW_HEADER_LANGUAGE_SELECTOR when true + ({'SHOW_HEADER_LANGUAGE_SELECTOR': False, 'SHOW_LANGUAGE_SELECTOR': True}, {}, True), + ({'SHOW_HEADER_LANGUAGE_SELECTOR': False}, {'SHOW_LANGUAGE_SELECTOR': True}, True) + ) + @ddt.unpack + def test_header_language_selector_is_enabled(self, base_config, site_config, expected): + """ + Verify that the header language selector config is correct. + """ + with patch.dict('django.conf.settings.FEATURES', base_config): + with with_site_configuration_context(configuration=site_config): + self.assertEqual(language_api.header_language_selector_is_enabled(), expected) + + @ddt.data( + # Should return the base config value + ({'SHOW_FOOTER_LANGUAGE_SELECTOR': True}, {}, True), + + # Should return the site config value + ({'SHOW_FOOTER_LANGUAGE_SELECTOR': False}, {'SHOW_FOOTER_LANGUAGE_SELECTOR': True}, True), + ({'SHOW_FOOTER_LANGUAGE_SELECTOR': True}, {'SHOW_FOOTER_LANGUAGE_SELECTOR': False}, False) + ) + @ddt.unpack + def test_footer_language_selector_is_enabled(self, base_config, site_config, expected): + """ + Verify that the footer language selector config is correct. + """ + with patch.dict('django.conf.settings.FEATURES', base_config): + with with_site_configuration_context(configuration=site_config): + self.assertEqual(language_api.footer_language_selector_is_enabled(), expected) + @ddt.data(*[ ('en', [], [], []), ('en', [EN], [], [EN]), diff --git a/themes/edx.org/lms/templates/footer.html b/themes/edx.org/lms/templates/footer.html index a991e193375b0e2bebfe2f18ffacd09d68ef69d1..12751fbb31a44c622bb4b20f2b1588909df20cad 100644 --- a/themes/edx.org/lms/templates/footer.html +++ b/themes/edx.org/lms/templates/footer.html @@ -4,6 +4,7 @@ from django.utils.translation import ugettext as _ from branding.api import get_footer + from openedx.core.djangoapps.lang_pref.api import footer_language_selector_is_enabled %> <% footer = get_footer(is_secure=is_secure) %> <%namespace name='static' file='static_content.html'/> @@ -45,8 +46,8 @@ </ul> </nav> - % if include_language_selector: - <%include file="widgets/footer-language-selector.html"/> + % if context.get('include_language_selector', footer_language_selector_is_enabled()): + <%include file="${static.get_template_path('widgets/footer-language-selector.html')}"/> % endif <p class="copyright">${_( diff --git a/themes/red-theme/lms/templates/footer.html b/themes/red-theme/lms/templates/footer.html index 1046b37254ea6079d858f06ac9e7d4032cd2022c..cb48e10c32c1fe7aede7402f15fb5dc31992da52 100755 --- a/themes/red-theme/lms/templates/footer.html +++ b/themes/red-theme/lms/templates/footer.html @@ -3,6 +3,7 @@ <%! from django.core.urlresolvers import reverse from django.utils.translation import ugettext as _ +from openedx.core.djangoapps.lang_pref.api import footer_language_selector_is_enabled %> <div class="wrapper wrapper-footer"> @@ -43,8 +44,8 @@ from django.utils.translation import ugettext as _ </ol> </nav> - % if include_language_selector: - <%include file='widgets/footer-language-selector.html'/> + % if context.get('include_language_selector', footer_language_selector_is_enabled()): + <%include file="${static.get_template_path('widgets/footer-language-selector.html')}"/> % endif <div class="wrapper-logo"> diff --git a/themes/stanford-style/lms/templates/footer.html b/themes/stanford-style/lms/templates/footer.html index af22699718168e248e6ad7d67b80a41595358916..15faea08121b4f1b58f80c6e202f40bf8efd34e9 100644 --- a/themes/stanford-style/lms/templates/footer.html +++ b/themes/stanford-style/lms/templates/footer.html @@ -1,11 +1,11 @@ ## mako <%! + from datetime import date from django.core.urlresolvers import reverse from django.utils.translation import ugettext as _ + from openedx.core.djangoapps.lang_pref.api import footer_language_selector_is_enabled %> -<%! - from datetime import date -%> +<%namespace name='static' file='static_content.html'/> <!-- footer overrides for stanford theme go here --> <div class="wrapper-footer"> <footer> @@ -22,8 +22,8 @@ </ol> </nav> - % if include_language_selector: - <%include file='widgets/footer-language-selector.html'/> + % if context.get('include_language_selector', footer_language_selector_is_enabled()): + <%include file="${static.get_template_path('widgets/footer-language-selector.html')}"/> % endif </div>