added i18next, translated header

This commit is contained in:
Philippe Loctaux 2023-08-06 17:52:22 +02:00
parent 3d79fc1817
commit 29609dbc67
7 changed files with 51 additions and 5 deletions

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -0,0 +1,2 @@
// https://www.unpkg.com/loc-i18next@0.1.5/loc-i18next.min.js
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define(t):e.locI18next=t()}(this,function(){"use strict";function e(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function t(t){for(var n=1;n<arguments.length;n++){var r=null!=arguments[n]?arguments[n]:{},i=Object.keys(r);"function"==typeof Object.getOwnPropertySymbols&&(i=i.concat(Object.getOwnPropertySymbols(r).filter(function(e){return Object.getOwnPropertyDescriptor(r,e).enumerable}))),i.forEach(function(n){e(t,n,r[n])})}return t}function n(e){function n(t,n,r){var i="text";if(0==n.indexOf("[")){var o=n.split("]");n=o[1],i=o[0].substr(1,o[0].length-1)}if(n=n.indexOf(";")==n.length-1?n.substr(0,n.length-2):n,"html"===i)t.innerHTML=e.t(n,c(r,t.innerHTML));else if("text"===i)t.textContent=e.t(n,c(r,t.textContent));else if("prepend"===i){var l=t.innerHTML.indexOf("<loc-i18n>"),u=t.innerHTML.indexOf("</loc-i18n>")+11;l>-1&&u>6&&(t.innerHTML=[t.innerHTML.substring(0,l),t.innerHTML.slice(u)].join("")),t.innerHTML=["<loc-i18n>",e.t(n,c(r,t.innerHTML)),"</loc-i18n>",t.innerHTML].join("")}else if("append"===i){var f=t.innerHTML.indexOf("<loc-i18n>"),s=t.innerHTML.indexOf("</loc-i18n>")+11;f>-1&&s>6&&(t.innerHTML=[t.innerHTML.substring(0,f),t.innerHTML.slice(s)].join("")),t.innerHTML=[t.innerHTML,"<loc-i18n>",e.t(n,c(r,t.innerHTML),"</loc-i18n>")].join("")}else if(0===i.indexOf("data-")){var a=i.substr("data-".length),p=e.t(n,c(r,t.getAttribute(a)));t.setAttribute(a,p),t.setAttribute(i,p)}else t.setAttribute(i,e.t(n,c(r,t.getAttribute(i))))}function i(e){return JSON.parse(e.replace(/:\s*"([^"]*)"/g,function(e,t){return': "'+t.replace(/:/g,"@colon@")+'"'}).replace(/:\s*'([^']*)'/g,function(e,t){return': "'+t.replace(/:/g,"@colon@")+'"'}).replace(/(['"])?([a-z0-9A-Z_]+)(['"])?\s*:/g,'"$2": ').replace(/@colon@/g,":"))}function o(e,r){var o=e.getAttribute(u.selectorAttr);if(o){var l=e,c=e.getAttribute(u.targetAttr);if(null!=c&&(l=e.querySelector(c)||e),r||!0!==u.useOptionsAttr||(r=i(e.getAttribute(u.optionsAttr)||"{}")),r=r||{},o.indexOf(";")>=0)for(var f=o.split(";"),s=0,a=f.length;s<a;s++)""!=f[s]&&n(l,f[s],r);else n(l,o,r);if(!0===u.useOptionsAttr){var p={};p=t({clone:p},r),delete p.lng,e.setAttribute(u.optionsAttr,JSON.stringify(p))}}}function l(e,t){for(var n=(null===t||void 0===t?void 0:t.document)||u.document,r=n.querySelectorAll(e),i=0;i<r.length;i++){for(var l=r[i],c=l.querySelectorAll("["+u.selectorAttr+"]"),f=c.length-1;f>-1;f--)o(c[f],t);o(l,t)}}var u=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{};u=t({},r,u);var c=function(e,n){return u.parseDefaultValueFromContent?t({},e,{defaultValue:n}):e};return l}var r={selectorAttr:"data-i18n",targetAttr:"i18n-target",optionsAttr:"i18n-options",useOptionsAttr:!1,parseDefaultValueFromContent:!0,document:document};return{init:n}});

View file

@ -1,5 +1,5 @@
<!doctype html>
<html lang="en">
<html>
<head>
<meta charset="utf-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover"/>
@ -9,6 +9,11 @@
<link href="/css/tabler.min.css" rel="stylesheet"/>
<link href="/css/tabler-vendors.min.css" rel="stylesheet"/>
<link href="/css/demo.min.css" rel="stylesheet"/>
<!-- i18n -->
<script src="/libs/i18next/i18next.min.js"></script>
<script src="/libs/i18next-http-backend/i18nextHttpBackend.min.js"></script>
<script src="/libs/i18next-browser-language-detector/i18nextBrowserLanguageDetector.min.js"></script>
<script src="/libs/loc-i18next/loc-i18next.min.js"></script>
<!-- Favicon -->
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
@ -27,5 +32,34 @@
}
</style>
</head>
{% block page %}{% endblock page %}
<script>
i18next
.use(i18nextBrowserLanguageDetector)
.use(i18nextHttpBackend)
.init({
detection: {
order: ['localStorage', 'navigator'],
},
fallbackLng: 'en',
debug: false,
interpolation: {
prefix: "[[",
suffix: "]]"
},
backend: {
loadPath: '/i18n/[[lng]].json'
}
}, function (err, _t) {
if (err) {
return console.error(err);
}
localize = locI18next.init(i18next);
{% block i18n %}{% endblock i18n %}
});
</script>
</html>

View file

@ -21,3 +21,7 @@
{% block additional_js %}{% endblock additional_js %}
</body>
{% endblock page %}
{% block i18n %}
localize("#header_user_nav");
{% endblock i18n %}

View file

@ -16,7 +16,7 @@
{{ user::user_info(name=user.name, username=user.username, email=user.email) }}
</div>
</a>
<div class="dropdown-menu dropdown-menu-end dropdown-menu-arrow">
<div class="dropdown-menu dropdown-menu-end dropdown-menu-arrow" id="header_user_nav">
<div class="d-xl-none">
<div class="dropdown-item-text">
{{ user::user_info(name=user.name, username=user.username, email=user.email) }}
@ -24,13 +24,13 @@
<div class="dropdown-divider"></div>
</div>
<a href="/settings" class="dropdown-item">Settings</a>
<a href="/settings" class="dropdown-item" data-i18n="header.settings"></a>
{% if user.isAdmin == true %}
<a href="/admin" class="dropdown-item">Admin panel</a>
<a href="/admin" class="dropdown-item" data-i18n="header.admin_panel"></a>
{% endif %}
<div class="dropdown-divider"></div>
<form action="/logout" method="post">
<button type="submit" class="dropdown-item">Logout</button>
<button type="submit" class="dropdown-item" data-i18n="header.logout"></button>
</form>
</div>
</div>