mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-12-22 08:20:36 +01:00
fixed serverside templating; footer, logout internationalization; updated more global lang keys
This commit is contained in:
1
app.js
1
app.js
@@ -85,6 +85,7 @@
|
|||||||
plugins = require('./src/plugins'); // Don't remove this - plugins initializes itself
|
plugins = require('./src/plugins'); // Don't remove this - plugins initializes itself
|
||||||
|
|
||||||
global.templates = {};
|
global.templates = {};
|
||||||
|
global.translator = translator;
|
||||||
|
|
||||||
translator.loadServer();
|
translator.loadServer();
|
||||||
|
|
||||||
|
|||||||
12
public/language/en/footer.json
Normal file
12
public/language/en/footer.json
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"disconnect.title": "Socket Disconnect",
|
||||||
|
"disconnect.message": "Looks like you disconnected, try reloading the page.",
|
||||||
|
"disconnect.reload_button": "Reload",
|
||||||
|
"chat.chatting_with": "Chat with <span id='chat-with-name'></span>",
|
||||||
|
"chat.placeholder": "type chat message, here press enter to send",
|
||||||
|
"chat.send": "Send",
|
||||||
|
"stats.online": "Online",
|
||||||
|
"stats.users": "Users",
|
||||||
|
"stats.topics": "Topics",
|
||||||
|
"stats.posts": "Posts"
|
||||||
|
}
|
||||||
@@ -4,5 +4,8 @@
|
|||||||
"403.title": "Access Denied",
|
"403.title": "Access Denied",
|
||||||
"403.message": "You seem to have stumbled upon a page that you do not have access to. Perhaps you should <a href='/login'>try logging in</a>?",
|
"403.message": "You seem to have stumbled upon a page that you do not have access to. Perhaps you should <a href='/login'>try logging in</a>?",
|
||||||
"404.title": "Not Found",
|
"404.title": "Not Found",
|
||||||
"404.message": "You seem to have stumbled upon a page that does not exist. Return to the <a href='/''>home page</a>."
|
"404.message": "You seem to have stumbled upon a page that does not exist. Return to the <a href='/''>home page</a>.",
|
||||||
|
"logout": "Logout",
|
||||||
|
"logout.title": "You are now logged out.",
|
||||||
|
"logout.message": "You have successfully logged out of NodeBB"
|
||||||
}
|
}
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
(function (module) {
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
})('undefined' === typeof module ? {
|
|
||||||
module: {
|
|
||||||
exports: {}
|
|
||||||
}
|
|
||||||
} : module);
|
|
||||||
@@ -17,12 +17,73 @@
|
|||||||
files = {
|
files = {
|
||||||
loaded: {},
|
loaded: {},
|
||||||
loading: {},
|
loading: {},
|
||||||
callbacks: {}
|
callbacks: {} // could be combined with "loading" in future.
|
||||||
},
|
},
|
||||||
isServer = false;
|
isServer = false;
|
||||||
|
|
||||||
module.exports = translator;
|
module.exports = translator;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO: DRY, see translator.translate. The hard part is to make sure both work node.js / js side
|
||||||
|
*/
|
||||||
|
translator.get = function (key, callback) {
|
||||||
|
var parsedKey = key.split(':'),
|
||||||
|
languageFile = parsedKey[0];
|
||||||
|
|
||||||
|
parsedKey = parsedKey[1];
|
||||||
|
translator.load(languageFile, function (languageData) {
|
||||||
|
if (callback) {
|
||||||
|
callback(languageData[parsedKey]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return languageData[parsedKey];
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO: Not fully converted to server side yet, ideally server should be able to parse whole templates on demand if necessary
|
||||||
|
* fix: translator.load should determine if server side and immediately return appropriate language file.
|
||||||
|
*/
|
||||||
|
translator.translate = function (data, callback) {
|
||||||
|
var keys = data.match(/\[\[.*?\]\]/g),
|
||||||
|
loading = 0;
|
||||||
|
|
||||||
|
for (var key in keys) {
|
||||||
|
if (keys.hasOwnProperty(key)) {
|
||||||
|
//check for additional variables then keys[key].split(/[,][?\s+]/);
|
||||||
|
|
||||||
|
var parsedKey = keys[key].replace('[[', '').replace(']]', '').split(':'),
|
||||||
|
languageFile = parsedKey[0];
|
||||||
|
|
||||||
|
parsedKey = parsedKey[1];
|
||||||
|
|
||||||
|
if (files.loaded[languageFile]) {
|
||||||
|
data = data.replace(keys[key], files.loaded[languageFile][parsedKey]);
|
||||||
|
} else {
|
||||||
|
loading++;
|
||||||
|
|
||||||
|
(function (languageKey, parsedKey) {
|
||||||
|
translator.load(languageFile, function (languageData) {
|
||||||
|
data = data.replace(languageKey, languageData[parsedKey]);
|
||||||
|
loading--;
|
||||||
|
checkComplete();
|
||||||
|
});
|
||||||
|
}(keys[key], parsedKey));
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
checkComplete();
|
||||||
|
|
||||||
|
function checkComplete() {
|
||||||
|
if (loading === 0) {
|
||||||
|
callback(data);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
translator.load = function (filename, callback) {
|
translator.load = function (filename, callback) {
|
||||||
if (isServer === true) {
|
if (isServer === true) {
|
||||||
if (callback) {
|
if (callback) {
|
||||||
@@ -80,68 +141,6 @@
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
|
||||||
* TODO: DRY, see translator.translate. The hard part is to make sure both work node.js / js side
|
|
||||||
*/
|
|
||||||
translator.get = function (key, callback) {
|
|
||||||
var parsedKey = key.split(':'),
|
|
||||||
languageFile = parsedKey[0];
|
|
||||||
|
|
||||||
parsedKey = parsedKey[1];
|
|
||||||
translator.load(languageFile, function (languageData) {
|
|
||||||
if (callback) {
|
|
||||||
callback(languageData[parsedKey]);
|
|
||||||
}
|
|
||||||
|
|
||||||
return languageData[parsedKey];
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* TODO: Not fully converted to server side yet, ideally server should be able to parse whole templates on demand if necessary
|
|
||||||
* fix: translator.load should determine if server side and immediately return appropriate language file.
|
|
||||||
*/
|
|
||||||
translator.translate = function (data, callback) {
|
|
||||||
var keys = data.match(/\[\[.*?\]\]/g),
|
|
||||||
loading = 0;
|
|
||||||
|
|
||||||
for (var key in keys) {
|
|
||||||
if (keys.hasOwnProperty(key)) {
|
|
||||||
//check for additional variables then keys[key].split(/[,][?\s+]/);
|
|
||||||
|
|
||||||
var parsedKey = keys[key].replace('[[', '').replace(']]', '').split(':'),
|
|
||||||
languageFile = parsedKey[0];
|
|
||||||
|
|
||||||
parsedKey = parsedKey[1];
|
|
||||||
|
|
||||||
if (files.loaded[languageFile]) {
|
|
||||||
data = data.replace(keys[key], files.loaded[languageFile][parsedKey]);
|
|
||||||
} else {
|
|
||||||
loading++;
|
|
||||||
|
|
||||||
(function (languageKey, parsedKey) {
|
|
||||||
translator.load(languageFile, function (languageData) {
|
|
||||||
data = data.replace(languageKey, languageData[parsedKey]);
|
|
||||||
loading--;
|
|
||||||
checkComplete();
|
|
||||||
});
|
|
||||||
}(keys[key], parsedKey));
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
checkComplete();
|
|
||||||
|
|
||||||
function checkComplete() {
|
|
||||||
if (loading === 0) {
|
|
||||||
callback(data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
if ('undefined' !== typeof window) {
|
if ('undefined' !== typeof window) {
|
||||||
window.translator = module.exports;
|
window.translator = module.exports;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,13 +6,13 @@
|
|||||||
<div class="modal-dialog">
|
<div class="modal-dialog">
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<h3 id="myModalLabel">Socket Disconnect</h3>
|
<h3 id="myModalLabel">[[footer:disconnect.title]]</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<span id="disconnect-text">Looks like you disconnected, try reloading the page.</span>
|
<span id="disconnect-text">[[footer:disconnect.message]]</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<a id="reload-button" href="/" class="btn btn-primary">Reload</a>
|
<a id="reload-button" href="/" class="btn btn-primary">[[footer:disconnect.reload_button]]</a>
|
||||||
</div>
|
</div>
|
||||||
</div><!-- /.modal-content -->
|
</div><!-- /.modal-content -->
|
||||||
</div><!-- /.modal-dialog -->
|
</div><!-- /.modal-dialog -->
|
||||||
@@ -23,15 +23,15 @@
|
|||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
|
||||||
<h3 id="myModalLabel">Chat with <span id="chat-with-name"></span></h3>
|
<h3 id="myModalLabel">[[footer:chat.chatting_with]]</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
<textarea class="form-control" id="chat-content" cols="40" rows="10" readonly></textarea><br/>
|
<textarea class="form-control" id="chat-content" cols="40" rows="10" readonly></textarea><br/>
|
||||||
<input id="chat-message-input" type="text" class="form-control" name="chat-message" placeholder="type chat message, here press enter to send"/>
|
<input id="chat-message-input" type="text" class="form-control" name="chat-message" placeholder="[[footer:chat.placeholder]]"/>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-footer">
|
<div class="modal-footer">
|
||||||
<button type="button" id="chat-message-send-btn" href="#" class="btn btn-primary btn-lg btn-block
|
<button type="button" id="chat-message-send-btn" href="#" class="btn btn-primary btn-lg btn-block
|
||||||
">Send</button>
|
">[[footer:chat.send]]</button>
|
||||||
</div>
|
</div>
|
||||||
</div><!-- /.modal-content -->
|
</div><!-- /.modal-content -->
|
||||||
</div><!-- /.modal-dialog -->
|
</div><!-- /.modal-dialog -->
|
||||||
@@ -45,22 +45,22 @@
|
|||||||
<div class="row footer-stats">
|
<div class="row footer-stats">
|
||||||
<div class="col-md-3 col-xs-6">
|
<div class="col-md-3 col-xs-6">
|
||||||
<div class="stats-card well">
|
<div class="stats-card well">
|
||||||
<h2><span id="stats_online"></span><br /><small>Online</small></h2>
|
<h2><span id="stats_online"></span><br /><small>[[footer:stats.online]]</small></h2>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-3 col-xs-6">
|
<div class="col-md-3 col-xs-6">
|
||||||
<div class="stats-card well">
|
<div class="stats-card well">
|
||||||
<h2><span id="stats_users"></span><br /><small>Users</small></h2>
|
<h2><span id="stats_users"></span><br /><small>[[footer:stats.users]]</small></h2>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-3 col-xs-6">
|
<div class="col-md-3 col-xs-6">
|
||||||
<div class="stats-card well">
|
<div class="stats-card well">
|
||||||
<h2><span id="stats_topics"></span><br /><small>Topics</small></h2>
|
<h2><span id="stats_topics"></span><br /><small>[[footer:stats.topics]]</small></h2>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-3 col-xs-6">
|
<div class="col-md-3 col-xs-6">
|
||||||
<div class="stats-card well">
|
<div class="stats-card well">
|
||||||
<h2><span id="stats_posts"></span><br /><small>Posts</small></h2>
|
<h2><span id="stats_posts"></span><br /><small>[[footer:stats.posts]]</small></h2>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -1,13 +1,13 @@
|
|||||||
<ol class="breadcrumb">
|
<ol class="breadcrumb">
|
||||||
<li itemscope="itemscope" itemtype="http://data-vocabulary.org/Breadcrumb">
|
<li itemscope="itemscope" itemtype="http://data-vocabulary.org/Breadcrumb">
|
||||||
<a href="/" itemprop="url"><span itemprop="title">Home</span></a>
|
<a href="/" itemprop="url"><span itemprop="title">[[global:home]]</span></a>
|
||||||
</li>
|
</li>
|
||||||
<li class="active" itemscope="itemscope" itemtype="http://data-vocabulary.org/Breadcrumb">
|
<li class="active" itemscope="itemscope" itemtype="http://data-vocabulary.org/Breadcrumb">
|
||||||
<span itemprop="title">Logout</span>
|
<span itemprop="title">[[global:logout]]</span>
|
||||||
</li>
|
</li>
|
||||||
</ol>
|
</ol>
|
||||||
|
|
||||||
<div class="alert alert-success" id="message">
|
<div class="alert alert-success" id="message">
|
||||||
<h4>You are now logged out.</h4>
|
<h4>[[global:logout.title]]</h4>
|
||||||
<p>You have successfully logged out of NodeBB</p>
|
<p>[[global:logout.message]]</p>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -55,13 +55,9 @@ var express = require('express'),
|
|||||||
meta_tags: metaString
|
meta_tags: metaString
|
||||||
};
|
};
|
||||||
|
|
||||||
// meta.build_title(options.title, (options.req.user ? options.req.user.uid : 0), function(err, title) {
|
translator.translate(templates['header'].parse(templateValues), function(template) {
|
||||||
// if (!err) templateValues.browserTitle = title;
|
callback(null, template);
|
||||||
|
});
|
||||||
// callback(null, templates['header'].parse(templateValues));
|
|
||||||
// });
|
|
||||||
|
|
||||||
callback(null, templates['header'].parse(templateValues));
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Middlewares
|
// Middlewares
|
||||||
@@ -117,6 +113,15 @@ var express = require('express'),
|
|||||||
|
|
||||||
module.exports.init = function() {
|
module.exports.init = function() {
|
||||||
templates = global.templates;
|
templates = global.templates;
|
||||||
|
|
||||||
|
// translate all static templates served by webserver here. ex. footer, logout
|
||||||
|
translator.translate(templates['footer'].toString(), function(parsedTemplate) {
|
||||||
|
templates['footer'] = parsedTemplate;
|
||||||
|
});
|
||||||
|
translator.translate(templates['logout'].toString(), function(parsedTemplate) {
|
||||||
|
templates['logout'] = parsedTemplate;
|
||||||
|
});
|
||||||
|
|
||||||
server.listen(nconf.get('PORT') || nconf.get('port'));
|
server.listen(nconf.get('PORT') || nconf.get('port'));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user