mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-10-29 18:16:17 +01:00
@@ -69,5 +69,6 @@
|
||||
"invisible": "Invisible",
|
||||
"offline": "Offline",
|
||||
|
||||
"privacy": "Privacy"
|
||||
"privacy": "Privacy",
|
||||
"language": "Language"
|
||||
}
|
||||
|
||||
@@ -7,16 +7,21 @@ define(['forum/accountheader'], function(header) {
|
||||
$('#submitBtn').on('click', function() {
|
||||
var settings = {};
|
||||
|
||||
$('.account input, .account textarea').each(function(id, input) {
|
||||
$('.account').find('input, textarea, select').each(function(id, input) {
|
||||
input = $(input);
|
||||
var setting = input.attr('data-property');
|
||||
if (input.is('select')) {
|
||||
settings[setting] = input.val();
|
||||
return;
|
||||
}
|
||||
|
||||
switch (input.attr('type')) {
|
||||
case 'text' :
|
||||
case 'textarea' :
|
||||
settings[input.attr('data-property')] = input.val();
|
||||
settings[setting] = input.val();
|
||||
break;
|
||||
case 'checkbox' :
|
||||
settings[input.attr('data-property')] = input.is(':checked') ? 1 : 0;
|
||||
settings[setting] = input.is(':checked') ? 1 : 0;
|
||||
break;
|
||||
}
|
||||
});
|
||||
@@ -32,9 +37,16 @@ define(['forum/accountheader'], function(header) {
|
||||
});
|
||||
|
||||
socket.emit('user.getSettings', function(err, settings) {
|
||||
for (var setting in settings) {
|
||||
if (settings.hasOwnProperty(setting)) {
|
||||
var input = $('.account input[data-property="' + setting + '"]');
|
||||
var inputs = $('.account').find('input, textarea, select');
|
||||
|
||||
inputs.each(function(index, input) {
|
||||
input = $(input);
|
||||
var setting = input.attr('data-property');
|
||||
if (setting) {
|
||||
if (input.is('select')) {
|
||||
input.val(settings[setting]);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (input.attr('type')) {
|
||||
case 'text' :
|
||||
@@ -46,7 +58,7 @@ define(['forum/accountheader'], function(header) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -4,17 +4,15 @@
|
||||
|
||||
|
||||
var translator = {},
|
||||
files = {
|
||||
loaded: {},
|
||||
loading: {},
|
||||
callbacks: {} // could be combined with "loading" in future.
|
||||
};
|
||||
languages = {};
|
||||
|
||||
module.exports = translator;
|
||||
|
||||
// Use this in plugins to add your own translation files.
|
||||
translator.addTranslation = function(filename, translations) {
|
||||
files.loaded[filename] = translations;
|
||||
translator.addTranslation = function(language, filename, translations) {
|
||||
languages[language] = languages[language] || {};
|
||||
languages[language].loaded = languages[language].loaded || {};
|
||||
languages[language].loaded[filename] = translations;
|
||||
};
|
||||
|
||||
translator.getLanguage = function() {
|
||||
@@ -67,11 +65,21 @@
|
||||
}
|
||||
};
|
||||
|
||||
translator.translate = function (data, callback) {
|
||||
translator.translate = function (data, language, callback) {
|
||||
if (!data) {
|
||||
return callback(data);
|
||||
}
|
||||
|
||||
if (typeof language === 'function') {
|
||||
callback = language;
|
||||
if ('undefined' !== typeof window && config) {
|
||||
language = config.defaultLang || 'en_GB';
|
||||
} else {
|
||||
var meta = require('../../src/meta');
|
||||
language = meta.config.defaultLang || 'en_GB';
|
||||
}
|
||||
}
|
||||
|
||||
function insertLanguage(text, key, value, variables) {
|
||||
if (value) {
|
||||
for (var i = 1, ii = variables.length; i < ii; i++) {
|
||||
@@ -109,12 +117,12 @@
|
||||
var languageFile = parsedKey[0];
|
||||
parsedKey = ('' + parsedKey[1]).split(',')[0];
|
||||
|
||||
if (files.loaded[languageFile]) {
|
||||
data = insertLanguage(data, key, files.loaded[languageFile][parsedKey], variables);
|
||||
if (isLanguageFileLoaded(language, languageFile)) {
|
||||
data = insertLanguage(data, key, languages[language].loaded[languageFile][parsedKey], variables);
|
||||
} else {
|
||||
loading++;
|
||||
(function (languageKey, parsedKey, languageFile, variables) {
|
||||
translator.load(languageFile, function (languageData) {
|
||||
translator.load(language, languageFile, function (languageData) {
|
||||
data = insertLanguage(data, languageKey, languageData[parsedKey], variables);
|
||||
loading--;
|
||||
checkComplete();
|
||||
@@ -132,61 +140,73 @@
|
||||
}
|
||||
};
|
||||
|
||||
translator.clearLoadedFiles = function() {
|
||||
files.loaded = {};
|
||||
files.loading = {};
|
||||
};
|
||||
translator.load = function (language, filename, callback) {
|
||||
|
||||
translator.load = function (filename, callback) {
|
||||
|
||||
if (files.loaded[filename] && !files.loading[filename]) {
|
||||
if (isLanguageFileLoaded(language, filename)) {
|
||||
if (callback) {
|
||||
callback(files.loaded[filename]);
|
||||
callback(languages[language].loaded[filename]);
|
||||
}
|
||||
} else if (files.loading[filename]) {
|
||||
} else if (isLanguageFileLoading(language, filename)) {
|
||||
if (callback) {
|
||||
files.callbacks[filename] = files.callbacks[filename] || [];
|
||||
files.callbacks[filename].push(callback);
|
||||
addLanguageFileCallback(language, filename, callback);
|
||||
}
|
||||
} else {
|
||||
|
||||
files.loading[filename] = true;
|
||||
languages[language] = languages[language] || {loading: {}, loaded: {}, callbacks: []};
|
||||
|
||||
load(filename, function(language) {
|
||||
files.loaded[filename] = language;
|
||||
languages[language].loading[filename] = true;
|
||||
|
||||
load(language, filename, function(translations) {
|
||||
|
||||
languages[language].loaded[filename] = translations;
|
||||
|
||||
if (callback) {
|
||||
callback(language);
|
||||
callback(translations);
|
||||
}
|
||||
|
||||
while (files.callbacks[filename] && files.callbacks[filename].length) {
|
||||
files.callbacks[filename].pop()(language);
|
||||
while (languages[language].callbacks[filename] && languages[language].callbacks[filename].length) {
|
||||
languages[language].callbacks[filename].pop()(translations);
|
||||
}
|
||||
|
||||
files.loading[filename] = false;
|
||||
languages[language].loading[filename] = false;
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
function load(filename, callback) {
|
||||
function isLanguageFileLoaded(language, filename) {
|
||||
var languageObj = languages[language];
|
||||
return languageObj && languageObj.loaded && languageObj.loaded[filename] && !languageObj.loading[filename];
|
||||
}
|
||||
|
||||
function isLanguageFileLoading(language, filename) {
|
||||
return languages[language] && languages[language].loading && languages[language].loading[filename];
|
||||
}
|
||||
|
||||
function addLanguageFileCallback(language, filename, callback) {
|
||||
languages[language].callbacks = languages[language].callbacks || {};
|
||||
|
||||
languages[language].callbacks[filename] = languages[language].callbacks[filename] || [];
|
||||
languages[language].callbacks[filename].push(callback);
|
||||
}
|
||||
|
||||
function load(language, filename, callback) {
|
||||
if ('undefined' !== typeof window) {
|
||||
loadClient(filename, callback);
|
||||
loadClient(language, filename, callback);
|
||||
} else {
|
||||
loadServer(filename, callback);
|
||||
loadServer(language, filename, callback);
|
||||
}
|
||||
}
|
||||
|
||||
function loadClient(filename, callback) {
|
||||
function loadClient(language, filename, callback) {
|
||||
var timestamp = new Date().getTime();
|
||||
$.getJSON(config.relative_path + '/language/' + config.defaultLang + '/' + filename + '.json?v=' + timestamp, callback);
|
||||
$.getJSON(config.relative_path + '/language/' + language + '/' + filename + '.json?v=' + timestamp, callback);
|
||||
}
|
||||
|
||||
function loadServer(filename, callback) {
|
||||
function loadServer(language, filename, callback) {
|
||||
var fs = require('fs'),
|
||||
path = require('path'),
|
||||
winston = require('winston'),
|
||||
meta = require('../../src/meta'),
|
||||
language = meta.config.defaultLang || 'en_GB';
|
||||
meta = require('../../src/meta');
|
||||
|
||||
if (!fs.existsSync(path.join(__dirname, '../language', language))) {
|
||||
winston.warn('[translator] Language \'' + meta.config.defaultLang + '\' not found. Defaulting to \'en_GB\'');
|
||||
|
||||
@@ -15,6 +15,7 @@ var fs = require('fs'),
|
||||
utils = require('./../../public/src/utils'),
|
||||
meta = require('./../meta'),
|
||||
plugins = require('./../plugins'),
|
||||
languages = require('./../languages'),
|
||||
image = require('./../image'),
|
||||
file = require('./../file');
|
||||
|
||||
@@ -331,22 +332,29 @@ accountsController.accountSettings = function(req, res, next) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
user.getUserFields(uid, ['username', 'userslug'], function(err, userData) {
|
||||
async.parallel({
|
||||
user: function(next) {
|
||||
user.getUserFields(uid, ['username', 'userslug'], next);
|
||||
},
|
||||
languages: function(next) {
|
||||
languages.list(next);
|
||||
}
|
||||
}, function(err, results) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
if(!userData) {
|
||||
if(!results.user) {
|
||||
return userNotFound();
|
||||
}
|
||||
userData.yourid = req.user.uid;
|
||||
userData.theirid = uid;
|
||||
userData.settings = settings;
|
||||
|
||||
res.render('accountsettings', userData);
|
||||
results.user.yourid = req.user.uid;
|
||||
results.user.theirid = uid;
|
||||
results.user.settings = settings;
|
||||
|
||||
res.render('accountsettings', results);
|
||||
});
|
||||
});
|
||||
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
@@ -58,6 +58,7 @@ apiController.getConfig = function(req, res, next) {
|
||||
config.topicsPerPage = settings.topicsPerPage;
|
||||
config.postsPerPage = settings.postsPerPage;
|
||||
config.notificationSounds = settings.notificationSounds;
|
||||
config.defaultLang = settings.language || config.defaultLang;
|
||||
|
||||
if (res.locals.isAPI) {
|
||||
res.json(200, config);
|
||||
|
||||
17
src/meta.js
17
src/meta.js
@@ -63,11 +63,6 @@ var fs = require('fs'),
|
||||
|
||||
callback(err, res);
|
||||
}
|
||||
|
||||
// this might be a good spot to add a hook
|
||||
if (field === 'defaultLang') {
|
||||
translator.clearLoadedFiles();
|
||||
}
|
||||
});
|
||||
},
|
||||
setOnEmpty: function (field, value, callback) {
|
||||
@@ -173,10 +168,8 @@ var fs = require('fs'),
|
||||
isTopic: /^topic\/\d+\/?/,
|
||||
isUserPage: /^user\/[^\/]+(\/[\w]+)?/
|
||||
},
|
||||
build: function (urlFragment, callback) {
|
||||
var user = require('./user');
|
||||
|
||||
Meta.title.parseFragment(decodeURIComponent(urlFragment), function(err, title) {
|
||||
build: function (urlFragment, language, callback) {
|
||||
Meta.title.parseFragment(decodeURIComponent(urlFragment), language, function(err, title) {
|
||||
if (err) {
|
||||
title = Meta.config.browserTitle || 'NodeBB';
|
||||
} else {
|
||||
@@ -186,14 +179,14 @@ var fs = require('fs'),
|
||||
callback(null, title);
|
||||
});
|
||||
},
|
||||
parseFragment: function (urlFragment, callback) {
|
||||
parseFragment: function (urlFragment, language, callback) {
|
||||
var translated = ['', 'recent', 'unread', 'users', 'notifications'];
|
||||
if (translated.indexOf(urlFragment) !== -1) {
|
||||
if (!urlFragment.length) {
|
||||
urlFragment = 'home';
|
||||
}
|
||||
|
||||
translator.translate('[[pages:' + urlFragment + ']]', function(translated) {
|
||||
translator.translate('[[pages:' + urlFragment + ']]', language, function(translated) {
|
||||
callback(null, translated);
|
||||
});
|
||||
} else if (this.tests.isCategory.test(urlFragment)) {
|
||||
@@ -215,7 +208,7 @@ var fs = require('fs'),
|
||||
|
||||
User.getUsernameByUserslug(userslug, function(err, username) {
|
||||
if (subpage) {
|
||||
translator.translate('[[pages:user.' + subpage + ', ' + username + ']]', function(translated) {
|
||||
translator.translate('[[pages:user.' + subpage + ', ' + username + ']]', language, function(translated) {
|
||||
callback(null, translated);
|
||||
});
|
||||
} else {
|
||||
|
||||
@@ -143,30 +143,31 @@ middleware.checkAccountPermissions = function(req, res, next) {
|
||||
};
|
||||
|
||||
middleware.buildHeader = function(req, res, next) {
|
||||
async.parallel([
|
||||
function(next) {
|
||||
res.locals.renderHeader = true;
|
||||
next();
|
||||
res.locals.renderHeader = true;
|
||||
async.parallel({
|
||||
config: function(next) {
|
||||
controllers.api.getConfig(req, res, next);
|
||||
},
|
||||
function(next) {
|
||||
controllers.api.getConfig(req, res, function(err, config) {
|
||||
res.locals.config = config;
|
||||
next(err);
|
||||
});
|
||||
},
|
||||
function(next) {
|
||||
// consider caching this, since no user specific information is loaded here
|
||||
app.render('footer', {}, function(err, template) {
|
||||
translator.translate(template, function(parsedTemplate) {
|
||||
res.locals.footer = parsedTemplate;
|
||||
next(err);
|
||||
});
|
||||
});
|
||||
footer: function(next) {
|
||||
app.render('footer', {}, next);
|
||||
}
|
||||
], next);
|
||||
}, function(err, results) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
|
||||
res.locals.config = results.config;
|
||||
|
||||
translator.translate(results.footer, results.config.defaultLang, function(parsedTemplate) {
|
||||
res.locals.footer = parsedTemplate;
|
||||
next();
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
middleware.renderHeader = function(req, res, callback) {
|
||||
var uid = req.user ? parseInt(req.user.uid, 10) : 0;
|
||||
|
||||
var custom_header = {
|
||||
'navigation': []
|
||||
};
|
||||
@@ -218,8 +219,6 @@ middleware.renderHeader = function(req, res, callback) {
|
||||
}
|
||||
}
|
||||
|
||||
var uid = '0';
|
||||
|
||||
templateValues.metaTags = defaultMetaTags.concat(res.locals.metaTags || []).map(function(tag) {
|
||||
if(!tag || typeof tag.content !== 'string') {
|
||||
winston.warn('Invalid meta tag. ', tag);
|
||||
@@ -239,9 +238,6 @@ middleware.renderHeader = function(req, res, callback) {
|
||||
href: nconf.get('relative_path') + '/favicon.ico'
|
||||
});
|
||||
|
||||
if(req.user && req.user.uid) {
|
||||
uid = req.user.uid;
|
||||
}
|
||||
|
||||
templateValues.useCustomCSS = false;
|
||||
if (meta.config.useCustomCSS === '1') {
|
||||
@@ -249,34 +245,30 @@ middleware.renderHeader = function(req, res, callback) {
|
||||
templateValues.customCSS = meta.config.customCSS;
|
||||
}
|
||||
|
||||
async.parallel([
|
||||
function(next) {
|
||||
translator.translate('[[pages:' + path.basename(req.url) + ']]', function(translated) {
|
||||
var metaTitle = templateValues.metaTags.filter(function(tag) {
|
||||
return tag.name === 'title';
|
||||
});
|
||||
|
||||
if (translated) {
|
||||
templateValues.browserTitle = translated;
|
||||
} else if (metaTitle.length > 0 && metaTitle[0].content) {
|
||||
templateValues.browserTitle = metaTitle[0].content;
|
||||
} else {
|
||||
templateValues.browserTitle = meta.config.browserTitle || 'NodeBB';
|
||||
}
|
||||
|
||||
next();
|
||||
});
|
||||
async.parallel({
|
||||
title: function(next) {
|
||||
if (uid) {
|
||||
user.getSettings(uid, function(err, settings) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
meta.title.build(req.url.slice(1), settings.language, next);
|
||||
});
|
||||
} else {
|
||||
meta.title.build(req.url.slice(1), meta.config.defaultLang, next);
|
||||
}
|
||||
},
|
||||
function(next) {
|
||||
user.isAdministrator(uid, function(err, isAdmin) {
|
||||
templateValues.isAdmin = isAdmin || false;
|
||||
next();
|
||||
});
|
||||
isAdmin: function(next) {
|
||||
user.isAdministrator(uid, next);
|
||||
}
|
||||
], function() {
|
||||
app.render('header', templateValues, function(err, template) {
|
||||
callback(null, template);
|
||||
});
|
||||
}, function(err, results) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
templateValues.browserTitle = results.title;
|
||||
templateValues.isAdmin = results.isAdmin || false;
|
||||
|
||||
app.render('header', templateValues, callback);
|
||||
});
|
||||
});
|
||||
};
|
||||
@@ -322,7 +314,7 @@ middleware.processRender = function(req, res, next) {
|
||||
middleware.renderHeader(req, res, function(err, template) {
|
||||
str = template + str;
|
||||
|
||||
translator.translate(str, function(translated) {
|
||||
translator.translate(str, res.locals.config.defaultLang, function(translated) {
|
||||
fn(err, translated);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -32,7 +32,16 @@ SocketMeta.reconnected = function(socket) {
|
||||
};
|
||||
|
||||
SocketMeta.buildTitle = function(socket, text, callback) {
|
||||
meta.title.build(text, callback);
|
||||
if (socket.uid) {
|
||||
user.getSettings(socket.uid, function(err, settings) {
|
||||
if (err) {
|
||||
return callback(err);
|
||||
}
|
||||
meta.title.build(text, settings.language, callback);
|
||||
});
|
||||
} else {
|
||||
meta.title.build(text, meta.config.defaultLang, callback);
|
||||
}
|
||||
};
|
||||
|
||||
SocketMeta.updateHeader = function(socket, data, callback) {
|
||||
|
||||
@@ -29,6 +29,7 @@ module.exports = function(User) {
|
||||
settings.topicsPerPage = settings.topicsPerPage ? parseInt(settings.topicsPerPage, 10) : parseInt(meta.config.topicsPerPage, 10) || 20;
|
||||
settings.postsPerPage = settings.postsPerPage ? parseInt(settings.postsPerPage, 10) : parseInt(meta.config.postsPerPage, 10) || 10;
|
||||
settings.notificationSounds = settings.notificationSounds ? parseInt(settings.notificationSounds, 10) === 1 : true;
|
||||
settings.language = settings.language || meta.config.defaultLang || 'en_GB';
|
||||
callback(null, settings);
|
||||
});
|
||||
});
|
||||
@@ -47,7 +48,8 @@ module.exports = function(User) {
|
||||
usePagination: data.usePagination,
|
||||
topicsPerPage: data.topicsPerPage,
|
||||
postsPerPage: data.postsPerPage,
|
||||
notificationSounds: data.notificationSounds
|
||||
notificationSounds: data.notificationSounds,
|
||||
language: data.language || meta.config.defaultLang
|
||||
}, callback);
|
||||
};
|
||||
};
|
||||
Reference in New Issue
Block a user