ZIM viewer i18n via userlang query parameter

ZIM viewer is now internally internationalized but the UI language
can only be set by providing the `userlang` query parameter in the URL:

Example:

  /viewer?userlang=fr#wikipedia_en_climate_change_mini_2021-03/A/index
         ^^^^^^^^^^^^
This commit is contained in:
Veloman Yunkan 2023-01-19 15:56:05 +04:00
parent e42719c9df
commit eba7e15358
3 changed files with 42 additions and 7 deletions

View File

@ -2,10 +2,14 @@
// //
// user url: identifier of the page that has to be displayed in the viewer // user url: identifier of the page that has to be displayed in the viewer
// and that is used as the hash component of the viewer URL. For // and that is used as the hash component of the viewer URL. For
// book resources the address url is {book}/{resource} . // book resources the user url is {book}/{resource} .
// //
// iframe url: the URL to be loaded in the viewer iframe. // iframe url: the URL to be loaded in the viewer iframe.
let viewerState = {
uiLanguage: 'en',
};
function userUrl2IframeUrl(url) { function userUrl2IframeUrl(url) {
if ( url == '' ) { if ( url == '' ) {
return blankPageUrl; return blankPageUrl;
@ -68,14 +72,24 @@ function makeJSLink(jsCodeString, linkText, linkAttr="") {
function suggestionsApiURL() function suggestionsApiURL()
{ {
return `${root}/suggest?content=${encodeURIComponent(currentBook)}`; const uriEncodedBookName = encodeURIComponent(currentBook);
const userLang = viewerState.uiLanguage;
return `${root}/suggest?userlang=${userLang}&content=${uriEncodedBookName}`;
}
function setTitle(element, text) {
if ( element ) {
element.title = text;
if ( element.hasAttribute("aria-label") ) {
element.setAttribute("aria-label", text);
}
}
} }
function setCurrentBook(book, title) { function setCurrentBook(book, title) {
currentBook = book; currentBook = book;
currentBookTitle = title; currentBookTitle = title;
homeButton.title = `Go to the main page of '${title}'`; setTitle(homeButton, $t("home-button-text", {BOOK_TITLE: title}));
homeButton.setAttribute("aria-label", homeButton.title);
homeButton.innerHTML = `<button>${title}</button>`; homeButton.innerHTML = `<button>${title}</button>`;
bookUIGroup.style.display = 'inline'; bookUIGroup.style.display = 'inline';
updateSearchBoxForBookChange(); updateSearchBoxForBookChange();
@ -153,7 +167,7 @@ function updateSearchBoxForBookChange() {
const searchbox = document.getElementById('kiwixsearchbox'); const searchbox = document.getElementById('kiwixsearchbox');
const kiwixSearchFormWrapper = document.querySelector('.kiwix_searchform'); const kiwixSearchFormWrapper = document.querySelector('.kiwix_searchform');
if ( currentBookTitle ) { if ( currentBookTitle ) {
searchbox.title = `Search '${currentBookTitle}'`; searchbox.title = $t("searchbox-tooltip", {BOOK_TITLE : currentBookTitle});
searchbox.placeholder = searchbox.title; searchbox.placeholder = searchbox.title;
searchbox.setAttribute("aria-label", searchbox.title); searchbox.setAttribute("aria-label", searchbox.title);
kiwixSearchFormWrapper.style.display = 'inline'; kiwixSearchFormWrapper.style.display = 'inline';
@ -402,6 +416,10 @@ function setupViewer() {
return; return;
} }
const lang = getUserLanguage();
setUserLanguage(lang, finishViewerSetupOnceTranslationsAreLoaded);
viewerState.uiLanguage = lang;
kiwixToolBarWrapper.style.display = 'block'; kiwixToolBarWrapper.style.display = 'block';
if ( ! viewerSettings.libraryButtonEnabled ) { if ( ! viewerSettings.libraryButtonEnabled ) {
document.getElementById("kiwix_serve_taskbar_library_button").remove(); document.getElementById("kiwix_serve_taskbar_library_button").remove();
@ -417,9 +435,22 @@ function setupViewer() {
if (document.body.clientWidth < 520) { if (document.body.clientWidth < 520) {
setupAutoHidingOfTheToolbar(); setupAutoHidingOfTheToolbar();
} }
}
function updateUIText() {
currentBook = getBookFromUserUrl(location.hash.slice(1)); currentBook = getBookFromUserUrl(location.hash.slice(1));
updateCurrentBook(currentBook); updateCurrentBook(currentBook);
setTitle(document.getElementById("kiwix_serve_taskbar_library_button"),
$t("library-button-text"));
setTitle(document.getElementById("kiwix_serve_taskbar_random_button"),
$t("random-page-button-text"));
}
function finishViewerSetupOnceTranslationsAreLoaded()
{
updateUIText();
handle_location_hash_change(); handle_location_hash_change();
window.onhashchange = handle_location_hash_change; window.onhashchange = handle_location_hash_change;

View File

@ -7,6 +7,8 @@
<link type="text/css" href="./skin/taskbar.css?KIWIXCACHEID" rel="Stylesheet" /> <link type="text/css" href="./skin/taskbar.css?KIWIXCACHEID" rel="Stylesheet" />
<link type="text/css" href="./skin/css/autoComplete.css?KIWIXCACHEID" rel="Stylesheet" /> <link type="text/css" href="./skin/css/autoComplete.css?KIWIXCACHEID" rel="Stylesheet" />
<script type="text/javascript" src="./viewer_settings.js"></script> <script type="text/javascript" src="./viewer_settings.js"></script>
<script type="module" src="./skin/i18n.js?KIWIXCACHEID" defer></script>
<script type="text/javascript" src="./skin/languages.js?KIWIXCACHEID" defer></script>
<script type="text/javascript" src="./skin/viewer.js?KIWIXCACHEID" defer></script> <script type="text/javascript" src="./skin/viewer.js?KIWIXCACHEID" defer></script>
<script type="text/javascript" src="./skin/autoComplete.min.js?KIWIXCACHEID"></script> <script type="text/javascript" src="./skin/autoComplete.min.js?KIWIXCACHEID"></script>
<script> <script>

View File

@ -73,7 +73,7 @@ const ResourceCollection resources200Compressible{
{ DYNAMIC_CONTENT, "/ROOT/skin/taskbar.css" }, { DYNAMIC_CONTENT, "/ROOT/skin/taskbar.css" },
{ STATIC_CONTENT, "/ROOT/skin/taskbar.css?cacheid=216d6b5d" }, { STATIC_CONTENT, "/ROOT/skin/taskbar.css?cacheid=216d6b5d" },
{ DYNAMIC_CONTENT, "/ROOT/skin/viewer.js" }, { DYNAMIC_CONTENT, "/ROOT/skin/viewer.js" },
{ STATIC_CONTENT, "/ROOT/skin/viewer.js?cacheid=33265688" }, { STATIC_CONTENT, "/ROOT/skin/viewer.js?cacheid=961068b0" },
{ DYNAMIC_CONTENT, "/ROOT/skin/fonts/Poppins.ttf" }, { DYNAMIC_CONTENT, "/ROOT/skin/fonts/Poppins.ttf" },
{ STATIC_CONTENT, "/ROOT/skin/fonts/Poppins.ttf?cacheid=af705837" }, { STATIC_CONTENT, "/ROOT/skin/fonts/Poppins.ttf?cacheid=af705837" },
{ DYNAMIC_CONTENT, "/ROOT/skin/fonts/Roboto.ttf" }, { DYNAMIC_CONTENT, "/ROOT/skin/fonts/Roboto.ttf" },
@ -300,7 +300,9 @@ R"EXPECTEDRESULT( <img src="../skin/download.png?
/* url */ "/ROOT/viewer", /* url */ "/ROOT/viewer",
R"EXPECTEDRESULT( <link type="text/css" href="./skin/taskbar.css?cacheid=216d6b5d" rel="Stylesheet" /> R"EXPECTEDRESULT( <link type="text/css" href="./skin/taskbar.css?cacheid=216d6b5d" rel="Stylesheet" />
<link type="text/css" href="./skin/css/autoComplete.css?cacheid=08951e06" rel="Stylesheet" /> <link type="text/css" href="./skin/css/autoComplete.css?cacheid=08951e06" rel="Stylesheet" />
<script type="text/javascript" src="./skin/viewer.js?cacheid=33265688" defer></script> <script type="module" src="./skin/i18n.js?cacheid=eb41f5ce" defer></script>
<script type="text/javascript" src="./skin/languages.js?cacheid=fe100348" defer></script>
<script type="text/javascript" src="./skin/viewer.js?cacheid=961068b0" defer></script>
<script type="text/javascript" src="./skin/autoComplete.min.js?cacheid=1191aaaf"></script> <script type="text/javascript" src="./skin/autoComplete.min.js?cacheid=1191aaaf"></script>
const blankPageUrl = root + "/skin/blank.html?cacheid=6b1fa032"; const blankPageUrl = root + "/skin/blank.html?cacheid=6b1fa032";
<label for="kiwix_button_show_toggle"><img src="./skin/caret.png?cacheid=22b942b4" alt=""></label> <label for="kiwix_button_show_toggle"><img src="./skin/caret.png?cacheid=22b942b4" alt=""></label>