summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleš Smodiš <aless@guru.si>2015-09-30 17:37:31 +0200
committerAleš Smodiš <aless@guru.si>2015-09-30 17:37:31 +0200
commit0da1117cfc28688633be7b8382aa60435bf740eb (patch)
treeb464b92e673419db595c231ed1ba8e7c6cfd783b
parent8995341d43efe16f307b55f200821944cfecf4c8 (diff)
Implemented GUI translations via the data-tkey tag attribute and res/*.json files.
-rw-r--r--index.html38
-rw-r--r--js/codeq/comms.js14
-rw-r--r--js/codeq/core.js63
-rw-r--r--js/codeq/translation.js10
-rw-r--r--res/en.json15
-rw-r--r--res/sl.json15
6 files changed, 120 insertions, 35 deletions
diff --git a/index.html b/index.html
index 1464528..042e59a 100644
--- a/index.html
+++ b/index.html
@@ -36,11 +36,11 @@
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse">
<ul class="nav navbar-nav">
- <li style="display: none;" id="navigation-language"><a href="">Language</a></li>
- <li style="display: none;" id="navigation-problem"><a href="">Problem</a></li>
- <li style="display: none;" id="navigation-python"><a href="">Python</a></li>
- <li style="display: none;" id="navigation-prolog"><a href="">Prolog</a></li>
- <li style="display: none;" id="navigation-robot"><a href="">Robot</a></li>
+ <li style="display: none;" id="navigation-language"><a href="" data-tkey="language">Language</a></li>
+ <li style="display: none;" id="navigation-problem"><a href="" data-tkey="problem">Problem</a></li>
+ <li style="display: none;" id="navigation-python"><a href="" data-tkey="python">Python</a></li>
+ <li style="display: none;" id="navigation-prolog"><a href="" data-tkey="prolog">Prolog</a></li>
+ <li style="display: none;" id="navigation-robot"><a href="" data-tkey="robot">Robot</a></li>
</ul>
<ul class="nav navbar-nav navbar-right">
<p class="navbar-text" id="signed-in-title"></p>
@@ -55,10 +55,10 @@
<span class="glyphicon glyphicon glyphicon-user"></span>
</a>
<ul class="dropdown-menu">
- <li id="navigation-logout"><a href="#">Logout</a></li>
- <li id="navigation-profile"><a href="#">Profile</a></li>
+ <li id="navigation-logout"><a href="#" data-tkey="logout">Logout</a></li>
+ <li id="navigation-profile"><a href="#" data-tkey="profile">Profile</a></li>
<li role="separator" class="divider"></li>
- <li><a href="#" data-toggle="modal" data-target="#modalChangePassword">Change password</a></li>
+ <li><a href="#" data-toggle="modal" data-target="#modalChangePassword" data-tkey="change_pass">Change password</a></li>
</ul>
</li>
<li class="dropdown">
@@ -66,7 +66,7 @@
<div class="dropdown-menu" style="background-color: #fff">
<form class="form col-sm-12">
<div class="form-group">
- <span class="small">Language</span>
+ <span class="small" data-tkey="language">Language</span>
<a class="text-muted" data-container="body" data-toggle="popover" data-trigger="hover" data-placement="left" data-html="true" data-content="<span class='small'>Select the UI language.</span>" data-original-title="" title=""><i class="glyphicon glyphicon-question-sign"></i></a><br>
<select class="form-control">
<option value="sl">Slovensko</option>
@@ -75,7 +75,7 @@
</select>
</div>
<div class="form-group">
- <span class="small">
+ <span class="small" data-tkey="language">
Language
</span>
<a class="text-muted" data-container="body" data-toggle="popover" data-trigger="hover" data-placement="left" data-html="true" data-content="<span class='small'>Select the UI language.</span>" data-original-title="" title=""><i class="glyphicon glyphicon-question-sign"></i></a><br>
@@ -165,9 +165,9 @@
<div class="col-lg-3 col-md-6 col-sm-12 block block2">
<nav class="navbar navbar-default">
<div class="container-fluid">
- <button type="button" class="btn btn-default navbar-btn btn-plan">Plan</button>
- <button type="button" class="btn btn-default navbar-btn btn-hint">Hint</button>
- <button type="button" class="btn btn-default navbar-btn btn-test">Test</button>
+ <button type="button" class="btn btn-default navbar-btn btn-plan" data-tkey="btn_plan">Plan</button>
+ <button type="button" class="btn btn-default navbar-btn btn-hint" data-tkey="btn_hint">Hint</button>
+ <button type="button" class="btn btn-default navbar-btn btn-test" data-tkey="btn_test">Test</button>
</div>
</nav>
<div class="code_editor"></div>
@@ -195,11 +195,11 @@
<div class="col-lg-3 col-md-6 col-sm-12 block block2">
<nav class="navbar navbar-default">
<div class="container-fluid">
- <button type="button" class="btn btn-default navbar-btn btn-plan">Plan</button>
- <button type="button" class="btn btn-default navbar-btn btn-hint">Hint</button>
- <button type="button" class="btn btn-default navbar-btn btn-test">Test</button>
- <button type="button" class="btn btn-default navbar-btn btn-run">Run</button>
- <button type="button" class="btn btn-default navbar-btn btn-stop">Stop</button>
+ <button type="button" class="btn btn-default navbar-btn btn-plan" data-tkey="btn_plan">Plan</button>
+ <button type="button" class="btn btn-default navbar-btn btn-hint" data-tkey="btn_hint">Hint</button>
+ <button type="button" class="btn btn-default navbar-btn btn-test" data-tkey="btn_test">Test</button>
+ <button type="button" class="btn btn-default navbar-btn btn-run" data-tkey="btn_run">Run</button>
+ <button type="button" class="btn btn-default navbar-btn btn-stop" data-tkey="btn_stop">Stop</button>
</div>
</nav>
<div class="code_editor"></div>
@@ -253,7 +253,7 @@
<h2>
Profile
<div class="btn-group btn-group-xs hidden-md pull-right">
- <a href="" data-toggle="modal" data-target="#modalChangePassword" class="btn btn-default">Change Password</a>
+ <a href="" data-toggle="modal" data-target="#modalChangePassword" class="btn btn-default" data-tkey="change_pass">Change Password</a>
<a href="#" class="btn btn-default">Go back</a>
</div>
</h2>
diff --git a/js/codeq/comms.js b/js/codeq/comms.js
index ecca6ff..f416e88 100644
--- a/js/codeq/comms.js
+++ b/js/codeq/comms.js
@@ -165,7 +165,6 @@
// ================================================================================
var languageCache = {}, // language defs, keyed by language identifier
- problemCache = {}, // problem cache, 3-level, keyed by: language, problem group, and problem identifier
ajaxGet = function (url) {
return Q.Promise(function (resolve, reject, notify) {
$.ajax({
@@ -197,7 +196,7 @@
});
});
},
- ajaxPrefix;
+ ajaxPrefix, ajaxDataPrefix, ajaxResPrefix;
ajaxPrefix = location.pathname;
if (!ajaxPrefix) ajaxPrefix = '/';
@@ -206,7 +205,8 @@
ajaxPrefix[ajaxPrefix.length - 1] = '';
ajaxPrefix = ajaxPrefix.join('/');
}
- ajaxPrefix = ajaxPrefix + 'data/';
+ ajaxDataPrefix = ajaxPrefix + 'data/';
+ ajaxResPrefix = ajaxPrefix + 'res/';
// ================================================================================
// This module's API methods
@@ -399,7 +399,7 @@
return Q(x);
}
}
- x = ajaxGet(ajaxPrefix + identifier + '/language.json').then(
+ x = ajaxGet(ajaxDataPrefix + identifier + '/language.json').then(
function getLanguageDefSuccess(data) {
languageCache[identifier] = data;
return data; // proxy further
@@ -414,7 +414,11 @@
},
'getProblemDef': function (language, group, problem) {
- return ajaxGet(ajaxPrefix + language + '/' + group + '/' + problem + '/problem.json');
+ return ajaxGet(ajaxDataPrefix + language + '/' + group + '/' + problem + '/problem.json');
+ },
+
+ 'getGuiTranslation': function (lang) {
+ return ajaxGet(ajaxResPrefix + lang + '.json');
}
};
})();
diff --git a/js/codeq/core.js b/js/codeq/core.js
index 01382d1..29b497c 100644
--- a/js/codeq/core.js
+++ b/js/codeq/core.js
@@ -372,6 +372,49 @@
// The boot sequence
// ================================================================================
+ var loadGuiTranslations = function () {
+ var langs = codeq.availableLangs,
+ loaders = [],
+ loaderLangs = [],
+ i, lang;
+ for (i = langs.length - 1; i >= 0; i--) {
+ lang = langs[i];
+ loaders.push(codeq.comms.getGuiTranslation(lang));
+ loaderLangs.push(lang);
+ }
+ return Q.all(loaders)
+ .then(function (results) {
+ // convert translations into something that the translation module can use
+ var dictionary = {},
+ i, json, key, lang, translations;
+ for (i = results.length - 1; i >= 0; i--) {
+ json = results[i];
+ lang = loaderLangs[i];
+ for (key in json) {
+ if (!json.hasOwnProperty(key)) continue;
+ translations = dictionary[key];
+ if (translations) translations[lang] = json[key];
+ else {
+ translations = {};
+ dictionary[key] = translations;
+ translations[lang] = json[key];
+ }
+ }
+ }
+ // ensure each key contains all translations
+ for (key in dictionary) {
+ if (!dictionary.hasOwnProperty(key)) continue;
+ translations = dictionary[key];
+ for (i = langs.length - 1; i >= 0; i--) {
+ lang = langs[i];
+ if (!(lang in translations)) translations[lang] = "(Untranslated: " + lang + ")";
+ }
+ }
+ // register with the system
+ codeq.tr.registerDictionary('gui', dictionary);
+ });
+ };
+
$(document).ready(function () {
// set the language
var navigatorLang = navigator.language || navigator.browserLanguage, // language reported by browser
@@ -387,11 +430,17 @@
codeq.availableLangs.push(key);
}
- codeq.fire('init'); // tell any interested modules that we are not initialized, perhaps they want to initialize too
- codeq.setLang(lang || 'en'); // initial language setting
- // go to login
- codeq.globalStateMachine.transition('login');
-
- //For performance reasons, the Tooltip and Popover data-apis are opt-in, meaning you must initialize them yourself.
- $('[data-toggle="popover"]').popover()});
+ // the boot chain: must be a sequence of .then() terminated with .done()
+ loadGuiTranslations()
+ .then(function () {
+ codeq.fire('init'); // tell any interested modules that we are now initialized, perhaps they want to initialize too
+ codeq.setLang(lang || 'en'); // initial language setting, this also translates the GUI
+ // go to login
+ codeq.globalStateMachine.transition('login');
+
+ //For performance reasons, the Tooltip and Popover data-apis are opt-in, meaning you must initialize them yourself.
+ $('[data-toggle="popover"]').popover()
+ })
+ .done();
+ });
})();
diff --git a/js/codeq/translation.js b/js/codeq/translation.js
index f33199d..67f49eb 100644
--- a/js/codeq/translation.js
+++ b/js/codeq/translation.js
@@ -2,7 +2,7 @@
var dicts = {},
translateElement = function (jqElt, lang) {
- var dictionaryKey = jqElt.data('dict'),
+ var dictionaryKey = jqElt.data('dict') || 'gui',
translationKey = jqElt.data('tkey'),
dict = dicts[dictionaryKey],
translations, html, key;
@@ -43,7 +43,7 @@
jqElt.html(html);
},
translateDocument = function (lang) {
- $('.translatable').each(function () {
+ $('[data-tkey]').each(function () {
translateElement($(this), lang);
});
};
@@ -70,8 +70,10 @@
'translateDom': function (jqTopElt) {
var lang = codeq.getLang();
- if (jqTopElt.hasClass('translatable')) translateElement(jqTopElt, lang);
- jqTopElt.find('.translatable').each(function () {
+ jqTopElt.filter('[data-tkey]').each(function () {
+ translateElement(jqTopElt, lang)
+ });
+ jqTopElt.find('[data-tkey]').each(function () {
translateElement($(this), lang);
});
}
diff --git a/res/en.json b/res/en.json
new file mode 100644
index 0000000..5330cdc
--- /dev/null
+++ b/res/en.json
@@ -0,0 +1,15 @@
+{
+ "language": "Language",
+ "problem": "Problem",
+ "python": "Python",
+ "prolog": "Prolog",
+ "robot": "Robot",
+ "logout": "Logout",
+ "profile": "Profile",
+ "change_pass": "Change password",
+ "btn_plan": "Plan",
+ "btn_hint": "Hint",
+ "btn_test": "Test",
+ "btn_run": "Run",
+ "btn_stop": "Stop"
+} \ No newline at end of file
diff --git a/res/sl.json b/res/sl.json
new file mode 100644
index 0000000..cdde4f4
--- /dev/null
+++ b/res/sl.json
@@ -0,0 +1,15 @@
+{
+ "language": "Jezik",
+ "problem": "Problem",
+ "python": "Python",
+ "prolog": "Prolog",
+ "robot": "Robot",
+ "logout": "Odjava",
+ "profile": "Profil",
+ "change_pass": "Zamenjaj geslo",
+ "btn_plan": "Plan",
+ "btn_hint": "Namig",
+ "btn_test": "Testiraj",
+ "btn_run": "Zaženi",
+ "btn_stop": "Ustavi"
+} \ No newline at end of file