diff --git a/public/src/app.js b/public/src/app.js index f175c9f21f..6c5103165c 100644 --- a/public/src/app.js +++ b/public/src/app.js @@ -140,7 +140,7 @@ app.cacheBuster = null; Notifications.prepareDOM(); Chat.prepareDOM(); app.reskin(data.config.bootswatchSkin); - callback(); + translator.switchTimeagoLanguage(callback); }); }); }; diff --git a/public/src/modules/translator.js b/public/src/modules/translator.js index 2064709edc..8bce483e44 100644 --- a/public/src/modules/translator.js +++ b/public/src/modules/translator.js @@ -596,6 +596,15 @@ toggle(); } }, + + switchTimeagoLanguage: function switchTimeagoLanguage(callback) { + // Delete the cached shorthand strings if present + delete adaptor.timeagoShort; + + var languageCode = utils.userLangToTimeagoCode(config.userLang); + jQuery.getScript(config.relative_path + '/assets/vendor/jquery/timeago/locales/jquery.timeago.' + languageCode + '.js').done(callback); + }, + prepareDOM: function prepareDOM() { // Add directional code if necessary adaptor.translate('[[language:dir]]', function (value) { diff --git a/src/controllers/authentication.js b/src/controllers/authentication.js index 0e2e699a3f..3b05ac578c 100644 --- a/src/controllers/authentication.js +++ b/src/controllers/authentication.js @@ -284,6 +284,8 @@ function continueLogin(req, res, next) { }); }); } else { + delete req.query.lang; + async.parallel({ doLogin: async.apply(authenticationController.doLogin, req, userData.uid), header: async.apply(middleware.generateHeader, req, res, {}), diff --git a/src/middleware/headers.js b/src/middleware/headers.js index 3eafc203d9..ef9935ec37 100644 --- a/src/middleware/headers.js +++ b/src/middleware/headers.js @@ -2,8 +2,10 @@ var os = require('os'); var winston = require('winston'); +var _ = require('lodash'); var meta = require('../meta'); +var languages = require('../languages'); module.exports = function (middleware) { middleware.addHeaders = function (req, res, next) { @@ -60,4 +62,30 @@ module.exports = function (middleware) { next(); }; + + let langs = []; + middleware.autoLocale = function (req, res, next) { + if (parseInt(req.uid, 10) > 0 || !meta.config.autoDetectLang) { + return next(); + } + + var lang = req.acceptsLanguages(langs); + if (!lang) { + return next(); + } + req.query.lang = lang; + next(); + }; + + languages.listCodes(function (err, codes) { + if (err) { + winston.error('[middleware/autoLocale] Could not retrieve languages codes list!'); + codes = []; + } + + winston.verbose('[middleware/autoLocale] Retrieves languages list for middleware'); + var defaultLang = meta.config.defaultLang || 'en-GB'; + + langs = _.uniq([defaultLang, ...codes]); + }); }; diff --git a/src/webserver.js b/src/webserver.js index 71c4d01664..76e96a3ffb 100644 --- a/src/webserver.js +++ b/src/webserver.js @@ -25,7 +25,6 @@ var db = require('./database'); var file = require('./file'); var emailer = require('./emailer'); var meta = require('./meta'); -var languages = require('./languages'); var logger = require('./logger'); var plugins = require('./plugins'); var flags = require('./flags'); @@ -194,12 +193,13 @@ function setupExpressApp(app, callback) { app.use(middleware.addHeaders); app.use(middleware.processRender); auth.initialize(app, middleware); + app.use(middleware.autoLocale); // must be added after auth middlewares are added var toobusy = require('toobusy-js'); toobusy.maxLag(meta.config.eventLoopLagThreshold); toobusy.interval(meta.config.eventLoopInterval); - setupAutoLocale(app, callback); + callback(); } function setupFavicon(app) { @@ -233,35 +233,6 @@ function setupCookie() { return cookie; } -function setupAutoLocale(app, callback) { - languages.listCodes(function (err, codes) { - if (err) { - return callback(err); - } - - var defaultLang = meta.config.defaultLang || 'en-GB'; - - var langs = [defaultLang].concat(codes).filter(function (el, i, arr) { - return arr.indexOf(el) === i; - }); - - app.use(function (req, res, next) { - if (parseInt(req.uid, 10) > 0 || !meta.config.autoDetectLang) { - return next(); - } - - var lang = req.acceptsLanguages(langs); - if (!lang) { - return next(); - } - req.query.lang = lang; - next(); - }); - - callback(); - }); -} - function listen(callback) { callback = callback || function () { }; var port = nconf.get('port'); diff --git a/test/locale-detect.js b/test/locale-detect.js index 1bace9fd75..5f865bbd7d 100644 --- a/test/locale-detect.js +++ b/test/locale-detect.js @@ -9,17 +9,20 @@ var meta = require('../src/meta'); describe('Language detection', function () { it('should detect the language for a guest', function (done) { - meta.config.autoDetectLang = 1; - request(nconf.get('url') + '/api/config', { - headers: { - 'Accept-Language': 'de-DE,de;q=0.5', - }, - }, function (err, res, body) { + meta.configs.set('autoDetectLang', 1, function (err) { assert.ifError(err); - assert.ok(body); + request(nconf.get('url') + '/api/config', { + headers: { + 'Accept-Language': 'de-DE,de;q=0.5', + }, + json: true, + }, function (err, res, body) { + assert.ifError(err); + assert.ok(body); - assert.strictEqual(JSON.parse(body).userLang, 'de'); - done(); + assert.strictEqual(body.userLang, 'de'); + done(); + }); }); }); @@ -30,11 +33,12 @@ describe('Language detection', function () { headers: { 'Accept-Language': 'de-DE,de;q=0.5', }, + json: true, }, function (err, res, body) { assert.ifError(err); assert.ok(body); - assert.strictEqual(JSON.parse(body).userLang, 'en-GB'); + assert.strictEqual(body.userLang, 'en-GB'); done(); }); });