Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Internationalization of ZIM viewer #871

Merged
merged 12 commits into from
Feb 6, 2023
Merged
12 changes: 7 additions & 5 deletions scripts/kiwix-compile-resources
Original file line number Diff line number Diff line change
Expand Up @@ -202,15 +202,17 @@ if __name__ == "__main__":
parser.add_argument('--source_dir',
help="Additional directory where to look for resources.",
action='append')
parser.add_argument('resource_file',
parser.add_argument('resource_files', nargs='+',
help='The list of resources to compile.')
args = parser.parse_args()

base_dir = os.path.dirname(os.path.realpath(args.resource_file))
source_dir = args.source_dir or []
with open(args.resource_file, 'r') as f:
resources = [Resource([base_dir]+source_dir, *line.strip().split())
for line in f.readlines()]
resources = []
for resfile in args.resource_files:
base_dir = os.path.dirname(os.path.realpath(resfile))
with open(resfile, 'r') as f:
resources += [Resource([base_dir]+source_dir, *line.strip().split())
for line in f.readlines()]

h_identifier = to_identifier(os.path.basename(args.hfile))
with open(args.hfile, 'w') as f:
Expand Down
2 changes: 1 addition & 1 deletion scripts/kiwix-compile-resources.1
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
.SH NAME
kiwix-compile-resources \- helper to compile and generate some Kiwix resources
.SH SYNOPSIS
\fBkiwix\-compile\-resources\fR [\-h] [\-\-cxxfile CXXFILE] [\-\-hfile HFILE] resource_file\fR
\fBkiwix\-compile\-resources\fR [\-h] [\-\-cxxfile CXXFILE] [\-\-hfile HFILE] resource_file ...\fR
.SH DESCRIPTION
.TP
resource_file
Expand Down
29 changes: 25 additions & 4 deletions static/generate_i18n_resources_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,36 @@
# along with this program. If not, see <http://www.gnu.org/licenses/>.

from pathlib import Path
import json

script_path = Path(__file__)

resource_file = script_path.parent / "i18n_resources_list.txt"
translation_dir = script_path.parent / "i18n"
translation_dir = script_path.parent / "skin/i18n"
language_list_relpath = "skin/languages.js"

def get_translation_info(filepath):
lang_code = Path(filepath).stem
with open(filepath, 'r', encoding="utf-8") as f:
content = json.load(f)
return lang_code, content["name"]

language_list = []
json_files = translation_dir.glob("*.json")
with open(resource_file, 'w', encoding="utf-8") as f:
for json in sorted(translation_dir.glob("*.json")):
if json.name == "qqq.json":
for i18n_file in sorted(translation_dir.glob("*.json")):
if i18n_file.name == "qqq.json":
continue
f.write(str(json.relative_to(script_path.parent)) + '\n')
print("Processing", i18n_file.name)
if i18n_file.name != "test.json":
language_list.append(get_translation_info(i18n_file))
f.write(str(i18n_file.relative_to(script_path.parent)) + '\n')

language_list = [{name: code} for code, name in sorted(language_list)]
language_list_jsobj_str = json.dumps(language_list,
indent=2,
ensure_ascii=False)
print("Saving", language_list_relpath)
fullpath = script_path.parent / language_list_relpath
with open(fullpath, 'w', encoding="utf-8") as f:
f.write("const uiLanguages = " + language_list_jsobj_str)
48 changes: 24 additions & 24 deletions static/i18n_resources_list.txt
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
i18n/ar.json
i18n/bn.json
i18n/cs.json
i18n/de.json
i18n/en.json
i18n/fr.json
i18n/he.json
i18n/hy.json
i18n/it.json
i18n/ja.json
i18n/ko.json
i18n/ku-latn.json
i18n/mk.json
i18n/nqo.json
i18n/pl.json
i18n/ru.json
i18n/sc.json
i18n/sk.json
i18n/sl.json
i18n/sv.json
i18n/test.json
i18n/tr.json
i18n/zh-hans.json
i18n/zh-hant.json
skin/i18n/ar.json
skin/i18n/bn.json
skin/i18n/cs.json
skin/i18n/de.json
skin/i18n/en.json
skin/i18n/fr.json
skin/i18n/he.json
skin/i18n/hy.json
skin/i18n/it.json
skin/i18n/ja.json
skin/i18n/ko.json
skin/i18n/ku-latn.json
skin/i18n/mk.json
skin/i18n/nqo.json
skin/i18n/pl.json
skin/i18n/ru.json
skin/i18n/sc.json
skin/i18n/sk.json
skin/i18n/sl.json
skin/i18n/sv.json
skin/i18n/test.json
skin/i18n/tr.json
skin/i18n/zh-hans.json
skin/i18n/zh-hant.json
2 changes: 1 addition & 1 deletion static/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ preprocessed_resources = custom_target('preprocessed_resource_files',
)

lib_resources = custom_target('resources',
input: preprocessed_resources,
input: [preprocessed_resources, 'i18n_resources_list.txt'],
output: ['libkiwix-resources.cpp', 'libkiwix-resources.h'],
command:[res_compiler,
'--cxxfile', '@OUTPUT0@',
Expand Down
3 changes: 3 additions & 0 deletions static/resources_list.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ skin/fonts/Roboto.ttf
skin/search_results.css
skin/blank.html
skin/viewer.js
skin/i18n.js
skin/languages.js
skin/mustache.min.js
veloman-yunkan marked this conversation as resolved.
Show resolved Hide resolved
viewer.html
templates/search_result.html
templates/search_result.xml
Expand Down
103 changes: 103 additions & 0 deletions static/skin/i18n.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
import mustache from '../skin/mustache.min.js?KIWIXCACHEID'

const Translations = {
defaultLanguage: null,
currentLanguage: null,
promises: {},
data: {},

load: function(lang, asDefault=false) {
if ( asDefault ) {
this.defaultLanguage = lang;
this.loadTranslationsJSON(lang);
} else {
this.currentLanguage = lang;
if ( lang != this.defaultLanguage ) {
this.loadTranslationsJSON(lang);
}
}
},

loadTranslationsJSON: function(lang) {
if ( this.promises[lang] )
return;

const errorMsg = `Error loading translations for language '${lang}': `;
this.promises[lang] = fetch(`./skin/i18n/${lang}.json`).then(async (resp) => {
if ( resp.ok ) {
this.data[lang] = JSON.parse(await resp.text());
} else {
console.log(errorMsg + resp.statusText);
}
}).catch((err) => {
console.log(errorMsg + err);
});
},

whenReady: function(callback) {
const defaultLangPromise = this.promises[this.defaultLanguage];
const currentLangPromise = this.promises[this.currentLanguage];
Promise.all([defaultLangPromise, currentLangPromise]).then(callback);
},

get: function(msgId) {
const activeTranslation = this.data[this.currentLanguage];

const r = activeTranslation && activeTranslation[msgId];
if ( r )
return r;

const defaultMsgs = this.data[this.defaultLanguage];
if ( defaultMsgs )
return defaultMsgs[msgId];

throw "Translations are not loaded";
}
}


function $t(msgId, params={}) {
try {
const msgTemplate = Translations.get(msgId);
if ( ! msgTemplate ) {
return "Invalid message id: " + msgId;
}

return mustache.render(msgTemplate, params);
} catch (err) {
return "ERROR: " + err;
}
}

function getCookie(cookieName) {
const name = cookieName + "=";
let result;
decodeURIComponent(document.cookie).split('; ').forEach(val => {
if (val.indexOf(name) === 0) {
result = val.substring(name.length);
}
});
return result;
}


const DEFAULT_UI_LANGUAGE = 'en';

Translations.load(DEFAULT_UI_LANGUAGE, /*asDefault=*/true);

function getUserLanguage() {
return new URLSearchParams(window.location.search).get('userlang')
|| getCookie('userlang')
|| DEFAULT_UI_LANGUAGE;
}

function setUserLanguage(lang, callback) {
const rootPath = new URL('..', import.meta.url).pathname.replace(/\/$/, '');
document.cookie = `userlang=${lang};path=${rootPath};max-age=31536000`;
Translations.load(lang);
Translations.whenReady(callback);
}

window.$t = $t;
window.getUserLanguage = getUserLanguage;
window.setUserLanguage = setUserLanguage;
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
1 change: 1 addition & 0 deletions static/i18n/ja.json → static/skin/i18n/ja.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
"MathXplore"
]
},
"name": "日本語",
"no-query": "クエリを指定していません。",
"400-page-title": "無効なリクエストです",
"400-page-heading": "無効なリクエストです",
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
65 changes: 65 additions & 0 deletions static/skin/languages.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
const uiLanguages = [
{
"বাংলা": "bn"
},
{
"Čeština": "cs"
},
{
"Deutsch": "de"
},
{
"English": "en"
},
{
"français": "fr"
},
{
"עברית": "he"
},
{
"Հայերեն": "hy"
},
{
"italiano": "it"
},
{
"日本語": "ja"
},
{
"한국어": "ko"
},
{
"kurdî": "ku-latn"
},
{
"македонски": "mk"
},
{
"ߒߞߏ": "nqo"
},
{
"Polski": "pl"
},
{
"русский": "ru"
},
{
"Sardu": "sc"
},
{
"slovenčina": "sk"
},
{
"Svenska": "sv"
},
{
"Türkçe": "tr"
},
{
"英语": "zh-hans"
},
{
"繁體中文": "zh-hant"
}
]
Loading