mirror of
https://github.com/jc21/nginx-proxy-manager.git
synced 2024-08-30 18:22:48 +00:00
I18n support, fixed version in footer
This commit is contained in:
parent
c629deb56c
commit
d49c3ba3af
@ -3,7 +3,9 @@
|
|||||||
const UserModel = require('../models/user');
|
const UserModel = require('../models/user');
|
||||||
|
|
||||||
let cache = {
|
let cache = {
|
||||||
User: new UserModel.Model()
|
User: new UserModel.Model(),
|
||||||
|
locale: 'en',
|
||||||
|
version: null
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = cache;
|
module.exports = cache;
|
||||||
|
25
src/frontend/js/app/i18n.js
Normal file
25
src/frontend/js/app/i18n.js
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
'use strict';
|
||||||
|
|
||||||
|
const Cache = ('./cache');
|
||||||
|
const messages = require('../i18n/messages.json');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param {String} namespace
|
||||||
|
* @param {String} key
|
||||||
|
* @param {Object} [data]
|
||||||
|
*/
|
||||||
|
module.exports = function (namespace, key, data) {
|
||||||
|
let locale = Cache.locale;
|
||||||
|
// check that the locale exists
|
||||||
|
if (typeof messages[locale] === 'undefined') {
|
||||||
|
locale = 'en';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof messages[locale][namespace] !== 'undefined' && typeof messages[locale][namespace][key] !== 'undefined') {
|
||||||
|
return messages[locale][namespace][key](data);
|
||||||
|
} else if (locale !== 'en' && typeof messages['en'][namespace] !== 'undefined' && typeof messages['en'][namespace][key] !== 'undefined') {
|
||||||
|
return messages['en'][namespace][key](data);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'INVALID I18N: ' + namespace + '/' + key;
|
||||||
|
};
|
@ -9,6 +9,7 @@ const Router = require('./router');
|
|||||||
const Api = require('./api');
|
const Api = require('./api');
|
||||||
const Tokens = require('./tokens');
|
const Tokens = require('./tokens');
|
||||||
const UI = require('./ui/main');
|
const UI = require('./ui/main');
|
||||||
|
const i18n = require('./i18n');
|
||||||
|
|
||||||
const App = Mn.Application.extend({
|
const App = Mn.Application.extend({
|
||||||
|
|
||||||
@ -16,7 +17,6 @@ const App = Mn.Application.extend({
|
|||||||
Api: Api,
|
Api: Api,
|
||||||
UI: null,
|
UI: null,
|
||||||
Controller: Controller,
|
Controller: Controller,
|
||||||
version: null,
|
|
||||||
|
|
||||||
region: {
|
region: {
|
||||||
el: '#app',
|
el: '#app',
|
||||||
@ -24,7 +24,7 @@ const App = Mn.Application.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
onStart: function (app, options) {
|
onStart: function (app, options) {
|
||||||
console.log('Welcome to Nginx Proxy Manager');
|
console.log(i18n('main', 'welcome'));
|
||||||
|
|
||||||
// Check if token is coming through
|
// Check if token is coming through
|
||||||
if (this.getParam('token')) {
|
if (this.getParam('token')) {
|
||||||
@ -34,12 +34,12 @@ const App = Mn.Application.extend({
|
|||||||
// Check if we are still logged in by refreshing the token
|
// Check if we are still logged in by refreshing the token
|
||||||
Api.status()
|
Api.status()
|
||||||
.then(result => {
|
.then(result => {
|
||||||
this.version = [result.version.major, result.version.minor, result.version.revision].join('.');
|
Cache.version = [result.version.major, result.version.minor, result.version.revision].join('.');
|
||||||
})
|
})
|
||||||
.then(Api.Tokens.refresh)
|
.then(Api.Tokens.refresh)
|
||||||
.then(this.bootstrap)
|
.then(this.bootstrap)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
console.info('You are logged in');
|
console.info(i18n('main', 'logged-in', Cache.User.attributes));
|
||||||
this.bootstrapTimer();
|
this.bootstrapTimer();
|
||||||
this.refreshTokenTimer();
|
this.refreshTokenTimer();
|
||||||
|
|
||||||
@ -60,7 +60,6 @@ const App = Mn.Application.extend({
|
|||||||
console.warn('Not logged in:', err.message);
|
console.warn('Not logged in:', err.message);
|
||||||
Controller.showLogin();
|
Controller.showLogin();
|
||||||
});
|
});
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
History: {
|
History: {
|
||||||
@ -86,7 +85,7 @@ const App = Mn.Application.extend({
|
|||||||
let ErrorView = Mn.View.extend({
|
let ErrorView = Mn.View.extend({
|
||||||
tagName: 'section',
|
tagName: 'section',
|
||||||
id: 'error',
|
id: 'error',
|
||||||
template: _.template('Error loading stuff. Please reload the app.')
|
template: _.template(i18n('main', 'unknown-error'))
|
||||||
});
|
});
|
||||||
|
|
||||||
this.getRegion().show(new ErrorView());
|
this.getRegion().show(new ErrorView());
|
||||||
@ -130,7 +129,7 @@ const App = Mn.Application.extend({
|
|||||||
Api.status()
|
Api.status()
|
||||||
.then(result => {
|
.then(result => {
|
||||||
let version = [result.version.major, result.version.minor, result.version.revision].join('.');
|
let version = [result.version.major, result.version.minor, result.version.revision].join('.');
|
||||||
if (version !== this.version) {
|
if (version !== Cache.version) {
|
||||||
document.location.reload();
|
document.location.reload();
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -3,12 +3,14 @@
|
|||||||
<div class="row align-items-center">
|
<div class="row align-items-center">
|
||||||
<div class="col-auto">
|
<div class="col-auto">
|
||||||
<ul class="list-inline list-inline-dots mb-0">
|
<ul class="list-inline list-inline-dots mb-0">
|
||||||
<li class="list-inline-item"><a href="https://github.com/jc21/docker-registry-ui?utm_source=docker-registry-ui">Fork me on Github</a></li>
|
<li class="list-inline-item"><a href="https://github.com/jc21/nginx-proxy-manager?utm_source=nginx-proxy-manager"><%- i18n('footer', 'fork-me') %></a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12 col-lg-auto mt-3 mt-lg-0 text-center">
|
<div class="col-12 col-lg-auto mt-3 mt-lg-0 text-center">
|
||||||
v<%- getVersion() %> © 2018 <a href="https://jc21.com?utm_source=nginx-proxy-manager" target="_blank">jc21.com</a>. Theme by <a href="https://tabler.github.io/?utm_source=nginx-proxy-manager" target="_blank">Tabler</a>
|
<%- i18n('footer', 'version', {version: getVersion()}) %>
|
||||||
|
<%= i18n('footer', 'copy', {url: 'https://jc21.com?utm_source=nginx-proxy-manager'}) %>
|
||||||
|
<%= i18n('footer', 'theme', {url: 'https://tabler.github.io/?utm_source=nginx-proxy-manager'}) %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
const Mn = require('backbone.marionette');
|
const Mn = require('backbone.marionette');
|
||||||
const template = require('./main.ejs');
|
const template = require('./main.ejs');
|
||||||
const App = require('../../main');
|
const Cache = require('../../cache');
|
||||||
|
|
||||||
module.exports = Mn.View.extend({
|
module.exports = Mn.View.extend({
|
||||||
className: 'container',
|
className: 'container',
|
||||||
@ -10,7 +10,7 @@ module.exports = Mn.View.extend({
|
|||||||
|
|
||||||
templateContext: {
|
templateContext: {
|
||||||
getVersion: function () {
|
getVersion: function () {
|
||||||
return App.version;
|
return Cache.version || '0.0.0';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<div class="container">
|
<div class="container">
|
||||||
<div class="d-flex">
|
<div class="d-flex">
|
||||||
<a class="navbar-brand" href="/">
|
<a class="navbar-brand" href="/">
|
||||||
<img src="/images/favicons/favicon-32x32.png" border="0"> Nginx Proxy Manager
|
<img src="/images/favicons/favicon-32x32.png" border="0"> <%- i18n('main', 'app') %>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
<div class="d-flex order-lg-2 ml-auto">
|
<div class="d-flex order-lg-2 ml-auto">
|
||||||
@ -9,16 +9,16 @@
|
|||||||
<a href="#" class="nav-link pr-0 leading-none" data-toggle="dropdown">
|
<a href="#" class="nav-link pr-0 leading-none" data-toggle="dropdown">
|
||||||
<span class="avatar" style="background-image: url(<%- getUserField('avatar', '/images/default-avatar.jpg') %>)"></span>
|
<span class="avatar" style="background-image: url(<%- getUserField('avatar', '/images/default-avatar.jpg') %>)"></span>
|
||||||
<span class="ml-2 d-none d-lg-block">
|
<span class="ml-2 d-none d-lg-block">
|
||||||
<span class="text-default"><%- getUserField('nickname', null) || getUserField('name', 'Unknown User') %></span>
|
<span class="text-default"><%- getUserField('nickname', null) || getUserField('name', i18n('main', 'unknown-user')) %></span>
|
||||||
<small class="text-muted d-block mt-1"><%- getRole() %></small>
|
<small class="text-muted d-block mt-1"><%- getRole() %></small>
|
||||||
</span>
|
</span>
|
||||||
</a>
|
</a>
|
||||||
<div class="dropdown-menu dropdown-menu-right dropdown-menu-arrow">
|
<div class="dropdown-menu dropdown-menu-right dropdown-menu-arrow">
|
||||||
<a class="dropdown-item edit-details" href="#">
|
<a class="dropdown-item edit-details" href="#">
|
||||||
<i class="dropdown-icon fe fe-user"></i> Edit Details
|
<i class="dropdown-icon fe fe-user"></i> <%- i18n('user', 'edit-details') %>
|
||||||
</a>
|
</a>
|
||||||
<a class="dropdown-item change-password" href="#">
|
<a class="dropdown-item change-password" href="#">
|
||||||
<i class="dropdown-icon fe fe-lock"></i> Change Password
|
<i class="dropdown-icon fe fe-lock"></i> <%- i18n('user', 'change-password') %>
|
||||||
</a>
|
</a>
|
||||||
<div class="dropdown-divider"></div>
|
<div class="dropdown-divider"></div>
|
||||||
<a class="dropdown-item logout" href="/logout">
|
<a class="dropdown-item logout" href="/logout">
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
const $ = require('jquery');
|
const $ = require('jquery');
|
||||||
const Mn = require('backbone.marionette');
|
const Mn = require('backbone.marionette');
|
||||||
|
const i18n = require('../../i18n');
|
||||||
const Cache = require('../../cache');
|
const Cache = require('../../cache');
|
||||||
const Controller = require('../../controller');
|
const Controller = require('../../controller');
|
||||||
const Tokens = require('../../tokens');
|
const Tokens = require('../../tokens');
|
||||||
@ -50,15 +51,15 @@ module.exports = Mn.View.extend({
|
|||||||
},
|
},
|
||||||
|
|
||||||
getRole: function () {
|
getRole: function () {
|
||||||
return Cache.User.isAdmin() ? 'Administrator' : 'Apache Helicopter';
|
return i18n('roles', Cache.User.isAdmin() ? 'admin' : 'user');
|
||||||
},
|
},
|
||||||
|
|
||||||
getLogoutText: function () {
|
getLogoutText: function () {
|
||||||
if (Tokens.getTokenCount() > 1) {
|
if (Tokens.getTokenCount() > 1) {
|
||||||
return 'Sign back in as ' + Tokens.getNextTokenName();
|
return i18n('main', 'sign-in-as', {name: Tokens.getNextTokenName()});
|
||||||
}
|
}
|
||||||
|
|
||||||
return 'Sign out';
|
return i18n('main', 'sign-out');
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
27
src/frontend/js/i18n/messages.json
Normal file
27
src/frontend/js/i18n/messages.json
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"en": {
|
||||||
|
"main": {
|
||||||
|
"app": "Nginx Proxy Manager",
|
||||||
|
"welcome": "Welcome to Nginx Proxy Manager",
|
||||||
|
"logged-in": "You are logged in as {name}",
|
||||||
|
"unknown-error": "Error loading stuff. Please reload the app.",
|
||||||
|
"unknown-user": "Unknown User",
|
||||||
|
"sign-out": "Sign out",
|
||||||
|
"sign-in-as": "Sign back in as {name}"
|
||||||
|
},
|
||||||
|
"user": {
|
||||||
|
"edit-details": "Edit Details",
|
||||||
|
"change-password": "Change Password"
|
||||||
|
},
|
||||||
|
"roles": {
|
||||||
|
"admin": "Administrator",
|
||||||
|
"user": "Apache Helicopter"
|
||||||
|
},
|
||||||
|
"footer": {
|
||||||
|
"fork-me": "Fork me on Github",
|
||||||
|
"copy": "© 2018 <a href=\"{url}\" target=\"_blank\">jc21.com</a>.",
|
||||||
|
"version": "v{version}",
|
||||||
|
"theme": "Theme by <a href=\"{url}\" target=\"_blank\">Tabler</a>"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -4,6 +4,7 @@ const _ = require('underscore');
|
|||||||
const Mn = require('backbone.marionette');
|
const Mn = require('backbone.marionette');
|
||||||
const moment = require('moment');
|
const moment = require('moment');
|
||||||
const numeral = require('numeral');
|
const numeral = require('numeral');
|
||||||
|
const i18n = require('../app/i18n');
|
||||||
|
|
||||||
let render = Mn.Renderer.render;
|
let render = Mn.Renderer.render;
|
||||||
|
|
||||||
@ -11,6 +12,8 @@ Mn.Renderer.render = function (template, data, view) {
|
|||||||
|
|
||||||
data = _.clone(data);
|
data = _.clone(data);
|
||||||
|
|
||||||
|
data.i18n = i18n;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param {Integer} number
|
* @param {Integer} number
|
||||||
* @returns {String}
|
* @returns {String}
|
||||||
|
@ -45,6 +45,19 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
// other:
|
// other:
|
||||||
|
{
|
||||||
|
type: 'javascript/auto', // <= Set the module.type explicitly
|
||||||
|
test: /\bmessages\.json$/,
|
||||||
|
loader: 'messageformat-loader',
|
||||||
|
options: {
|
||||||
|
biDiSupport: false,
|
||||||
|
disablePluralKeyChecks: false,
|
||||||
|
formatters: null,
|
||||||
|
intlSupport: false,
|
||||||
|
locale: ['en'/*, 'es'*/],
|
||||||
|
strictNumberSign: false
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
test: /\.js$/,
|
test: /\.js$/,
|
||||||
exclude: /node_modules/,
|
exclude: /node_modules/,
|
||||||
|
Loading…
Reference in New Issue
Block a user