Commit cd0bb4c7 by Diana Huang

Add ability to generate static i18n files.

parent dce3d9ca
**/vendor **/vendor
node_modules node_modules
cms/static/js/i18n/**/*.js
lms/static/js/i18n/**/*.js
...@@ -60,6 +60,8 @@ from lms.envs.common import ( ...@@ -60,6 +60,8 @@ from lms.envs.common import (
# Django REST framework configuration # Django REST framework configuration
REST_FRAMEWORK, REST_FRAMEWORK,
STATICI18N_OUTPUT_DIR
) )
from path import Path as path from path import Path as path
from warnings import simplefilter from warnings import simplefilter
...@@ -465,6 +467,8 @@ LANGUAGE_DICT = dict(LANGUAGES) ...@@ -465,6 +467,8 @@ LANGUAGE_DICT = dict(LANGUAGES)
USE_I18N = True USE_I18N = True
USE_L10N = True USE_L10N = True
STATICI18N_ROOT = PROJECT_ROOT / "static"
# Localization strings (e.g. django.po) are under this directory # Localization strings (e.g. django.po) are under this directory
LOCALE_PATHS = (REPO_ROOT + '/conf/locale',) # edx-platform/conf/locale/ LOCALE_PATHS = (REPO_ROOT + '/conf/locale',) # edx-platform/conf/locale/
...@@ -845,6 +849,9 @@ INSTALLED_APPS = ( ...@@ -845,6 +849,9 @@ INSTALLED_APPS = (
# edx-milestones service # edx-milestones service
'milestones', 'milestones',
# Static i18n support
'statici18n',
) )
......
if (window) { ;(function (require, define) {
'use strict';
if (window) {
// MathJax Fast Preview was introduced in 2.5. However, it // MathJax Fast Preview was introduced in 2.5. However, it
// causes undesirable flashing/font size changes when // causes undesirable flashing/font size changes when
// MathJax is used for interactive preview (equation editor). // MathJax is used for interactive preview (equation editor).
...@@ -9,14 +11,19 @@ if (window) { ...@@ -9,14 +11,19 @@ if (window) {
window.MathJax = { window.MathJax = {
menuSettings: {CHTMLpreview: false} menuSettings: {CHTMLpreview: false}
}; };
} // Since we are serving the gettext catalog as static files,
// the URL for the gettext file will vary depending on which locale
// needs to be served. To handle this, we load the correct file in the
// rendered template and then use this to ensure that RequireJS knows
// how to find it.
define("gettext", function () { return window.gettext; });
}
require.config({ require.config({
// NOTE: baseUrl has been previously set in cms/static/templates/base.html // NOTE: baseUrl has been previously set in cms/static/templates/base.html
waitSeconds: 60, waitSeconds: 60,
paths: { paths: {
"domReady": "js/vendor/domReady", "domReady": "js/vendor/domReady",
"gettext": "/i18n",
"mustache": "js/vendor/mustache", "mustache": "js/vendor/mustache",
"codemirror": "js/vendor/codemirror-compressed", "codemirror": "js/vendor/codemirror-compressed",
"codemirror/stex": "js/vendor/CodeMirror/stex", "codemirror/stex": "js/vendor/CodeMirror/stex",
...@@ -83,7 +90,7 @@ require.config({ ...@@ -83,7 +90,7 @@ require.config({
// end of Annotation tool files // end of Annotation tool files
// externally hosted files // externally hosted files
"mathjax": "//cdn.mathjax.org/mathjax/2.5-latest/MathJax.js?config=TeX-MML-AM_HTMLorMML-full&delayStartupUntil=configured", "mathjax": "//cdn.mathjax.org/mathjax/2.5-latest/MathJax.js?config=TeX-MML-AM_HTMLorMML-full&delayStartupUntil=configured", // jshint ignore:line
"youtube": [ "youtube": [
// youtube URL does not end in ".js". We add "?noext" to the path so // youtube URL does not end in ".js". We add "?noext" to the path so
// that require.js adds the ".js" to the query component of the URL, // that require.js adds the ".js" to the query component of the URL,
...@@ -192,7 +199,7 @@ require.config({ ...@@ -192,7 +199,7 @@ require.config({
"mathjax": { "mathjax": {
exports: "MathJax", exports: "MathJax",
init: function() { init: function() {
MathJax.Hub.Config({ window.MathJax.Hub.Config({
tex2jax: { tex2jax: {
inlineMath: [ inlineMath: [
["\\(","\\)"], ["\\(","\\)"],
...@@ -209,8 +216,8 @@ require.config({ ...@@ -209,8 +216,8 @@ require.config({
// (remove delay between input and output phases). This // (remove delay between input and output phases). This
// effectively disables fast preview, regardless of // effectively disables fast preview, regardless of
// the fast preview setting as shown in the context menu. // the fast preview setting as shown in the context menu.
MathJax.Hub.processSectionDelay = 0; window.MathJax.Hub.processSectionDelay = 0;
MathJax.Hub.Configured(); window.MathJax.Hub.Configured();
} }
}, },
"URI": { "URI": {
...@@ -278,12 +285,19 @@ require.config({ ...@@ -278,12 +285,19 @@ require.config({
}, },
"ova":{ "ova":{
exports: "ova", exports: "ova",
deps: ["annotator", "annotator-harvardx", "video.dev", "vjs.youtube", "rangeslider", "share-annotator", "richText-annotator", "reply-annotator", "tags-annotator", "flagging-annotator", "grouping-annotator", "diacritic-annotator", "jquery-Watch", "catch", "handlebars", "URI"] deps: ["annotator", "annotator-harvardx", "video.dev", "vjs.youtube",
"rangeslider", "share-annotator", "richText-annotator", "reply-annotator",
"tags-annotator", "flagging-annotator", "grouping-annotator", "diacritic-annotator",
"jquery-Watch", "catch", "handlebars", "URI"]
}, },
"osda":{ "osda":{
exports: "osda", exports: "osda",
deps: ["annotator", "annotator-harvardx", "video.dev", "vjs.youtube", "rangeslider", "share-annotator", "richText-annotator", "reply-annotator", "tags-annotator", "flagging-annotator", "grouping-annotator", "diacritic-annotator", "openseadragon", "jquery-Watch", "catch", "handlebars", "URI"] deps: ["annotator", "annotator-harvardx", "video.dev", "vjs.youtube",
"rangeslider", "share-annotator", "richText-annotator", "reply-annotator",
"tags-annotator", "flagging-annotator", "grouping-annotator", "diacritic-annotator",
"openseadragon", "jquery-Watch", "catch", "handlebars", "URI"]
} }
// end of annotation tool files // end of annotation tool files
} }
}); });
}).call(this, require, define);
...@@ -23,6 +23,11 @@ from openedx.core.lib.js_utils import ( ...@@ -23,6 +23,11 @@ from openedx.core.lib.js_utils import (
${settings.STUDIO_NAME} ${settings.STUDIO_NAME}
</title> </title>
<%
jsi18n_path = "js/i18n/{language}/djangojs.js".format(language=LANGUAGE_CODE)
%>
<script type="text/javascript" src="${static.url(jsi18n_path)}"></script>
<meta name="viewport" content="width=device-width,initial-scale=1"> <meta name="viewport" content="width=device-width,initial-scale=1">
<meta name="path_prefix" content="${EDX_ROOT_URL}"> <meta name="path_prefix" content="${EDX_ROOT_URL}">
......
...@@ -122,12 +122,6 @@ JS_INFO_DICT = { ...@@ -122,12 +122,6 @@ JS_INFO_DICT = {
'packages': ('openassessment',), 'packages': ('openassessment',),
} }
urlpatterns += patterns(
'',
# Serve catalog of localized strings to be rendered by Javascript
url(r'^i18n.js$', 'django.views.i18n.javascript_catalog', JS_INFO_DICT),
)
if settings.FEATURES.get('ENABLE_CONTENT_LIBRARIES'): if settings.FEATURES.get('ENABLE_CONTENT_LIBRARIES'):
urlpatterns += ( urlpatterns += (
url(r'^library/{}?$'.format(LIBRARY_KEY_PATTERN), url(r'^library/{}?$'.format(LIBRARY_KEY_PATTERN),
......
...@@ -111,6 +111,9 @@ ignore_dirs: ...@@ -111,6 +111,9 @@ ignore_dirs:
- '*/spec' - '*/spec'
- '*/tests' - '*/tests'
- '*/features' - '*/features'
# Directories full of auto-generated JS
- lms/static/js/i18n
- cms/static/js/i18n
# Third-party installed apps that we also extract strings from. When adding a # Third-party installed apps that we also extract strings from. When adding a
......
...@@ -922,6 +922,9 @@ LANGUAGE_DICT = dict(LANGUAGES) ...@@ -922,6 +922,9 @@ LANGUAGE_DICT = dict(LANGUAGES)
USE_I18N = True USE_I18N = True
USE_L10N = True USE_L10N = True
STATICI18N_ROOT = PROJECT_ROOT / "static"
STATICI18N_OUTPUT_DIR = "js/i18n"
# Localization strings (e.g. django.po) are under this directory # Localization strings (e.g. django.po) are under this directory
LOCALE_PATHS = (REPO_ROOT + '/conf/locale',) # edx-platform/conf/locale/ LOCALE_PATHS = (REPO_ROOT + '/conf/locale',) # edx-platform/conf/locale/
# Messages # Messages
...@@ -1943,6 +1946,9 @@ INSTALLED_APPS = ( ...@@ -1943,6 +1946,9 @@ INSTALLED_APPS = (
# Gating of course content # Gating of course content
'gating.apps.GatingConfig', 'gating.apps.GatingConfig',
# Static i18n support
'statici18n',
) )
# Migrations which are not in the standard module "migrations" # Migrations which are not in the standard module "migrations"
......
...@@ -32,7 +32,6 @@ ...@@ -32,7 +32,6 @@
// NOTE: baseUrl has been previously set in lms/templates/main.html // NOTE: baseUrl has been previously set in lms/templates/main.html
waitSeconds: 60, waitSeconds: 60,
paths: { paths: {
"gettext": "/i18n",
"annotator_1.2.9": "js/vendor/edxnotes/annotator-full.min", "annotator_1.2.9": "js/vendor/edxnotes/annotator-full.min",
"date": "js/vendor/date", "date": "js/vendor/date",
"moment": "js/vendor/moment.min", "moment": "js/vendor/moment.min",
......
...@@ -51,7 +51,11 @@ from branding import api as branding_api ...@@ -51,7 +51,11 @@ from branding import api as branding_api
</script> </script>
% endif % endif
<script type="text/javascript" src="/i18n.js"></script> <%
jsi18n_path = "js/i18n/{language}/djangojs.js".format(language=LANGUAGE_CODE)
%>
<script type="text/javascript" src="${static.url(jsi18n_path)}"></script>
<link rel="icon" type="image/x-icon" href="${static.url(static.get_value('favicon_path', settings.FAVICON_PATH))}" /> <link rel="icon" type="image/x-icon" href="${static.url(static.get_value('favicon_path', settings.FAVICON_PATH))}" />
......
...@@ -138,11 +138,6 @@ js_info_dict = { ...@@ -138,11 +138,6 @@ js_info_dict = {
'packages': ('openassessment',), 'packages': ('openassessment',),
} }
urlpatterns += (
# Serve catalog of localized strings to be rendered by Javascript
url(r'^i18n.js$', 'django.views.i18n.javascript_catalog', js_info_dict),
)
# sysadmin dashboard, to see what courses are loaded, to delete & load courses # sysadmin dashboard, to see what courses are loaded, to delete & load courses
if settings.FEATURES["ENABLE_SYSADMIN_DASHBOARD"]: if settings.FEATURES["ENABLE_SYSADMIN_DASHBOARD"]:
urlpatterns += ( urlpatterns += (
......
...@@ -5,12 +5,15 @@ import sys ...@@ -5,12 +5,15 @@ import sys
import subprocess import subprocess
from path import Path as path from path import Path as path
from paver.easy import task, cmdopts, needs, sh from paver.easy import task, cmdopts, needs, sh
from .utils.cmd import django_cmd
try: try:
from pygments.console import colorize from pygments.console import colorize
except ImportError: except ImportError:
colorize = lambda color, text: text colorize = lambda color, text: text
DEFAULT_SETTINGS = 'devstack'
@task @task
@needs( @needs(
...@@ -194,6 +197,7 @@ def i18n_robot_pull(): ...@@ -194,6 +197,7 @@ def i18n_robot_pull():
""" """
Pull source strings, generate po and mo files, and validate Pull source strings, generate po and mo files, and validate
""" """
# sh('paver test_i18n') # sh('paver test_i18n')
# Tests were removed from repo, but there should still be tests covering the translations # Tests were removed from repo, but there should still be tests covering the translations
# TODO: Validate the recently pulled translations, and give a bail option # TODO: Validate the recently pulled translations, and give a bail option
...@@ -203,10 +207,16 @@ def i18n_robot_pull(): ...@@ -203,10 +207,16 @@ def i18n_robot_pull():
print "\n\nValidating translations with `i18n_tool validate`..." print "\n\nValidating translations with `i18n_tool validate`..."
sh("{cmd}".format(cmd=cmd)) sh("{cmd}".format(cmd=cmd))
# Generate static i18n JS files.
for system in ['lms', 'cms']:
sh(django_cmd(system, DEFAULT_SETTINGS, 'compilejsi18n'))
con = raw_input("Continue with committing these translations (y/n)? ") con = raw_input("Continue with committing these translations (y/n)? ")
if con.lower() == 'y': if con.lower() == 'y':
sh('git add conf/locale') sh('git add conf/locale')
sh('git add cms/static/js/i18n')
sh('git add lms/static/js/i18n')
sh( sh(
'git commit --message=' 'git commit --message='
......
...@@ -26,6 +26,7 @@ django-oauth-plus==2.2.8 ...@@ -26,6 +26,7 @@ django-oauth-plus==2.2.8
django-sekizai==0.8.2 django-sekizai==0.8.2
django-ses==0.7.0 django-ses==0.7.0
django-simple-history==1.6.3 django-simple-history==1.6.3
django-statici18n==1.1.5
django-storages-redux==1.3 django-storages-redux==1.3
django-method-override==0.1.0 django-method-override==0.1.0
# We need a fix to DRF 3.2.x, for now use it from our own cherry-picked repo # We need a fix to DRF 3.2.x, for now use it from our own cherry-picked repo
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment