work-in-progress commit for #4655

v1.18.x
Julian Lam 9 years ago
parent 81bbe93640
commit 437770538c

@ -3,8 +3,48 @@
var fs = require('fs'),
path = require('path'),
async = require('async'),
LRU = require('lru-cache'),
_ = require('underscore');
Languages = {};
var plugins = require('./plugins');
var Languages = {};
Languages.init = function(next) {
if (Languages.hasOwnProperty('_cache')) {
Languages._cache.reset();
} else {
Languages._cache = LRU(100);
}
next();
};
Languages.get = function(code, key, callback) {
var combined = [code, key].join('/');
if (Languages._cache.has(combined)) {
return callback(null, Languages._cache.get(combined));
}
var languageData;
fs.readFile(path.join(__dirname, '../public/language/', code, key), { encoding: 'utf-8' }, function(err, data) {
// If language file in core cannot be read, then no language file present
try {
languageData = JSON.parse(data) || {};
} catch (e) {
languageData = {};
}
if (plugins.customLanguages.hasOwnProperty(combined)) {
_.extendOwn(languageData, plugins.customLanguages[combined]);
}
Languages._cache.set(combined, languageData);
callback(null, languageData);
});
};
Languages.list = function(callback) {
var languagesPath = path.join(__dirname, '../public/language'),

@ -8,6 +8,7 @@ var async = require('async'),
user = require('./user'),
groups = require('./groups'),
languages = require('./languages'),
emitter = require('./emitter'),
pubsub = require('./pubsub'),
auth = require('./routes/authentication'),
@ -65,6 +66,7 @@ var async = require('async'),
async.apply(Meta.js.minify, 'nodebb.min.js'),
async.apply(Meta.js.minify, 'acp.min.js'),
async.apply(Meta.sounds.init),
async.apply(languages.init),
async.apply(Meta.templates.compile),
async.apply(auth.reloadRoutes),
function(next) {

@ -16,6 +16,7 @@ var app,
toobusy = require('toobusy-js'),
plugins = require('../plugins'),
languages = require('../languages'),
meta = require('../meta'),
user = require('../user'),
groups = require('../groups'),
@ -314,6 +315,19 @@ middleware.applyBlacklist = function(req, res, next) {
};
middleware.processLanguages = function(req, res, next) {
var code = req.params.code;
var key = req.path.match(/[\w]+\.json/);
if (code && key) {
languages.get(code, key[0], function(err, language) {
res.status(200).json(language);
})
} else {
res.status(404).json('{}');
}
};
middleware.processTimeagoLocales = function(req, res, next) {
var fallback = req.path.indexOf('-short') === -1 ? 'jquery.timeago.en.js' : 'jquery.timeago.en-short.js',
localPath = path.join(__dirname, '../../public/vendor/jquery/timeago/locales', req.path),
exists;

@ -31,7 +31,7 @@ var middleware;
Plugins.lessFiles = [];
Plugins.clientScripts = [];
Plugins.acpScripts = [];
Plugins.customLanguages = [];
Plugins.customLanguages = {};
Plugins.customLanguageFallbacks = {};
Plugins.libraryPaths = [];
Plugins.versionWarning = [];
@ -85,10 +85,10 @@ var middleware;
Plugins.acpScripts.length = 0;
Plugins.libraryPaths.length = 0;
Plugins.registerHook('core', {
hook: 'static:app.load',
method: addLanguages
});
// Plugins.registerHook('core', {
// hook: 'static:app.load',
// method: addLanguages
// });
async.waterfall([
function(next) {
@ -415,27 +415,28 @@ var middleware;
], next);
};
function addLanguages(params, callback) {
Plugins.customLanguages.forEach(function(lang) {
params.router.get('/language' + lang.route, function(req, res, next) {
res.json(lang.file);
});
var components = lang.route.split('/'),
language = components[1],
filename = components[2].replace('.json', '');
translator.addTranslation(language, filename, lang.file);
});
for(var resource in Plugins.customLanguageFallbacks) {
params.router.get('/language/:lang/' + resource + '.json', function(req, res, next) {
winston.verbose('[translator] No resource file found for ' + req.params.lang + '/' + path.basename(req.path, '.json') + ', using provided fallback language file');
res.sendFile(Plugins.customLanguageFallbacks[path.basename(req.path, '.json')]);
});
}
callback(null);
}
// function addLanguages(params, callback) {
// Plugins.customLanguages.forEach(function(lang) {
// console.log('route for', '/language/' + lang.route);
// params.router.get('/language' + lang.route, function(req, res, next) {
// res.json(lang.file);
// });
// var components = lang.route.split('/'),
// language = components[1],
// filename = components[2].replace('.json', '');
// translator.addTranslation(language, filename, lang.file);
// });
// for(var resource in Plugins.customLanguageFallbacks) {
// params.router.get('/language/:lang/' + resource + '.json', function(req, res, next) {
// winston.verbose('[translator] No resource file found for ' + req.params.lang + '/' + path.basename(req.path, '.json') + ', using provided fallback language file');
// res.sendFile(Plugins.customLanguageFallbacks[path.basename(req.path, '.json')]);
// });
// }
// callback(null);
// }
}(exports));

@ -219,26 +219,23 @@ module.exports = function(Plugins) {
fallbackMap = {};
utils.walk(pathToFolder, function(err, languages) {
var arr = [];
async.each(languages, function(pathToLang, next) {
fs.readFile(pathToLang, function(err, file) {
if (err) {
return next(err);
}
var json;
var data;
var route = pathToLang.replace(pathToFolder + '/', '');
try {
json = JSON.parse(file.toString());
data = JSON.parse(file.toString());
} catch (err) {
winston.error('[plugins] Unable to parse custom language file: ' + pathToLang + '\r\n' + err.stack);
return next(err);
}
arr.push({
file: json,
route: pathToLang.replace(pathToFolder, '')
});
Plugins.customLanguages[route] = Plugins.customLanguages[route] || {};
_.extendOwn(Plugins.customLanguages[route], data);
if (pluginData.defaultLang && pathToLang.endsWith(pluginData.defaultLang + '/' + path.basename(pathToLang))) {
fallbackMap[path.basename(pathToLang, '.json')] = path.join(pathToFolder, pluginData.defaultLang, path.basename(pathToLang));
@ -251,7 +248,7 @@ module.exports = function(Plugins) {
return callback(err);
}
Plugins.customLanguages = Plugins.customLanguages.concat(arr);
// do I need this either?
_.extendOwn(Plugins.customLanguageFallbacks, fallbackMap);
callback();

@ -144,10 +144,11 @@ module.exports = function(app, middleware, hotswapIds) {
}
app.use(middleware.privateUploads);
app.use('/language/:code', middleware.processLanguages);
app.use(relativePath, express.static(path.join(__dirname, '../../', 'public'), {
maxAge: app.enabled('cache') ? 5184000000 : 0
}));
app.use('/vendor/jquery/timeago/locales', middleware.processLanguages);
app.use('/vendor/jquery/timeago/locales', middleware.processTimeagoLocales);
app.use(controllers.handle404);
app.use(controllers.handleErrors);

@ -12,6 +12,7 @@ var path = require('path'),
emailer = require('./emailer'),
meta = require('./meta'),
languages = require('./languages'),
logger = require('./logger'),
plugins = require('./plugins'),
middleware = require('./middleware'),
@ -92,6 +93,7 @@ function initializeNodeBB(callback) {
async.apply(!skipJS ? meta.js.minify : meta.js.getFromFile, 'acp.min.js'),
async.apply(meta.css.minify),
async.apply(meta.sounds.init),
async.apply(languages.init),
async.apply(meta.blacklist.load)
], next);
},

Loading…
Cancel
Save