SysOps: deploy-all — 2026-06-09 10:41 UTC
This commit is contained in:
@@ -0,0 +1,80 @@
|
||||
/** 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); };
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user