Files
foodlinkk-command-center/cockpit/static/js/i18n.js
T
2026-06-09 10:41:13 +00:00

81 lines
2.6 KiB
JavaScript

/** Foodlinkk i18n — edit /static/i18n/nl.json and en.json to translate. */
window.I18n = (function () {
var locale = 'nl';
var strings = {};
function t(key, fallback) {
if (!key) return fallback || '';
var parts = String(key).split('.');
var o = strings;
for (var i = 0; i < parts.length; i++) {
if (o == null || typeof o !== 'object') return fallback != null ? fallback : key;
o = o[parts[i]];
}
return typeof o === 'string' ? o : (fallback != null ? fallback : key);
}
function applyDom() {
document.querySelectorAll('[data-i18n]').forEach(function (el) {
var k = el.getAttribute('data-i18n');
if (k) el.textContent = t(k);
});
document.querySelectorAll('[data-i18n-placeholder]').forEach(function (el) {
var k = el.getAttribute('data-i18n-placeholder');
if (k) el.placeholder = t(k);
});
document.querySelectorAll('[data-i18n-title]').forEach(function (el) {
var k = el.getAttribute('data-i18n-title');
if (k) el.title = t(k);
});
document.documentElement.lang = locale;
}
async function loadBundle(loc) {
var r = await fetch('/static/i18n/' + loc + '.json?v=2');
if (!r.ok) throw new Error('Locale ' + loc + ' not found');
strings = await r.json();
}
async function setLocale(loc, persist) {
if (persist == null) persist = true;
locale = loc === 'en' ? 'en' : 'nl';
try {
await loadBundle(locale);
} catch (e) {
if (locale !== 'nl') {
locale = 'nl';
await loadBundle('nl');
}
}
localStorage.setItem('foodlinkk_locale', locale);
applyDom();
window.dispatchEvent(new CustomEvent('foodlinkk:locale', { detail: { locale: locale } }));
if (persist) {
fetch('/api/preferences/ui', {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ locale: locale }),
}).catch(function () {});
}
return locale;
}
async function init() {
var loc = localStorage.getItem('foodlinkk_locale') || 'nl';
try {
var prefs = await fetch('/api/preferences/ui').then(function (r) { return r.json(); });
if (prefs.locale) loc = prefs.locale;
} catch (e) { /* ignore */ }
await setLocale(loc, false);
}
return { t: t, init: init, setLocale: setLocale, locale: function () { return locale; }, applyDom: applyDom };
})();
document.addEventListener('alpine:init', function () {
if (!window.Alpine) return;
Alpine.magic('t', function () {
return function (key, fallback) { return window.I18n.t(key, fallback); };
});
});