From 05b68391ddacb92719fd19b1013d1d813ce50a40 Mon Sep 17 00:00:00 2001 From: Peter Jaszkowiak Date: Sat, 14 Jan 2017 22:36:10 -0700 Subject: [PATCH 01/11] Use `/assets` for client assets - Route `/assets` -> `build/public`, falling back on `public` - Moved destinations for `nodebb.min.js`, `acp.min.js`, `admin.css`, `stylesheet.css`, `templates`, and `sounds` to `build/public` - r.js modules previously routed through express are now symlinked into `public/build/src/modules` - minfiles no longer served from a memory cache - use config `views_dir` setting everywhere template directory is used - fix cache buster `v=v=` --- .eslintignore | 1 + app.js | 2 +- build.js | 1 + public/src/ajaxify.js | 2 +- public/src/app.js | 4 +- public/src/client/account/header.js | 2 +- public/src/modules/translator.js | 4 +- public/src/require-config.js | 2 +- public/src/widgets.js | 2 +- src/admin/search.js | 5 +- src/controllers/admin/settings.js | 3 +- src/controllers/admin/uploads.js | 2 +- src/coverPhoto.js | 2 +- src/meta/css.js | 24 +------- src/meta/js.js | 86 +++++++++------------------- src/meta/sounds.js | 4 +- src/meta/themes.js | 2 +- src/middleware/admin.js | 2 +- src/middleware/header.js | 2 +- src/routes/index.js | 38 ++++++++++-- src/routes/meta.js | 30 ---------- src/views/admin/header.tpl | 26 ++++----- src/views/admin/settings/group.tpl | 2 +- src/views/admin/settings/uploads.tpl | 2 +- src/webserver.js | 4 -- src/widgets/admin.js | 3 +- test/mocks/databasemock.js | 2 +- 27 files changed, 101 insertions(+), 158 deletions(-) diff --git a/.eslintignore b/.eslintignore index 0799652254..250640f954 100644 --- a/.eslintignore +++ b/.eslintignore @@ -18,3 +18,4 @@ logs/ *.ipr *.iws /coverage +/build diff --git a/app.js b/app.js index b6d7d07829..55cc0dbecf 100644 --- a/app.js +++ b/app.js @@ -99,7 +99,7 @@ function loadConfig(callback) { nconf.defaults({ base_dir: __dirname, themes_path: path.join(__dirname, 'node_modules'), - views_dir: path.join(__dirname, 'public/templates'), + views_dir: path.join(__dirname, 'build/public/templates'), version: pkg.version }); diff --git a/build.js b/build.js index a0250dfb37..32359e14f8 100644 --- a/build.js +++ b/build.js @@ -57,6 +57,7 @@ exports.buildTargets = function (targets, callback) { winston.info('[build] Building javascript'); var startTime = Date.now(); async.series([ + meta.js.linkModules, async.apply(meta.js.minify, 'nodebb.min.js'), async.apply(meta.js.minify, 'acp.min.js') ], step.bind(this, startTime, 'js', next)); diff --git a/public/src/ajaxify.js b/public/src/ajaxify.js index 2e895f380b..7eb46343e5 100644 --- a/public/src/ajaxify.js +++ b/public/src/ajaxify.js @@ -338,7 +338,7 @@ $(document).ready(function () { callback(templates.cache[template]); } else { $.ajax({ - url: RELATIVE_PATH + '/templates/' + template + '.tpl' + (config['cache-buster'] ? '?v=' + config['cache-buster'] : ''), + url: config.relative_path + '/assets/templates/' + template + '.tpl' + '?' + config['cache-buster'], type: 'GET', success: function (data) { callback(data.toString()); diff --git a/public/src/app.js b/public/src/app.js index fe12a7adfc..00d5e7c017 100644 --- a/public/src/app.js +++ b/public/src/app.js @@ -558,7 +558,7 @@ app.cacheBuster = null; var scriptEl = document.createElement('script'); scriptEl.type = 'text/javascript'; - scriptEl.src = config.relative_path + '/vendor/jquery/js/jquery-ui.js' + (app.cacheBuster ? '?v=' + app.cacheBuster : ''); + scriptEl.src = config.relative_path + '/vendor/jquery/js/jquery-ui.js' + '?' + config['cache-buster']; scriptEl.onload = callback; document.head.appendChild(scriptEl); }; @@ -625,7 +625,7 @@ app.cacheBuster = null; app.loadProgressiveStylesheet = function () { var linkEl = document.createElement('link'); linkEl.rel = 'stylesheet'; - linkEl.href = config.relative_path + '/js-enabled.css'; + linkEl.href = config.relative_path + '/assets/js-enabled.css'; document.head.appendChild(linkEl); }; diff --git a/public/src/client/account/header.js b/public/src/client/account/header.js index e99b7ee0a8..d0f84ade3a 100644 --- a/public/src/client/account/header.js +++ b/public/src/client/account/header.js @@ -84,7 +84,7 @@ define('forum/account/header', [ params: {uid: ajaxify.data.uid }, accept: '.png,.jpg,.bmp' }, function (imageUrlOnServer) { - components.get('account/cover').css('background-image', 'url(' + imageUrlOnServer + '?v=' + Date.now() + ')'); + components.get('account/cover').css('background-image', 'url(' + imageUrlOnServer + '?' + config['cache-buster'] + ')'); }); }, removeCover diff --git a/public/src/modules/translator.js b/public/src/modules/translator.js index eac467f413..ff2aa53bb0 100644 --- a/public/src/modules/translator.js +++ b/public/src/modules/translator.js @@ -513,12 +513,12 @@ break; } - jQuery.getScript(config.relative_path + '/vendor/jquery/timeago/locales/jquery.timeago.' + languageCode + '.js').done(function () { + jQuery.getScript(config.relative_path + '/assets/vendor/jquery/timeago/locales/jquery.timeago.' + languageCode + '.js').done(function () { jQuery('.timeago').timeago(); adaptor.timeagoShort = assign({}, jQuery.timeago.settings.strings); // Retrieve the shorthand timeago values as well - jQuery.getScript(config.relative_path + '/vendor/jquery/timeago/locales/jquery.timeago.' + languageCode + '-short.js').done(function () { + jQuery.getScript(config.relative_path + '/assets/vendor/jquery/timeago/locales/jquery.timeago.' + languageCode + '-short.js').done(function () { // Switch back to long-form adaptor.toggleTimeagoShorthand(); }); diff --git a/public/src/require-config.js b/public/src/require-config.js index 8618685052..0e021f6be0 100644 --- a/public/src/require-config.js +++ b/public/src/require-config.js @@ -1,5 +1,5 @@ require.config({ - baseUrl: config.relative_path + "/src/modules", + baseUrl: config.relative_path + '/assets/src/modules', waitSeconds: 7, urlArgs: config['cache-buster'], paths: { diff --git a/public/src/widgets.js b/public/src/widgets.js index 46023fad15..377ccb2c53 100644 --- a/public/src/widgets.js +++ b/public/src/widgets.js @@ -29,7 +29,7 @@ } }); - $.get(config.relative_path + '/api/widgets/render' + (config['cache-buster'] ? '?v=' + config['cache-buster'] : ''), { + $.get(config.relative_path + '/api/widgets/render' + '?' + config['cache-buster'], { locations: widgetLocations, template: template + '.tpl', url: url, diff --git a/src/admin/search.js b/src/admin/search.js index 860c527e6b..4c53815e48 100644 --- a/src/admin/search.js +++ b/src/admin/search.js @@ -4,6 +4,7 @@ var fs = require('fs'); var path = require('path'); var async = require('async'); var sanitizeHTML = require('sanitize-html'); +var nconf = require('nconf'); var utils = require('../../public/src/utils'); var Translator = require('../../public/src/modules/translator').Translator; @@ -23,7 +24,7 @@ function filterDirectories(directories) { } function getAdminNamespaces(callback) { - utils.walk(path.resolve(__dirname, '../../public/templates/admin'), function (err, directories) { + utils.walk(path.resolve(nconf.get('views_dir'), 'admin'), function (err, directories) { if (err) { return callback(err); } @@ -60,7 +61,7 @@ var fallbackCacheInProgress = {}; var fallbackCache = {}; function initFallback(namespace, callback) { - fs.readFile(path.resolve(__dirname, '../../public/templates/', namespace + '.tpl'), function (err, file) { + fs.readFile(path.resolve(nconf.get('views_dir'), namespace + '.tpl'), function (err, file) { if (err) { return callback(err); } diff --git a/src/controllers/admin/settings.js b/src/controllers/admin/settings.js index 639267f5f5..0d1f509631 100644 --- a/src/controllers/admin/settings.js +++ b/src/controllers/admin/settings.js @@ -2,6 +2,7 @@ var async = require('async'); +var nconf = require('nconf'); var meta = require('../../meta'); var settingsController = module.exports; @@ -25,7 +26,7 @@ function renderEmail(req, res, next) { var path = require('path'); var utils = require('../../../public/src/utils'); - var emailsPath = path.join(__dirname, '../../../public/templates/emails'); + var emailsPath = path.join(nconf.get('views_dir'), 'emails'); async.waterfall([ function (next) { diff --git a/src/controllers/admin/uploads.js b/src/controllers/admin/uploads.js index d1664cb8f1..2b1a60e281 100644 --- a/src/controllers/admin/uploads.js +++ b/src/controllers/admin/uploads.js @@ -105,7 +105,7 @@ uploadsController.uploadSound = function (req, res, next) { return next(err); } - var soundsPath = path.join(__dirname, '../../../public/sounds'), + var soundsPath = path.join(__dirname, '../../../build/public/sounds'), filePath = path.join(__dirname, '../../../public/uploads/sounds', uploadedFile.name); if (process.platform === 'win32') { diff --git a/src/coverPhoto.js b/src/coverPhoto.js index 699e4ee374..9380b347f4 100644 --- a/src/coverPhoto.js +++ b/src/coverPhoto.js @@ -26,7 +26,7 @@ function getCover(type, id) { return covers[id]; } - return nconf.get('relative_path') + '/images/cover-default.png'; + return nconf.get('relative_path') + '/assets/images/cover-default.png'; } module.exports = coverPhoto; \ No newline at end of file diff --git a/src/meta/css.js b/src/meta/css.js index 0d63e09d6d..f72ef6004d 100644 --- a/src/meta/css.js +++ b/src/meta/css.js @@ -86,15 +86,6 @@ module.exports = function (Meta) { }); }; - Meta.css.getFromFile = function (callback) { - async.series([ - async.apply(Meta.css.loadFile, path.join(__dirname, '../../public/stylesheet.css'), 'cache'), - async.apply(Meta.css.loadFile, path.join(__dirname, '../../public/admin.css'), 'acpCache') - ], function (err) { - callback(err); - }); - }; - function getStyleSource(files, prefix, extension, callback) { var pluginDirectories = [], source = ''; @@ -127,7 +118,7 @@ module.exports = function (Meta) { Meta.css.commitToFile = function (filename, callback) { var file = (filename === 'acpCache' ? 'admin' : 'stylesheet') + '.css'; - fs.writeFile(path.join(__dirname, '../../public/' + file), Meta.css[filename], function (err) { + fs.writeFile(path.join(__dirname, '../../build/public/' + file), Meta.css[filename], function (err) { if (!err) { winston.verbose('[meta/css] ' + file + ' committed to disk.'); } else { @@ -139,19 +130,6 @@ module.exports = function (Meta) { }); }; - Meta.css.loadFile = function (filePath, filename, callback) { - winston.verbose('[meta/css] Reading stylesheet ' + filePath.split('/').pop() + ' from file'); - - fs.readFile(filePath, function (err, file) { - if (err) { - return callback(err); - } - - Meta.css[filename] = file; - callback(); - }); - }; - function minify(source, paths, destination, callback) { callback = callback || function () {}; less.render(source, { diff --git a/src/meta/js.js b/src/meta/js.js index 7f39235993..8c3794043f 100644 --- a/src/meta/js.js +++ b/src/meta/js.js @@ -6,6 +6,7 @@ var path = require('path'); var async = require('async'); var nconf = require('nconf'); var fs = require('fs'); +var mkdirp = require('mkdirp'); var plugins = require('../plugins'); var utils = require('../../public/src/utils'); @@ -85,30 +86,34 @@ module.exports = function (Meta) { } } }; - - Meta.js.bridgeModules = function (app, callback) { - // Add routes for AMD-type modules to serve those files - function addRoute(relPath) { - var relativePath = nconf.get('relative_path'); - - app.get(relativePath + '/src/modules/' + relPath, function (req, res) { - return res.sendFile(path.join(__dirname, '../../', Meta.js.scripts.modules[relPath]), { - maxAge: app.enabled('cache') ? 5184000000 : 0 - }); - }); - } - - var numBridged = 0; - - for(var relPath in Meta.js.scripts.modules) { - if (Meta.js.scripts.modules.hasOwnProperty(relPath)) { - addRoute(relPath); - ++numBridged; + + Meta.js.linkModules = function (callback) { + function link(filePath, destPath, cb) { + if (process.platform === 'win32') { + fs.link(filePath, destPath, cb); + } else { + fs.symlink(filePath, destPath, 'file', cb); } } - winston.verbose('[meta/js] ' + numBridged + ' of ' + Object.keys(Meta.js.scripts.modules).length + ' modules bridged'); - callback(); + plugins.reload(function (err) { + if (err) { + return callback(err); + } + + async.each(Object.keys(Meta.js.scripts.modules), function (relPath, next) { + var filePath = path.join(__dirname, '../../', Meta.js.scripts.modules[relPath]); + var destPath = path.join(__dirname, '../../build/public/src/modules', relPath); + + mkdirp(path.dirname(destPath), function (err) { + if (err) { + return next(err); + } + + link(filePath, destPath, next); + }); + }, callback); + }); }; Meta.js.minify = function (target, callback) { @@ -202,48 +207,11 @@ module.exports = function (Meta) { }; Meta.js.commitToFile = function (target, callback) { - fs.writeFile(path.join(__dirname, '../../public/' + target), Meta.js.target[target].cache, function (err) { + fs.writeFile(path.join(__dirname, '../../build/public/' + target), Meta.js.target[target].cache, function (err) { callback(err); }); }; - Meta.js.getFromFile = function (target, callback) { - function readFile(filePath, next) { - fs.readFile(filePath, function (err, contents) { - if (err) { - if (err.code === 'ENOENT') { - if (!filePath.endsWith('.map')) { - winston.warn('[meta/js] ' + filePath + ' not found on disk, did you run ./nodebb build?'); - } - return next(null, ''); - } - } - next(err, contents); - }); - } - - var scriptPath = path.join(nconf.get('base_dir'), 'public/' + target); - var mapPath = path.join(nconf.get('base_dir'), 'public/' + target + '.map'); - - async.parallel({ - script: function (next) { - readFile(scriptPath, next); - }, - map: function (next) { - readFile(mapPath, next); - } - }, function (err, results) { - if (err) { - return callback(err); - } - Meta.js.target[target] = { - cache: results.script, - map: results.map - }; - callback(); - }); - }; - function setupDebugging() { /** * Check if the parent process is running with the debug option --debug (or --debug-brk) diff --git a/src/meta/sounds.js b/src/meta/sounds.js index 6068f16f5f..6acbd77a1f 100644 --- a/src/meta/sounds.js +++ b/src/meta/sounds.js @@ -28,7 +28,7 @@ module.exports = function (Meta) { Meta.sounds.getFiles = function (callback) { async.waterfall([ function (next) { - fs.readdir(path.join(__dirname, '../../public/sounds'), next); + fs.readdir(path.join(__dirname, '../../build/public/sounds'), next); }, function (sounds, next) { fs.readdir(path.join(__dirname, '../../public/uploads/sounds'), function (err, uploaded) { @@ -88,7 +88,7 @@ module.exports = function (Meta) { }; function setupSounds(callback) { - var soundsPath = path.join(__dirname, '../../public/sounds'); + var soundsPath = path.join(__dirname, '../../build/public/sounds'); async.waterfall([ function (next) { diff --git a/src/meta/themes.js b/src/meta/themes.js index be48d1e70d..e19dcdbf4c 100644 --- a/src/meta/themes.js +++ b/src/meta/themes.js @@ -48,7 +48,7 @@ module.exports = function (Meta) { if (configObj.screenshot) { configObj.screenshot_url = nconf.get('relative_path') + '/css/previews/' + configObj.id; } else { - configObj.screenshot_url = nconf.get('relative_path') + '/images/themes/default.png'; + configObj.screenshot_url = nconf.get('relative_path') + '/assets/images/themes/default.png'; } next(null, configObj); } catch (err) { diff --git a/src/middleware/admin.js b/src/middleware/admin.js index 3240eaf0af..9d4b43bf25 100644 --- a/src/middleware/admin.js +++ b/src/middleware/admin.js @@ -101,7 +101,7 @@ module.exports = function (middleware) { plugins: results.custom_header.plugins, authentication: results.custom_header.authentication, scripts: results.scripts, - 'cache-buster': meta.config['cache-buster'] ? 'v=' + meta.config['cache-buster'] : '', + 'cache-buster': meta.config['cache-buster'] || '', env: process.env.NODE_ENV ? true : false, title: (acpPath || 'Dashboard') + ' | NodeBB Admin Control Panel', bodyClass: data.bodyClass diff --git a/src/middleware/header.js b/src/middleware/header.js index c1b4175b5b..5e78416a0a 100644 --- a/src/middleware/header.js +++ b/src/middleware/header.js @@ -46,7 +46,7 @@ module.exports = function (middleware) { bootswatchCSS: meta.config['theme:src'], title: meta.config.title || '', description: meta.config.description || '', - 'cache-buster': meta.config['cache-buster'] ? 'v=' + meta.config['cache-buster'] : '', + 'cache-buster': meta.config['cache-buster'] || '', 'brand:logo': meta.config['brand:logo'] || '', 'brand:logo:url': meta.config['brand:logo:url'] || '', 'brand:logo:alt': meta.config['brand:logo:alt'] || '', diff --git a/src/routes/index.js b/src/routes/index.js index 158774b624..e1f95891cf 100644 --- a/src/routes/index.js +++ b/src/routes/index.js @@ -145,21 +145,47 @@ module.exports = function (app, middleware, hotswapIds) { } app.use(middleware.privateUploads); - app.use(relativePath + '/assets', express.static(path.join(__dirname, '../../', 'build/public'), { + + app.use(relativePath + '/assets', express.static(path.join(__dirname, '../../build/public'), { + maxAge: app.enabled('cache') ? 5184000000 : 0 + })); + app.use(relativePath + '/assets', express.static(path.join(__dirname, '../../public'), { maxAge: app.enabled('cache') ? 5184000000 : 0 })); + // DEPRECATED + var deprecatedPaths = [ + '/nodebb.min.js', + '/acp.min.js', + '/stylesheet.css', + '/js-enabled.css', + '/admin.css', + '/logo.png', + '/favicon.ico', + '/vendor/', + '/uploads/', + '/templates/', + '/src/', + '/images/', + // '/sounds/', + ]; + app.use(relativePath, function (req, res, next) { + if (deprecatedPaths.some(function (path) { return req.path.startsWith(path); })) { + winston.warn('[deprecated] Accessing `' + req.path.slice(1) + '` from `/` is deprecated. ' + + 'Use `/assets' + req.path + '` to access this file.'); + res.redirect(relativePath + '/assets' + req.path + '?' + meta.config['cache-buster']); + } else { + next(); + } + }); // DEPRECATED app.use(relativePath + '/api/language', function (req, res) { winston.warn('[deprecated] Accessing language files from `/api/language` is deprecated. ' + - 'Use `/assets/language/[langCode]/[namespace].json` for prefetch paths.'); + 'Use `/assets/language' + req.path + '.json` for prefetch paths.'); res.redirect(relativePath + '/assets/language' + req.path + '.json?' + meta.config['cache-buster']); }); - app.use(relativePath, express.static(path.join(__dirname, '../../', 'public'), { - maxAge: app.enabled('cache') ? 5184000000 : 0 - })); - app.use(relativePath + '/vendor/jquery/timeago/locales', middleware.processTimeagoLocales); + app.use(relativePath + '/assets/vendor/jquery/timeago/locales', middleware.processTimeagoLocales); app.use(controllers.handle404); app.use(controllers.handleURIErrors); app.use(controllers.handleErrors); diff --git a/src/routes/meta.js b/src/routes/meta.js index c62465c8d0..af4e89d897 100644 --- a/src/routes/meta.js +++ b/src/routes/meta.js @@ -5,31 +5,6 @@ var nconf = require('nconf'); var meta = require('../meta'); - -function sendMinifiedJS(req, res) { - var target = path.basename(req.path); - var cache = meta.js.target[target] ? meta.js.target[target].cache : ''; - res.type('text/javascript').send(cache); -} - -// The portions of code involving the source map are commented out as they're broken in UglifyJS2 -// Follow along here: https://github.com/mishoo/UglifyJS2/issues/700 -// function sendJSSourceMap(req, res) { -// if (meta.js.hasOwnProperty('map')) { -// res.type('application/json').send(meta.js.map); -// } else { -// res.redirect(404); -// } -// }; - -function sendStylesheet(req, res) { - res.type('text/css').status(200).send(meta.css.cache); -} - -function sendACPStylesheet(req, res) { - res.type('text/css').status(200).send(meta.css.acpCache); -} - function sendSoundFile(req, res, next) { var resolved = meta.sounds._filePathHash[path.basename(req.path)]; @@ -41,11 +16,6 @@ function sendSoundFile(req, res, next) { } module.exports = function (app, middleware, controllers) { - app.get('/stylesheet.css', middleware.addExpiresHeaders, sendStylesheet); - app.get('/admin.css', middleware.addExpiresHeaders, sendACPStylesheet); - app.get('/nodebb.min.js', middleware.addExpiresHeaders, sendMinifiedJS); - app.get('/acp.min.js', middleware.addExpiresHeaders, sendMinifiedJS); - // app.get('/nodebb.min.js.map', middleware.addExpiresHeaders, sendJSSourceMap); app.get('/sitemap.xml', controllers.sitemap.render); app.get('/sitemap/pages.xml', controllers.sitemap.getPages); app.get('/sitemap/categories.xml', controllers.sitemap.getCategories); diff --git a/src/views/admin/header.tpl b/src/views/admin/header.tpl index e6e92490f9..23ce1e2c02 100644 --- a/src/views/admin/header.tpl +++ b/src/views/admin/header.tpl @@ -4,8 +4,8 @@ {title} - - + + - - - - - - - - - - - + + + + + + + + + + + diff --git a/src/views/admin/settings/group.tpl b/src/views/admin/settings/group.tpl index 56a8b2c18e..1c0b660361 100644 --- a/src/views/admin/settings/group.tpl +++ b/src/views/admin/settings/group.tpl @@ -43,7 +43,7 @@

[[admin/settings/group:default-cover-help]]

-
+
diff --git a/src/views/admin/settings/uploads.tpl b/src/views/admin/settings/uploads.tpl index 2e79da9a2b..6c9b59db80 100644 --- a/src/views/admin/settings/uploads.tpl +++ b/src/views/admin/settings/uploads.tpl @@ -131,7 +131,7 @@

[[admin/settings/uploads:default-covers-help]]

- + diff --git a/src/webserver.js b/src/webserver.js index fec42974c6..2e7afdb228 100644 --- a/src/webserver.js +++ b/src/webserver.js @@ -88,7 +88,6 @@ function initializeNodeBB(callback) { plugins.init(app, middleware, next); }, async.apply(plugins.fireHook, 'static:assets.prepare', {}), - async.apply(meta.js.bridgeModules, app), function (next) { plugins.fireHook('static:app.preload', { app: app, @@ -104,9 +103,6 @@ function initializeNodeBB(callback) { }, function (next) { async.series([ - async.apply(meta.js.getFromFile, 'nodebb.min.js'), - async.apply(meta.js.getFromFile, 'acp.min.js'), - async.apply(meta.css.getFromFile), async.apply(meta.sounds.init), async.apply(languages.init), async.apply(meta.blacklist.load) diff --git a/src/widgets/admin.js b/src/widgets/admin.js index fc380804c6..ecfd73b750 100644 --- a/src/widgets/admin.js +++ b/src/widgets/admin.js @@ -3,6 +3,7 @@ var fs = require('fs'); var path = require('path'); var async = require('async'); +var nconf = require('nconf'); var plugins = require('../plugins'); var admin = {}; @@ -25,7 +26,7 @@ admin.get = function (callback) { plugins.fireHook('filter:widgets.getWidgets', [], next); }, adminTemplate: function (next) { - fs.readFile(path.resolve(__dirname, '../../public/templates/admin/partials/widget-settings.tpl'), 'utf8', next); + fs.readFile(path.resolve(nconf.get('views_dir'), 'admin/partials/widget-settings.tpl'), 'utf8', next); } }, function (err, widgetData) { if (err) { diff --git a/test/mocks/databasemock.js b/test/mocks/databasemock.js index 44de8c7122..182d9fea12 100644 --- a/test/mocks/databasemock.js +++ b/test/mocks/databasemock.js @@ -20,7 +20,7 @@ base_dir: path.join(__dirname,'../..'), themes_path: path.join(__dirname, '../../node_modules'), upload_url: path.join(path.sep, '../../uploads', path.sep), - views_dir: path.join(__dirname, '../../public/templates'), + views_dir: path.join(__dirname, '../../build/public/templates'), relative_path: '' }); From 8c86b2e32c9ebac4e9bbbfe2b8cb95e9d5e01f9c Mon Sep 17 00:00:00 2001 From: Peter Jaszkowiak Date: Sun, 15 Jan 2017 12:38:16 -0700 Subject: [PATCH 02/11] Build pipeline improvements - Refactor meta/css - `fs.link` usage consolidated to `file.link` - rimraf built modules directory to fix error - Remove `local-assets` flag --- build.js | 10 ++- src/controllers/admin/uploads.js | 6 +- src/file.js | 8 +++ src/meta/css.js | 102 +++++++++++++++---------------- src/meta/js.js | 24 ++------ src/meta/sounds.js | 22 +------ src/plugins/load.js | 3 +- src/routes/index.js | 3 +- src/routes/meta.js | 19 ------ src/webserver.js | 2 +- 10 files changed, 78 insertions(+), 121 deletions(-) diff --git a/build.js b/build.js index 32359e14f8..a8ad5007d1 100644 --- a/build.js +++ b/build.js @@ -46,7 +46,11 @@ exports.buildTargets = function (targets, callback) { var meta = require('./src/meta'); buildStart = buildStart || Date.now(); - var step = function (startTime, target, next) { + var step = function (startTime, target, next, err) { + if (err) { + winston.error('Build failed: ' + err.message); + process.exit(1); + } winston.info('[build] ' + target + ' => Completed in ' + ((Date.now() - startTime) / 1000) + 's'); next(); }; @@ -75,13 +79,13 @@ exports.buildTargets = function (targets, callback) { case 'clientCSS': winston.info('[build] Building client-side CSS'); startTime = Date.now(); - meta.css.minify('stylesheet.css', step.bind(this, startTime, target, next)); + meta.css.minify('client', step.bind(this, startTime, target, next)); break; case 'acpCSS': winston.info('[build] Building admin control panel CSS'); startTime = Date.now(); - meta.css.minify('admin.css', step.bind(this, startTime, target, next)); + meta.css.minify('admin', step.bind(this, startTime, target, next)); break; case 'tpl': diff --git a/src/controllers/admin/uploads.js b/src/controllers/admin/uploads.js index 2b1a60e281..25b2ae34fd 100644 --- a/src/controllers/admin/uploads.js +++ b/src/controllers/admin/uploads.js @@ -108,11 +108,7 @@ uploadsController.uploadSound = function (req, res, next) { var soundsPath = path.join(__dirname, '../../../build/public/sounds'), filePath = path.join(__dirname, '../../../public/uploads/sounds', uploadedFile.name); - if (process.platform === 'win32') { - fs.link(filePath, path.join(soundsPath, path.basename(filePath))); - } else { - fs.symlink(filePath, path.join(soundsPath, path.basename(filePath)), 'file'); - } + file.link(filePath, path.join(soundsPath, path.basename(filePath))); fs.unlink(uploadedFile.path, function (err) { if (err) { diff --git a/src/file.js b/src/file.js index df820cc47f..65f86a0bdd 100644 --- a/src/file.js +++ b/src/file.js @@ -102,4 +102,12 @@ file.existsSync = function (path) { return !!exists; }; +file.link = function link(filePath, destPath, cb) { + if (process.platform === 'win32') { + fs.link(filePath, destPath, cb); + } else { + fs.symlink(filePath, destPath, 'file', cb); + } +}; + module.exports = file; diff --git a/src/meta/css.js b/src/meta/css.js index f72ef6004d..d779ff8018 100644 --- a/src/meta/css.js +++ b/src/meta/css.js @@ -18,8 +18,32 @@ var utils = require('../../public/src/utils'); module.exports = function (Meta) { Meta.css = {}; - Meta.css.cache = undefined; - Meta.css.acpCache = undefined; + + var buildImports = { + client: function (source) { + return '@import "./theme";\n' + source + '\n' + [ + '@import "font-awesome";', + '@import (inline) "../../public/vendor/jquery/css/smoothness/jquery-ui.css";', + '@import (inline) "../../public/vendor/jquery/bootstrap-tagsinput/bootstrap-tagsinput.css";', + '@import (inline) "..' + path.sep + 'public/vendor/colorpicker/colorpicker.css";', + '@import "../../public/less/flags.less";', + '@import "../../public/less/blacklist.less";', + '@import "../../public/less/generics.less";', + '@import "../../public/less/mixins.less";', + '@import "../../public/less/global.less";', + ].map(function (str) { return str.replace(/\//g, path.sep); }).join('\n'); + }, + admin: function (source) { + return source + '\n' + [ + '@import "font-awesome";', + '@import "../public/less/admin/admin";', + '@import "../public/less/generics.less";', + '@import (inline) "../public/vendor/colorpicker/colorpicker.css";', + '@import (inline) "../public/vendor/jquery/css/smoothness/jquery-ui.css";', + '@import (inline) "../public/vendor/jquery/bootstrap-tagsinput/bootstrap-tagsinput.css";', + ].map(function (str) { return str.replace(/\//g, path.sep); }).join('\n'); + }, + }; Meta.css.minify = function (target, callback) { callback = callback || function () {}; @@ -30,25 +54,25 @@ module.exports = function (Meta) { return callback(err); } - var themeId = (themeData['theme:id'] || 'nodebb-theme-persona'), - baseThemePath = path.join(nconf.get('themes_path'), (themeData['theme:type'] && themeData['theme:type'] === 'local' ? themeId : 'nodebb-theme-vanilla')), - paths = [ - baseThemePath, - path.join(__dirname, '../../node_modules'), - path.join(__dirname, '../../public/vendor/fontawesome/less') - ], - source = '@import "font-awesome";'; + var themeId = (themeData['theme:id'] || 'nodebb-theme-persona'); + var baseThemePath = path.join(nconf.get('themes_path'), (themeData['theme:type'] && themeData['theme:type'] === 'local' ? themeId : 'nodebb-theme-vanilla')); + var paths = [ + baseThemePath, + path.join(__dirname, '../../node_modules'), + path.join(__dirname, '../../public/vendor/fontawesome/less') + ]; + var source = ''; - plugins.lessFiles = filterMissingFiles(plugins.lessFiles); - plugins.cssFiles = filterMissingFiles(plugins.cssFiles); + var lessFiles = filterMissingFiles(plugins.lessFiles); + var cssFiles = filterMissingFiles(plugins.cssFiles); async.waterfall([ function (next) { - getStyleSource(plugins.cssFiles, '\n@import (inline) ".', '.css', next); + getStyleSource(cssFiles, '\n@import (inline) ".', '.css', next); }, function (src, next) { source += src; - getStyleSource(plugins.lessFiles, '\n@import ".', '.less', next); + getStyleSource(lessFiles, '\n@import ".', '.less', next); }, function (src, next) { source += src; @@ -59,29 +83,7 @@ module.exports = function (Meta) { return callback(err); } - var acpSource = source; - - if (target !== 'admin.css') { - source += '\n@import (inline) "..' + path.sep + '..' + path.sep + 'public/vendor/jquery/css/smoothness/jquery-ui.css";'; - source += '\n@import (inline) "..' + path.sep + '..' + path.sep + 'public/vendor/jquery/bootstrap-tagsinput/bootstrap-tagsinput.css";'; - source += '\n@import (inline) "..' + path.sep + 'public/vendor/colorpicker/colorpicker.css";'; - source += '\n@import "..' + path.sep + '..' + path.sep + 'public/less/flags.less";'; - source += '\n@import "..' + path.sep + '..' + path.sep + 'public/less/blacklist.less";'; - source += '\n@import "..' + path.sep + '..' + path.sep + 'public/less/generics.less";'; - source += '\n@import "..' + path.sep + '..' + path.sep + 'public/less/mixins.less";'; - source += '\n@import "..' + path.sep + '..' + path.sep + 'public/less/global.less";'; - source = '@import "./theme";\n' + source; - - minify(source, paths, 'cache', callback); - } else { - acpSource += '\n@import "..' + path.sep + 'public/less/admin/admin";\n'; - acpSource += '\n@import "..' + path.sep + 'public/less/generics.less";\n'; - acpSource += '\n@import (inline) "..' + path.sep + 'public/vendor/colorpicker/colorpicker.css";\n'; - acpSource += '\n@import (inline) "..' + path.sep + 'public/vendor/jquery/css/smoothness/jquery-ui.css";'; - acpSource += '\n@import (inline) "..' + path.sep + 'public/vendor/jquery/bootstrap-tagsinput/bootstrap-tagsinput.css";'; - - minify(acpSource, paths, 'acpCache', callback); - } + minify(buildImports[target](source), paths, target, callback); }); }); }; @@ -115,22 +117,22 @@ module.exports = function (Meta) { }); } - Meta.css.commitToFile = function (filename, callback) { - var file = (filename === 'acpCache' ? 'admin' : 'stylesheet') + '.css'; + Meta.css.commitToFile = function (target, source, callback) { + var filename = (target === 'client' ? 'stylesheet' : 'admin') + '.css'; - fs.writeFile(path.join(__dirname, '../../build/public/' + file), Meta.css[filename], function (err) { + fs.writeFile(path.join(__dirname, '../../build/public/' + filename), source, function (err) { if (!err) { - winston.verbose('[meta/css] ' + file + ' committed to disk.'); + winston.verbose('[meta/css] ' + target + ' CSS committed to disk.'); } else { winston.error('[meta/css] ' + err.message); - process.exit(0); + process.exit(1); } callback(); }); }; - function minify(source, paths, destination, callback) { + function minify(source, paths, target, callback) { callback = callback || function () {}; less.render(source, { paths: paths @@ -140,20 +142,14 @@ module.exports = function (Meta) { return callback(err); } - postcss([ autoprefixer, clean() ]).process(lessOutput.css).then(function (result) { + postcss(global.env === 'development' ? [ autoprefixer ] : [ autoprefixer, clean() ]).process(lessOutput.css).then(function (result) { result.warnings().forEach(function (warn) { winston.verbose(warn.toString()); }); - Meta.css[destination] = result.css; - // Save the compiled CSS in public/ so things like nginx can serve it - if (nconf.get('local-assets') === undefined || nconf.get('local-assets') !== false) { - return Meta.css.commitToFile(destination, function () { - callback(null, result.css); - }); - } - - callback(null, result.css); + return Meta.css.commitToFile(target, result.css, function () { + callback(null, result.css); + }); }); }); } diff --git a/src/meta/js.js b/src/meta/js.js index 8c3794043f..d479e9161c 100644 --- a/src/meta/js.js +++ b/src/meta/js.js @@ -4,9 +4,11 @@ var winston = require('winston'); var fork = require('child_process').fork; var path = require('path'); var async = require('async'); -var nconf = require('nconf'); var fs = require('fs'); var mkdirp = require('mkdirp'); +var rimraf = require('rimraf'); + +var file = require('../file'); var plugins = require('../plugins'); var utils = require('../../public/src/utils'); @@ -88,19 +90,10 @@ module.exports = function (Meta) { }; Meta.js.linkModules = function (callback) { - function link(filePath, destPath, cb) { - if (process.platform === 'win32') { - fs.link(filePath, destPath, cb); - } else { - fs.symlink(filePath, destPath, 'file', cb); - } - } - - plugins.reload(function (err) { + rimraf(path.join(__dirname, '../../build/public/src/modules'), function (err) { if (err) { return callback(err); } - async.each(Object.keys(Meta.js.scripts.modules), function (relPath, next) { var filePath = path.join(__dirname, '../../', Meta.js.scripts.modules[relPath]); var destPath = path.join(__dirname, '../../build/public/src/modules', relPath); @@ -110,7 +103,7 @@ module.exports = function (Meta) { return next(err); } - link(filePath, destPath, next); + file.link(filePath, destPath, next); }); }, callback); }); @@ -143,12 +136,7 @@ module.exports = function (Meta) { winston.verbose('[meta/js] ' + target + ' minification complete'); minifier.kill(); - if (nconf.get('local-assets') === undefined || nconf.get('local-assets') !== false) { - return Meta.js.commitToFile(target, callback); - } else { - return callback(); - } - + Meta.js.commitToFile(target, callback); break; case 'error': winston.error('[meta/js] Could not compile ' + target + ': ' + message.message); diff --git a/src/meta/sounds.js b/src/meta/sounds.js index 6acbd77a1f..e44f43cccc 100644 --- a/src/meta/sounds.js +++ b/src/meta/sounds.js @@ -8,6 +8,7 @@ var rimraf = require('rimraf'); var mkdirp = require('mkdirp'); var async = require('async'); +var file = require('../file'); var plugins = require('../plugins'); var db = require('../database'); @@ -107,21 +108,6 @@ module.exports = function (Meta) { return; } - if (nconf.get('local-assets') === false) { - // Don't regenerate the public/sounds/ directory. Instead, create a mapping for the router to use - Meta.sounds._filePathHash = filePaths.reduce(function (hash, filePath) { - hash[path.basename(filePath)] = filePath; - return hash; - }, {}); - - winston.verbose('[sounds] Sounds OK'); - if (typeof next === 'function') { - return next(); - } else { - return; - } - } - // Clear the sounds directory async.series([ function (next) { @@ -138,11 +124,7 @@ module.exports = function (Meta) { // Link paths async.each(filePaths, function (filePath, next) { - if (process.platform === 'win32') { - fs.link(filePath, path.join(soundsPath, path.basename(filePath)), next); - } else { - fs.symlink(filePath, path.join(soundsPath, path.basename(filePath)), 'file', next); - } + file.link(filePath, path.join(soundsPath, path.basename(filePath)), next); }, function (err) { if (!err) { winston.verbose('[sounds] Sounds OK'); diff --git a/src/plugins/load.js b/src/plugins/load.js index 3121f8457e..cf6e0b4780 100644 --- a/src/plugins/load.js +++ b/src/plugins/load.js @@ -54,7 +54,8 @@ module.exports = function (Plugins) { async.parallel([ async.apply(mapFiles, pluginData, 'css', 'cssFiles'), async.apply(mapFiles, pluginData, 'less', 'lessFiles'), - async.apply(mapClientSideScripts, pluginData) + async.apply(mapClientSideScripts, pluginData), + async.apply(mapClientModules, pluginData), ], next); }, next); } diff --git a/src/routes/index.js b/src/routes/index.js index e1f95891cf..506a0063ec 100644 --- a/src/routes/index.js +++ b/src/routes/index.js @@ -167,7 +167,8 @@ module.exports = function (app, middleware, hotswapIds) { '/templates/', '/src/', '/images/', - // '/sounds/', + '/language/', + '/sounds/', ]; app.use(relativePath, function (req, res, next) { if (deprecatedPaths.some(function (path) { return req.path.startsWith(path); })) { diff --git a/src/routes/meta.js b/src/routes/meta.js index af4e89d897..cb089f1200 100644 --- a/src/routes/meta.js +++ b/src/routes/meta.js @@ -1,20 +1,5 @@ "use strict"; -var path = require('path'); -var nconf = require('nconf'); - -var meta = require('../meta'); - -function sendSoundFile(req, res, next) { - var resolved = meta.sounds._filePathHash[path.basename(req.path)]; - - if (resolved) { - res.status(200).sendFile(resolved); - } else { - next(); - } -} - module.exports = function (app, middleware, controllers) { app.get('/sitemap.xml', controllers.sitemap.render); app.get('/sitemap/pages.xml', controllers.sitemap.getPages); @@ -23,8 +8,4 @@ module.exports = function (app, middleware, controllers) { app.get('/robots.txt', controllers.robots); app.get('/manifest.json', controllers.manifest); app.get('/css/previews/:theme', controllers.admin.themes.get); - - if (nconf.get('local-assets') === false) { - app.get('/sounds/*', middleware.addExpiresHeaders, sendSoundFile); - } }; diff --git a/src/webserver.js b/src/webserver.js index 2e7afdb228..a8324f7376 100644 --- a/src/webserver.js +++ b/src/webserver.js @@ -45,7 +45,7 @@ server.on('error', function (err) { winston.error(err); if (err.code === 'EADDRINUSE') { winston.error('NodeBB address in use, exiting...'); - process.exit(0); + process.exit(1); } else { throw err; } From 186209a0a3e75914052e400ca2408c9052b05fe9 Mon Sep 17 00:00:00 2001 From: Peter Jaszkowiak Date: Sat, 21 Jan 2017 18:57:27 -0700 Subject: [PATCH 03/11] Build plugin `staticDirs` - route `/plugins` -> `build/public/plugins` - symlink `staticDirs` directories into `build/public/plugins` - remove custom `/plugins` route handling --- build.js | 1 + src/file.js | 5 +++++ src/meta/js.js | 22 +++++++++++++++++++++- src/plugins/load.js | 2 ++ src/routes/index.js | 6 ++++-- src/routes/plugins.js | 40 ---------------------------------------- 6 files changed, 33 insertions(+), 43 deletions(-) delete mode 100644 src/routes/plugins.js diff --git a/build.js b/build.js index a8ad5007d1..73013231d5 100644 --- a/build.js +++ b/build.js @@ -62,6 +62,7 @@ exports.buildTargets = function (targets, callback) { var startTime = Date.now(); async.series([ meta.js.linkModules, + meta.js.linkStatics, async.apply(meta.js.minify, 'nodebb.min.js'), async.apply(meta.js.minify, 'acp.min.js') ], step.bind(this, startTime, 'js', next)); diff --git a/src/file.js b/src/file.js index 65f86a0bdd..d8fa128e5e 100644 --- a/src/file.js +++ b/src/file.js @@ -110,4 +110,9 @@ file.link = function link(filePath, destPath, cb) { } }; +file.linkDirs = function linkDirs(sourceDir, destDir, callback) { + var type = (process.platform === 'win32') ? 'junction' : 'dir'; + fs.symlink(sourceDir, destDir, type, callback); +}; + module.exports = file; diff --git a/src/meta/js.js b/src/meta/js.js index d479e9161c..a44d18baba 100644 --- a/src/meta/js.js +++ b/src/meta/js.js @@ -94,7 +94,7 @@ module.exports = function (Meta) { if (err) { return callback(err); } - async.each(Object.keys(Meta.js.scripts.modules), function (relPath, next) { + async.eachLimit(Object.keys(Meta.js.scripts.modules), 1000, function (relPath, next) { var filePath = path.join(__dirname, '../../', Meta.js.scripts.modules[relPath]); var destPath = path.join(__dirname, '../../build/public/src/modules', relPath); @@ -109,6 +109,26 @@ module.exports = function (Meta) { }); }; + Meta.js.linkStatics = function (callback) { + rimraf(path.join(__dirname, '../../build/public/plugins'), function (err) { + if (err) { + return callback(err); + } + async.eachLimit(Object.keys(plugins.staticDirs), 1000, function (mappedPath, next) { + var sourceDir = plugins.staticDirs[mappedPath]; + var destDir = path.join(__dirname, '../../build/public/plugins', mappedPath); + + mkdirp(path.dirname(destDir), function (err) { + if (err) { + return next(err); + } + + file.linkDirs(sourceDir, destDir, next); + }); + }, callback); + }); + }; + Meta.js.minify = function (target, callback) { winston.verbose('[meta/js] Minifying ' + target); diff --git a/src/plugins/load.js b/src/plugins/load.js index cf6e0b4780..01dedc4e45 100644 --- a/src/plugins/load.js +++ b/src/plugins/load.js @@ -56,6 +56,7 @@ module.exports = function (Plugins) { async.apply(mapFiles, pluginData, 'less', 'lessFiles'), async.apply(mapClientSideScripts, pluginData), async.apply(mapClientModules, pluginData), + async.apply(mapStaticDirectories, pluginData, pluginData.path), ], next); }, next); } @@ -299,6 +300,7 @@ module.exports = function (Plugins) { pluginData.version = packageData.version; pluginData.repository = packageData.repository; pluginData.nbbpm = packageData.nbbpm; + pluginData.path = pluginPath; } catch(err) { var pluginDir = pluginPath.split(path.sep); pluginDir = pluginDir[pluginDir.length - 1]; diff --git a/src/routes/index.js b/src/routes/index.js index 506a0063ec..0b9e6fce9a 100644 --- a/src/routes/index.js +++ b/src/routes/index.js @@ -15,7 +15,6 @@ var metaRoutes = require('./meta'); var apiRoutes = require('./api'); var adminRoutes = require('./admin'); var feedRoutes = require('./feeds'); -var pluginRoutes = require('./plugins'); var authRoutes = require('./authentication'); var helpers = require('./helpers'); @@ -123,7 +122,6 @@ module.exports = function (app, middleware, hotswapIds) { metaRoutes(router, middleware, controllers); apiRoutes(router, middleware, controllers); feedRoutes(router, middleware, controllers); - pluginRoutes(router, middleware, controllers); mainRoutes(router, middleware, controllers); topicRoutes(router, middleware, controllers); @@ -152,6 +150,10 @@ module.exports = function (app, middleware, hotswapIds) { app.use(relativePath + '/assets', express.static(path.join(__dirname, '../../public'), { maxAge: app.enabled('cache') ? 5184000000 : 0 })); + // TODO: deprecate? + app.use(relativePath + '/plugins', express.static(path.join(__dirname, '../../build/public/plugins'), { + maxAge: app.enabled('cache') ? 5184000000 : 0 + })); // DEPRECATED var deprecatedPaths = [ diff --git a/src/routes/plugins.js b/src/routes/plugins.js deleted file mode 100644 index 37e23c5ee6..0000000000 --- a/src/routes/plugins.js +++ /dev/null @@ -1,40 +0,0 @@ -"use strict"; - -var _ = require('underscore'); -var path = require('path'); - -var plugins = require('../plugins'); - -module.exports = function (app, middleware, controllers) { - // Static Assets - app.get('/plugins/:id/*', middleware.addExpiresHeaders, function (req, res, next) { - - var relPath = req._parsedUrl.pathname.replace('/plugins/', ''); - - var matches = _.map(plugins.staticDirs, function (realPath, mappedPath) { - if (relPath.match(mappedPath)) { - var pathToFile = path.join(plugins.staticDirs[mappedPath], decodeURIComponent(relPath.slice(mappedPath.length))); - if (pathToFile.startsWith(plugins.staticDirs[mappedPath])) { - return pathToFile; - } - } - - return null; - }).filter(Boolean); - - if (!matches || !matches.length) { - return next(); - } - - res.sendFile(matches[0], {}, function (err) { - if (err) { - if (err.code === 'ENOENT') { - // File doesn't exist, this isn't an error, to send to 404 handler - return next(); - } else { - return next(err); - } - } - }); - }); -}; \ No newline at end of file From 001aa3d1a85eb79cc04acae3626b710c9ea482b3 Mon Sep 17 00:00:00 2001 From: Peter Jaszkowiak Date: Sat, 21 Jan 2017 19:21:02 -0700 Subject: [PATCH 04/11] Fix tests, npm Windows fixes --- nodebb | 4 ++-- src/plugins/install.js | 2 +- test/mocks/databasemock.js | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/nodebb b/nodebb index e1a4ab7fbf..7f1d2941a3 100755 --- a/nodebb +++ b/nodebb @@ -225,12 +225,12 @@ var getRunningPid = function (callback) { if (['y', 'Y', 'yes', 'YES'].indexOf(result.upgrade) !== -1) { process.stdout.write('\nUpgrading packages...'); - var args = ['npm', 'i']; + var args = ['i']; found.forEach(function (suggestObj) { args.push(suggestObj.name + '@' + suggestObj.suggested); }); - require('child_process').execFile('/usr/bin/env', args, { stdio: 'ignore' }, function (err) { + require('child_process').execFile((process.platform === 'win32') ? 'npm.cmd' : 'npm', args, { stdio: 'ignore' }, function (err) { if (!err) { process.stdout.write(' OK\n'.green); } diff --git a/src/plugins/install.js b/src/plugins/install.js index a914a09ca6..840d46008a 100644 --- a/src/plugins/install.js +++ b/src/plugins/install.js @@ -102,7 +102,7 @@ module.exports = function (Plugins) { } function runNpmCommand(command, pkgName, version, callback) { - require('child_process').execFile('npm', [command, pkgName + (command === 'install' ? '@' + version : '')], function (err, stdout) { + require('child_process').execFile((process.platform === 'win32') ? 'npm.cmd' : 'npm', [command, pkgName + (command === 'install' ? '@' + version : '')], function (err, stdout) { if (err) { return callback(err); } diff --git a/test/mocks/databasemock.js b/test/mocks/databasemock.js index 182d9fea12..b7ed4cfb8c 100644 --- a/test/mocks/databasemock.js +++ b/test/mocks/databasemock.js @@ -140,7 +140,7 @@ nconf.set('theme_config', path.join(nconf.get('themes_path'), 'nodebb-theme-persona', 'theme.json')); nconf.set('bcrypt_rounds', 1); - require('../../build').buildTargets(['js', 'clientCSS', 'acpCSS', 'tpl'], next); + require('../../build').buildAll(next); }, function (next) { var webserver = require('../../src/webserver'); From f4147f7922e1f19b1f442546f2225b7bc3193b48 Mon Sep 17 00:00:00 2001 From: Peter Jaszkowiak Date: Mon, 23 Jan 2017 21:06:34 -0700 Subject: [PATCH 05/11] Generate cache buster on build --- build.js | 23 ++++++++++++++------- src/meta/cacheBuster.js | 46 +++++++++++++++++++++++++++++++++++++++++ src/meta/configs.js | 14 +++++++++---- 3 files changed, 72 insertions(+), 11 deletions(-) create mode 100644 src/meta/cacheBuster.js diff --git a/build.js b/build.js index 73013231d5..89c55177ad 100644 --- a/build.js +++ b/build.js @@ -44,6 +44,8 @@ exports.build = function build(targets, callback) { exports.buildTargets = function (targets, callback) { var meta = require('./src/meta'); + var cacheBuster = require('./src/meta/cacheBuster'); + buildStart = buildStart || Date.now(); var step = function (startTime, target, next, err) { @@ -114,14 +116,21 @@ exports.buildTargets = function (targets, callback) { return process.exit(1); } - var time = (Date.now() - buildStart) / 1000; + cacheBuster.write(function (err) { + if (err) { + winston.error('[build] Failed to write `cache-buster.conf`: ' + err.message); + return process.exit(1); + } - winston.info('[build] Asset compilation successful. Completed in ' + time + 's.'); + var time = (Date.now() - buildStart) / 1000; - if (typeof callback === 'function') { - callback(); - } else { - process.exit(0); - } + winston.info('[build] Asset compilation successful. Completed in ' + time + 's.'); + + if (typeof callback === 'function') { + callback(); + } else { + process.exit(0); + } + }); }); }; \ No newline at end of file diff --git a/src/meta/cacheBuster.js b/src/meta/cacheBuster.js new file mode 100644 index 0000000000..ca00fba057 --- /dev/null +++ b/src/meta/cacheBuster.js @@ -0,0 +1,46 @@ +'use strict'; + +var fs = require('fs'); +var path = require('path'); +var mkdirp = require('mkdirp'); +var winston = require('winston'); + +var filePath = path.join(__dirname, '../../build/cache-buster'); + +var cached; + +// cache buster is an 11-character, lowercase, alphanumeric string +function generate() { + return (Math.random() * 1e18).toString(32).slice(0, 11); +} + +exports.write = function write(callback) { + mkdirp(path.dirname(filePath), function (err) { + if (err) { + return callback(err); + } + + fs.writeFile(filePath, generate(), callback); + }); +}; + +exports.read = function read(callback) { + if (cached) { + return callback(null, cached); + } + + fs.readFile(filePath, function (err, buffer) { + if (err) { + winston.warn('[cache-buster] could not read cache buster: ' + err.message); + return callback(); + } + + buffer = buffer.toString(); + if (buffer) { + cached = buffer; + return callback(null, cached); + } + + callback(); + }); +}; diff --git a/src/meta/configs.js b/src/meta/configs.js index 75da0595d2..907e0ef477 100644 --- a/src/meta/configs.js +++ b/src/meta/configs.js @@ -6,7 +6,7 @@ var nconf = require('nconf'); var db = require('../database'); var pubsub = require('../pubsub'); -var utils = require('../../public/src/utils'); +var cacheBuster = require('./cacheBuster'); module.exports = function (Meta) { @@ -21,10 +21,16 @@ module.exports = function (Meta) { Meta.configs.list(next); }, function (config, next) { - config['cache-buster'] = 'v=' + utils.generateUUID(); + cacheBuster.read(function (err, buster) { + if (err) { + return next(err); + } + + config['cache-buster'] = 'v=' + (buster || Date.now()); - Meta.config = config; - setImmediate(next); + Meta.config = config; + next(); + }); } ], callback); }; From 44a59ac435e18e62666821fbde21a69e72eaee68 Mon Sep 17 00:00:00 2001 From: Peter Jaszkowiak Date: Fri, 3 Feb 2017 16:37:03 -0700 Subject: [PATCH 06/11] Fix tests to use default activated plugin --- test/plugins.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/plugins.js b/test/plugins.js index 09537d8990..06aabaab8d 100644 --- a/test/plugins.js +++ b/test/plugins.js @@ -152,7 +152,7 @@ describe('Plugins', function () { }); describe('static assets', function () { - it('should 404 if resource does not exist', function (done) { + it('should 404 if plugin does not exist', function (done) { request.get(nconf.get('url') + '/plugins/doesnotexist/should404.tpl', function (err, res, body) { assert.ifError(err); assert.equal(res.statusCode, 404); @@ -162,7 +162,7 @@ describe('Plugins', function () { }); it('should 404 if resource does not exist', function (done) { - request.get(nconf.get('url') + '/plugins/nodebb-plugin-dbsearch/dbsearch/templates/admin/plugins/should404.tpl', function (err, res, body) { + request.get(nconf.get('url') + '/plugins/nodebb-plugin-markdown/js/should404.js', function (err, res, body) { assert.ifError(err); assert.equal(res.statusCode, 404); assert(body); @@ -171,7 +171,7 @@ describe('Plugins', function () { }); it('should get resource', function (done) { - request.get(nconf.get('url') + '/plugins/nodebb-plugin-dbsearch/dbsearch/templates/admin/plugins/dbsearch.tpl', function (err, res, body) { + request.get(nconf.get('url') + '/plugins/nodebb-plugin-markdown/js/admin.js', function (err, res, body) { assert.ifError(err); assert.equal(res.statusCode, 200); assert(body); From d31499a860b6e567b41c030132853eb1cb1a01b3 Mon Sep 17 00:00:00 2001 From: Peter Jaszkowiak Date: Fri, 3 Feb 2017 18:29:09 -0700 Subject: [PATCH 07/11] Fix tests rewriting `logo.png` --- src/image.js | 3 +++ src/user/picture.js | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/image.js b/src/image.js index 1cfbdccbe3..0ab68e5a23 100644 --- a/src/image.js +++ b/src/image.js @@ -65,6 +65,9 @@ image.resizeImage = function (data, callback) { } }, function (image, next) { + if (data.write === false) { + return next(); + } image.write(data.target || data.path, next); } ], function (err) { diff --git a/src/user/picture.js b/src/user/picture.js index 0fd1d1a3bd..273a5dd413 100644 --- a/src/user/picture.js +++ b/src/user/picture.js @@ -57,7 +57,8 @@ module.exports = function (User) { path: picture.path, extension: extension, width: imageDimension, - height: imageDimension + height: imageDimension, + write: false, }, next); }, function (next) { From fdad66f58e721b4a02b89f5d06d1b6c2889f27ef Mon Sep 17 00:00:00 2001 From: Peter Jaszkowiak Date: Fri, 3 Feb 2017 23:48:43 -0700 Subject: [PATCH 08/11] Revert "Fix tests to use default activated plugin" This reverts commit 44a59ac435e18e62666821fbde21a69e72eaee68. --- test/plugins.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/test/plugins.js b/test/plugins.js index 06aabaab8d..09537d8990 100644 --- a/test/plugins.js +++ b/test/plugins.js @@ -152,7 +152,7 @@ describe('Plugins', function () { }); describe('static assets', function () { - it('should 404 if plugin does not exist', function (done) { + it('should 404 if resource does not exist', function (done) { request.get(nconf.get('url') + '/plugins/doesnotexist/should404.tpl', function (err, res, body) { assert.ifError(err); assert.equal(res.statusCode, 404); @@ -162,7 +162,7 @@ describe('Plugins', function () { }); it('should 404 if resource does not exist', function (done) { - request.get(nconf.get('url') + '/plugins/nodebb-plugin-markdown/js/should404.js', function (err, res, body) { + request.get(nconf.get('url') + '/plugins/nodebb-plugin-dbsearch/dbsearch/templates/admin/plugins/should404.tpl', function (err, res, body) { assert.ifError(err); assert.equal(res.statusCode, 404); assert(body); @@ -171,7 +171,7 @@ describe('Plugins', function () { }); it('should get resource', function (done) { - request.get(nconf.get('url') + '/plugins/nodebb-plugin-markdown/js/admin.js', function (err, res, body) { + request.get(nconf.get('url') + '/plugins/nodebb-plugin-dbsearch/dbsearch/templates/admin/plugins/dbsearch.tpl', function (err, res, body) { assert.ifError(err); assert.equal(res.statusCode, 200); assert(body); From d43564dbbd31a8d7cd04cdcef0db80901035397b Mon Sep 17 00:00:00 2001 From: Peter Jaszkowiak Date: Fri, 3 Feb 2017 23:55:33 -0700 Subject: [PATCH 09/11] No need to build multiple times --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 1395ce329d..c43218397f 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "scripts": { "start": "node loader.js", "lint": "eslint --cache .", - "pretest": "npm run lint && node app --build", + "pretest": "npm run lint", "test": "istanbul cover node_modules/mocha/bin/_mocha -- -R dot", "coveralls": "istanbul cover _mocha --report lcovonly -- -R dot && cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js && rm -rf ./coverage" }, From b530701cffd74c70f37225c598cd226f2a13b525 Mon Sep 17 00:00:00 2001 From: Peter Jaszkowiak Date: Mon, 6 Feb 2017 15:54:21 -0700 Subject: [PATCH 10/11] Fix tabs :rage: --- src/meta/css.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/meta/css.js b/src/meta/css.js index 6c4a0f62e3..3627c6c41a 100644 --- a/src/meta/css.js +++ b/src/meta/css.js @@ -26,7 +26,7 @@ module.exports = function (Meta) { '@import (inline) "../public/vendor/jquery/css/smoothness/jquery-ui.css";', '@import (inline) "../public/vendor/jquery/bootstrap-tagsinput/bootstrap-tagsinput.css";', '@import (inline) "../public/vendor/colorpicker/colorpicker.css";', - '@import (inline) "../node_modules/cropperjs/dist/cropper.css";', + '@import (inline) "../node_modules/cropperjs/dist/cropper.css";', '@import "../../public/less/flags.less";', '@import "../../public/less/blacklist.less";', '@import "../../public/less/generics.less";', From a122aad54d7418226f59e353b97a191a45afadeb Mon Sep 17 00:00:00 2001 From: Julian Lam Date: Tue, 7 Feb 2017 20:53:34 +0000 Subject: [PATCH 11/11] updating fallbacks --- public/language/ar/admin/general/dashboard.json | 10 +++++++++- public/language/bg/admin/general/dashboard.json | 10 +++++++++- public/language/bn/admin/general/dashboard.json | 10 +++++++++- public/language/cs/admin/general/dashboard.json | 10 +++++++++- public/language/da/admin/general/dashboard.json | 10 +++++++++- public/language/de/admin/general/dashboard.json | 12 ++++++++++-- public/language/el/admin/general/dashboard.json | 10 +++++++++- public/language/en-US/admin/general/dashboard.json | 10 +++++++++- .../en-x-pirate/admin/general/dashboard.json | 10 +++++++++- public/language/es/admin/general/dashboard.json | 10 +++++++++- public/language/et/admin/general/dashboard.json | 10 +++++++++- public/language/fa-IR/admin/general/dashboard.json | 10 +++++++++- public/language/fi/admin/general/dashboard.json | 10 +++++++++- public/language/fr/admin/general/dashboard.json | 10 +++++++++- public/language/gl/admin/general/dashboard.json | 10 +++++++++- public/language/he/admin/general/dashboard.json | 10 +++++++++- public/language/hu/admin/general/dashboard.json | 10 +++++++++- public/language/id/admin/general/dashboard.json | 10 +++++++++- public/language/it/admin/general/dashboard.json | 10 +++++++++- public/language/ja/admin/general/dashboard.json | 10 +++++++++- public/language/ko/admin/general/dashboard.json | 10 +++++++++- public/language/lt/admin/general/dashboard.json | 10 +++++++++- public/language/ms/admin/general/dashboard.json | 10 +++++++++- public/language/nb/admin/general/dashboard.json | 10 +++++++++- public/language/nl/admin/general/dashboard.json | 10 +++++++++- public/language/pl/admin/general/dashboard.json | 10 +++++++++- public/language/pt-BR/admin/general/dashboard.json | 10 +++++++++- public/language/pt-PT/admin/general/dashboard.json | 10 +++++++++- public/language/ro/admin/general/dashboard.json | 10 +++++++++- public/language/ru/admin/general/dashboard.json | 10 +++++++++- public/language/rw/admin/general/dashboard.json | 10 +++++++++- public/language/sc/admin/general/dashboard.json | 10 +++++++++- public/language/sk/admin/general/dashboard.json | 10 +++++++++- public/language/sl/admin/general/dashboard.json | 10 +++++++++- public/language/sr/admin/general/dashboard.json | 10 +++++++++- public/language/sv/admin/general/dashboard.json | 10 +++++++++- public/language/th/admin/general/dashboard.json | 10 +++++++++- public/language/tr/admin/general/dashboard.json | 10 +++++++++- public/language/vi/admin/general/dashboard.json | 10 +++++++++- public/language/zh-CN/admin/general/dashboard.json | 10 +++++++++- public/language/zh-TW/admin/general/dashboard.json | 10 +++++++++- 41 files changed, 370 insertions(+), 42 deletions(-) diff --git a/public/language/ar/admin/general/dashboard.json b/public/language/ar/admin/general/dashboard.json index b82802db1b..a70dda322e 100644 --- a/public/language/ar/admin/general/dashboard.json +++ b/public/language/ar/admin/general/dashboard.json @@ -2,6 +2,9 @@ "forum-traffic": "Forum Traffic", "page-views": "Page Views", "unique-visitors": "Unique Visitors", + "users": "Users", + "posts": "Posts", + "topics": "Topics", "page-views-last-month": "Page views Last Month", "page-views-this-month": "Page views This Month", "page-views-last-day": "Page views in last 24 hours", @@ -20,6 +23,11 @@ "prerelease-warning": "

This is a pre-release version of NodeBB. Unintended bugs may occur.

", "notices": "Notices", + "restart-not-required": "Restart not required", + "restart-required": "Restart required", + "search-plugin-installed": "Search Plugin installed", + "search-plugin-not-installed": "Search Plugin not installed", + "search-plugin-tooltip": "Install a search plugin from the plugin page in order to activate search functionality", "control-panel": "System Control", "reload": "Reload", @@ -52,4 +60,4 @@ "graphs.unique-visitors": "Unique Visitors", "graphs.registered-users": "Registered Users", "graphs.anonymous-users": "Anonymous Users" -} \ No newline at end of file +} diff --git a/public/language/bg/admin/general/dashboard.json b/public/language/bg/admin/general/dashboard.json index 357fbcba2d..b54fa53d30 100644 --- a/public/language/bg/admin/general/dashboard.json +++ b/public/language/bg/admin/general/dashboard.json @@ -2,6 +2,9 @@ "forum-traffic": "Трафик на форума", "page-views": "Преглеждания на страниците", "unique-visitors": "Уникални посетители", + "users": "Users", + "posts": "Posts", + "topics": "Topics", "page-views-last-month": "Преглеждания на страниците през последния месец", "page-views-this-month": "Преглеждания на страниците този месец", "page-views-last-day": "Преглеждания на страниците през последните 24 часа", @@ -20,6 +23,11 @@ "prerelease-warning": "

Това е версия за предварителен преглед на NodeBB. Възможно е да има неочаквани неизправности.

", "notices": "Забележки", + "restart-not-required": "Restart not required", + "restart-required": "Restart required", + "search-plugin-installed": "Search Plugin installed", + "search-plugin-not-installed": "Search Plugin not installed", + "search-plugin-tooltip": "Install a search plugin from the plugin page in order to activate search functionality", "control-panel": "Системен контрол", "reload": "Презареждане", @@ -52,4 +60,4 @@ "graphs.unique-visitors": "Уникални посетители", "graphs.registered-users": "Регистрирани потребители", "graphs.anonymous-users": "Анонимни потребители" -} \ No newline at end of file +} diff --git a/public/language/bn/admin/general/dashboard.json b/public/language/bn/admin/general/dashboard.json index b82802db1b..a70dda322e 100644 --- a/public/language/bn/admin/general/dashboard.json +++ b/public/language/bn/admin/general/dashboard.json @@ -2,6 +2,9 @@ "forum-traffic": "Forum Traffic", "page-views": "Page Views", "unique-visitors": "Unique Visitors", + "users": "Users", + "posts": "Posts", + "topics": "Topics", "page-views-last-month": "Page views Last Month", "page-views-this-month": "Page views This Month", "page-views-last-day": "Page views in last 24 hours", @@ -20,6 +23,11 @@ "prerelease-warning": "

This is a pre-release version of NodeBB. Unintended bugs may occur.

", "notices": "Notices", + "restart-not-required": "Restart not required", + "restart-required": "Restart required", + "search-plugin-installed": "Search Plugin installed", + "search-plugin-not-installed": "Search Plugin not installed", + "search-plugin-tooltip": "Install a search plugin from the plugin page in order to activate search functionality", "control-panel": "System Control", "reload": "Reload", @@ -52,4 +60,4 @@ "graphs.unique-visitors": "Unique Visitors", "graphs.registered-users": "Registered Users", "graphs.anonymous-users": "Anonymous Users" -} \ No newline at end of file +} diff --git a/public/language/cs/admin/general/dashboard.json b/public/language/cs/admin/general/dashboard.json index 4a41012de9..7b53dd6562 100644 --- a/public/language/cs/admin/general/dashboard.json +++ b/public/language/cs/admin/general/dashboard.json @@ -2,6 +2,9 @@ "forum-traffic": "Forum Traffic", "page-views": "Page Views", "unique-visitors": "Unique Visitors", + "users": "Users", + "posts": "Posts", + "topics": "Topics", "page-views-last-month": "Page views Last Month", "page-views-this-month": "Page views This Month", "page-views-last-day": "Page views in last 24 hours", @@ -20,6 +23,11 @@ "prerelease-warning": "

This is a pre-release version of NodeBB. Unintended bugs may occur.

", "notices": "Notices", + "restart-not-required": "Restart not required", + "restart-required": "Restart required", + "search-plugin-installed": "Search Plugin installed", + "search-plugin-not-installed": "Search Plugin not installed", + "search-plugin-tooltip": "Install a search plugin from the plugin page in order to activate search functionality", "control-panel": "System Control", "reload": "Reload", @@ -52,4 +60,4 @@ "graphs.unique-visitors": "Unique Visitors", "graphs.registered-users": "Registered Users", "graphs.anonymous-users": "Anonymous Users" -} \ No newline at end of file +} diff --git a/public/language/da/admin/general/dashboard.json b/public/language/da/admin/general/dashboard.json index 1ceda1053c..23153a3f1b 100644 --- a/public/language/da/admin/general/dashboard.json +++ b/public/language/da/admin/general/dashboard.json @@ -2,6 +2,9 @@ "forum-traffic": "Forum Traffik", "page-views": "Side Visninger", "unique-visitors": "Unikke Besøgere", + "users": "Users", + "posts": "Posts", + "topics": "Topics", "page-views-last-month": "Side Visninger Sidste Måned", "page-views-this-month": "Side Visninger Denne Måned", "page-views-last-day": "Side visninger i de sidste 24 timer", @@ -20,6 +23,11 @@ "prerelease-warning": "

Dette er en pre-release udgave af NodeBB. Uforventede bugs kan forekomme.

", "notices": "Varsler", + "restart-not-required": "Restart not required", + "restart-required": "Restart required", + "search-plugin-installed": "Search Plugin installed", + "search-plugin-not-installed": "Search Plugin not installed", + "search-plugin-tooltip": "Install a search plugin from the plugin page in order to activate search functionality", "control-panel": "System Kontrol", "reload": "Genindlæs", @@ -52,4 +60,4 @@ "graphs.unique-visitors": "Unique Visitors", "graphs.registered-users": "Registered Users", "graphs.anonymous-users": "Anonymous Users" -} \ No newline at end of file +} diff --git a/public/language/de/admin/general/dashboard.json b/public/language/de/admin/general/dashboard.json index 6c87767148..b6eda417ab 100644 --- a/public/language/de/admin/general/dashboard.json +++ b/public/language/de/admin/general/dashboard.json @@ -2,6 +2,9 @@ "forum-traffic": "Forum Traffic", "page-views": "Seitenaufrufe", "unique-visitors": "Besucher", + "users": "Users", + "posts": "Posts", + "topics": "Topics", "page-views-last-month": "Aufrufe im letzten Monat", "page-views-this-month": "Aufrufe in diesem Monat", "page-views-last-day": "Aufrufe in den letzten 24 Stunden", @@ -12,7 +15,7 @@ "stats.all": "Alle", "updates": "Updates", - "running-version": "Es läuft NodeBB v%1.", + "running-version": "Es läuft NodeBB v%1.", "keep-updated": "Stelle immer sicher, dass dein NodeBB auf dem neuesten Stand ist für die neuesten Sicherheits-Patches und Bug-fixes.", "up-to-date": "

System ist aktuell

", "upgrade-available": "

Version (v%1) wurde veröffentlicht. Beachte um ein NodeBB Upgrade durchzuführen.

", @@ -20,6 +23,11 @@ "prerelease-warning": "

Das ist eine pre-release Version von NodeBB. Es können ungewollte Fehler auftreten.

", "notices": "Hinweise", + "restart-not-required": "Restart not required", + "restart-required": "Restart required", + "search-plugin-installed": "Search Plugin installed", + "search-plugin-not-installed": "Search Plugin not installed", + "search-plugin-tooltip": "Install a search plugin from the plugin page in order to activate search functionality", "control-panel": "Systemsteuerung", "reload": "Reload", @@ -52,4 +60,4 @@ "graphs.unique-visitors": "verschiedene Besucher", "graphs.registered-users": "registrierte Benutzer", "graphs.anonymous-users": "anonyme Benutzer" -} \ No newline at end of file +} diff --git a/public/language/el/admin/general/dashboard.json b/public/language/el/admin/general/dashboard.json index b82802db1b..a70dda322e 100644 --- a/public/language/el/admin/general/dashboard.json +++ b/public/language/el/admin/general/dashboard.json @@ -2,6 +2,9 @@ "forum-traffic": "Forum Traffic", "page-views": "Page Views", "unique-visitors": "Unique Visitors", + "users": "Users", + "posts": "Posts", + "topics": "Topics", "page-views-last-month": "Page views Last Month", "page-views-this-month": "Page views This Month", "page-views-last-day": "Page views in last 24 hours", @@ -20,6 +23,11 @@ "prerelease-warning": "

This is a pre-release version of NodeBB. Unintended bugs may occur.

", "notices": "Notices", + "restart-not-required": "Restart not required", + "restart-required": "Restart required", + "search-plugin-installed": "Search Plugin installed", + "search-plugin-not-installed": "Search Plugin not installed", + "search-plugin-tooltip": "Install a search plugin from the plugin page in order to activate search functionality", "control-panel": "System Control", "reload": "Reload", @@ -52,4 +60,4 @@ "graphs.unique-visitors": "Unique Visitors", "graphs.registered-users": "Registered Users", "graphs.anonymous-users": "Anonymous Users" -} \ No newline at end of file +} diff --git a/public/language/en-US/admin/general/dashboard.json b/public/language/en-US/admin/general/dashboard.json index b82802db1b..a70dda322e 100644 --- a/public/language/en-US/admin/general/dashboard.json +++ b/public/language/en-US/admin/general/dashboard.json @@ -2,6 +2,9 @@ "forum-traffic": "Forum Traffic", "page-views": "Page Views", "unique-visitors": "Unique Visitors", + "users": "Users", + "posts": "Posts", + "topics": "Topics", "page-views-last-month": "Page views Last Month", "page-views-this-month": "Page views This Month", "page-views-last-day": "Page views in last 24 hours", @@ -20,6 +23,11 @@ "prerelease-warning": "

This is a pre-release version of NodeBB. Unintended bugs may occur.

", "notices": "Notices", + "restart-not-required": "Restart not required", + "restart-required": "Restart required", + "search-plugin-installed": "Search Plugin installed", + "search-plugin-not-installed": "Search Plugin not installed", + "search-plugin-tooltip": "Install a search plugin from the plugin page in order to activate search functionality", "control-panel": "System Control", "reload": "Reload", @@ -52,4 +60,4 @@ "graphs.unique-visitors": "Unique Visitors", "graphs.registered-users": "Registered Users", "graphs.anonymous-users": "Anonymous Users" -} \ No newline at end of file +} diff --git a/public/language/en-x-pirate/admin/general/dashboard.json b/public/language/en-x-pirate/admin/general/dashboard.json index b82802db1b..a70dda322e 100644 --- a/public/language/en-x-pirate/admin/general/dashboard.json +++ b/public/language/en-x-pirate/admin/general/dashboard.json @@ -2,6 +2,9 @@ "forum-traffic": "Forum Traffic", "page-views": "Page Views", "unique-visitors": "Unique Visitors", + "users": "Users", + "posts": "Posts", + "topics": "Topics", "page-views-last-month": "Page views Last Month", "page-views-this-month": "Page views This Month", "page-views-last-day": "Page views in last 24 hours", @@ -20,6 +23,11 @@ "prerelease-warning": "

This is a pre-release version of NodeBB. Unintended bugs may occur.

", "notices": "Notices", + "restart-not-required": "Restart not required", + "restart-required": "Restart required", + "search-plugin-installed": "Search Plugin installed", + "search-plugin-not-installed": "Search Plugin not installed", + "search-plugin-tooltip": "Install a search plugin from the plugin page in order to activate search functionality", "control-panel": "System Control", "reload": "Reload", @@ -52,4 +60,4 @@ "graphs.unique-visitors": "Unique Visitors", "graphs.registered-users": "Registered Users", "graphs.anonymous-users": "Anonymous Users" -} \ No newline at end of file +} diff --git a/public/language/es/admin/general/dashboard.json b/public/language/es/admin/general/dashboard.json index b82802db1b..a70dda322e 100644 --- a/public/language/es/admin/general/dashboard.json +++ b/public/language/es/admin/general/dashboard.json @@ -2,6 +2,9 @@ "forum-traffic": "Forum Traffic", "page-views": "Page Views", "unique-visitors": "Unique Visitors", + "users": "Users", + "posts": "Posts", + "topics": "Topics", "page-views-last-month": "Page views Last Month", "page-views-this-month": "Page views This Month", "page-views-last-day": "Page views in last 24 hours", @@ -20,6 +23,11 @@ "prerelease-warning": "

This is a pre-release version of NodeBB. Unintended bugs may occur.

", "notices": "Notices", + "restart-not-required": "Restart not required", + "restart-required": "Restart required", + "search-plugin-installed": "Search Plugin installed", + "search-plugin-not-installed": "Search Plugin not installed", + "search-plugin-tooltip": "Install a search plugin from the plugin page in order to activate search functionality", "control-panel": "System Control", "reload": "Reload", @@ -52,4 +60,4 @@ "graphs.unique-visitors": "Unique Visitors", "graphs.registered-users": "Registered Users", "graphs.anonymous-users": "Anonymous Users" -} \ No newline at end of file +} diff --git a/public/language/et/admin/general/dashboard.json b/public/language/et/admin/general/dashboard.json index b82802db1b..a70dda322e 100644 --- a/public/language/et/admin/general/dashboard.json +++ b/public/language/et/admin/general/dashboard.json @@ -2,6 +2,9 @@ "forum-traffic": "Forum Traffic", "page-views": "Page Views", "unique-visitors": "Unique Visitors", + "users": "Users", + "posts": "Posts", + "topics": "Topics", "page-views-last-month": "Page views Last Month", "page-views-this-month": "Page views This Month", "page-views-last-day": "Page views in last 24 hours", @@ -20,6 +23,11 @@ "prerelease-warning": "

This is a pre-release version of NodeBB. Unintended bugs may occur.

", "notices": "Notices", + "restart-not-required": "Restart not required", + "restart-required": "Restart required", + "search-plugin-installed": "Search Plugin installed", + "search-plugin-not-installed": "Search Plugin not installed", + "search-plugin-tooltip": "Install a search plugin from the plugin page in order to activate search functionality", "control-panel": "System Control", "reload": "Reload", @@ -52,4 +60,4 @@ "graphs.unique-visitors": "Unique Visitors", "graphs.registered-users": "Registered Users", "graphs.anonymous-users": "Anonymous Users" -} \ No newline at end of file +} diff --git a/public/language/fa-IR/admin/general/dashboard.json b/public/language/fa-IR/admin/general/dashboard.json index b82802db1b..a70dda322e 100644 --- a/public/language/fa-IR/admin/general/dashboard.json +++ b/public/language/fa-IR/admin/general/dashboard.json @@ -2,6 +2,9 @@ "forum-traffic": "Forum Traffic", "page-views": "Page Views", "unique-visitors": "Unique Visitors", + "users": "Users", + "posts": "Posts", + "topics": "Topics", "page-views-last-month": "Page views Last Month", "page-views-this-month": "Page views This Month", "page-views-last-day": "Page views in last 24 hours", @@ -20,6 +23,11 @@ "prerelease-warning": "

This is a pre-release version of NodeBB. Unintended bugs may occur.

", "notices": "Notices", + "restart-not-required": "Restart not required", + "restart-required": "Restart required", + "search-plugin-installed": "Search Plugin installed", + "search-plugin-not-installed": "Search Plugin not installed", + "search-plugin-tooltip": "Install a search plugin from the plugin page in order to activate search functionality", "control-panel": "System Control", "reload": "Reload", @@ -52,4 +60,4 @@ "graphs.unique-visitors": "Unique Visitors", "graphs.registered-users": "Registered Users", "graphs.anonymous-users": "Anonymous Users" -} \ No newline at end of file +} diff --git a/public/language/fi/admin/general/dashboard.json b/public/language/fi/admin/general/dashboard.json index b82802db1b..a70dda322e 100644 --- a/public/language/fi/admin/general/dashboard.json +++ b/public/language/fi/admin/general/dashboard.json @@ -2,6 +2,9 @@ "forum-traffic": "Forum Traffic", "page-views": "Page Views", "unique-visitors": "Unique Visitors", + "users": "Users", + "posts": "Posts", + "topics": "Topics", "page-views-last-month": "Page views Last Month", "page-views-this-month": "Page views This Month", "page-views-last-day": "Page views in last 24 hours", @@ -20,6 +23,11 @@ "prerelease-warning": "

This is a pre-release version of NodeBB. Unintended bugs may occur.

", "notices": "Notices", + "restart-not-required": "Restart not required", + "restart-required": "Restart required", + "search-plugin-installed": "Search Plugin installed", + "search-plugin-not-installed": "Search Plugin not installed", + "search-plugin-tooltip": "Install a search plugin from the plugin page in order to activate search functionality", "control-panel": "System Control", "reload": "Reload", @@ -52,4 +60,4 @@ "graphs.unique-visitors": "Unique Visitors", "graphs.registered-users": "Registered Users", "graphs.anonymous-users": "Anonymous Users" -} \ No newline at end of file +} diff --git a/public/language/fr/admin/general/dashboard.json b/public/language/fr/admin/general/dashboard.json index 3123167d2a..02ea6849a7 100644 --- a/public/language/fr/admin/general/dashboard.json +++ b/public/language/fr/admin/general/dashboard.json @@ -2,6 +2,9 @@ "forum-traffic": "Trafic du forum", "page-views": "Pages vues", "unique-visitors": "Visiteurs uniques", + "users": "Users", + "posts": "Posts", + "topics": "Topics", "page-views-last-month": "Pages vues le mois dernier", "page-views-this-month": "Pages vues ce mois-ci", "page-views-last-day": "Pages vues ces dernières 24 heures", @@ -20,6 +23,11 @@ "prerelease-warning": "

Ceci est une version préliminaire de NodeBB. Des bugs inattendus peuvent se produire.

", "notices": "Informations", + "restart-not-required": "Restart not required", + "restart-required": "Restart required", + "search-plugin-installed": "Search Plugin installed", + "search-plugin-not-installed": "Search Plugin not installed", + "search-plugin-tooltip": "Install a search plugin from the plugin page in order to activate search functionality", "control-panel": "Contrôle du système", "reload": "Recharger", @@ -52,4 +60,4 @@ "graphs.unique-visitors": "Visiteurs uniques", "graphs.registered-users": "Utilisateurs enregistrés", "graphs.anonymous-users": "Utilisateurs anonymes" -} \ No newline at end of file +} diff --git a/public/language/gl/admin/general/dashboard.json b/public/language/gl/admin/general/dashboard.json index b82802db1b..a70dda322e 100644 --- a/public/language/gl/admin/general/dashboard.json +++ b/public/language/gl/admin/general/dashboard.json @@ -2,6 +2,9 @@ "forum-traffic": "Forum Traffic", "page-views": "Page Views", "unique-visitors": "Unique Visitors", + "users": "Users", + "posts": "Posts", + "topics": "Topics", "page-views-last-month": "Page views Last Month", "page-views-this-month": "Page views This Month", "page-views-last-day": "Page views in last 24 hours", @@ -20,6 +23,11 @@ "prerelease-warning": "

This is a pre-release version of NodeBB. Unintended bugs may occur.

", "notices": "Notices", + "restart-not-required": "Restart not required", + "restart-required": "Restart required", + "search-plugin-installed": "Search Plugin installed", + "search-plugin-not-installed": "Search Plugin not installed", + "search-plugin-tooltip": "Install a search plugin from the plugin page in order to activate search functionality", "control-panel": "System Control", "reload": "Reload", @@ -52,4 +60,4 @@ "graphs.unique-visitors": "Unique Visitors", "graphs.registered-users": "Registered Users", "graphs.anonymous-users": "Anonymous Users" -} \ No newline at end of file +} diff --git a/public/language/he/admin/general/dashboard.json b/public/language/he/admin/general/dashboard.json index 5be33f9db1..74abb83ea1 100644 --- a/public/language/he/admin/general/dashboard.json +++ b/public/language/he/admin/general/dashboard.json @@ -2,6 +2,9 @@ "forum-traffic": "Forum Traffic", "page-views": "Page Views", "unique-visitors": "Unique Visitors", + "users": "Users", + "posts": "Posts", + "topics": "Topics", "page-views-last-month": "Page views Last Month", "page-views-this-month": "Page views This Month", "page-views-last-day": "Page views in last 24 hours", @@ -20,6 +23,11 @@ "prerelease-warning": "

This is a pre-release version of NodeBB. Unintended bugs may occur.

", "notices": "Notices", + "restart-not-required": "Restart not required", + "restart-required": "Restart required", + "search-plugin-installed": "Search Plugin installed", + "search-plugin-not-installed": "Search Plugin not installed", + "search-plugin-tooltip": "Install a search plugin from the plugin page in order to activate search functionality", "control-panel": "System Control", "reload": "רענן", @@ -52,4 +60,4 @@ "graphs.unique-visitors": "Unique Visitors", "graphs.registered-users": "Registered Users", "graphs.anonymous-users": "Anonymous Users" -} \ No newline at end of file +} diff --git a/public/language/hu/admin/general/dashboard.json b/public/language/hu/admin/general/dashboard.json index b82802db1b..a70dda322e 100644 --- a/public/language/hu/admin/general/dashboard.json +++ b/public/language/hu/admin/general/dashboard.json @@ -2,6 +2,9 @@ "forum-traffic": "Forum Traffic", "page-views": "Page Views", "unique-visitors": "Unique Visitors", + "users": "Users", + "posts": "Posts", + "topics": "Topics", "page-views-last-month": "Page views Last Month", "page-views-this-month": "Page views This Month", "page-views-last-day": "Page views in last 24 hours", @@ -20,6 +23,11 @@ "prerelease-warning": "

This is a pre-release version of NodeBB. Unintended bugs may occur.

", "notices": "Notices", + "restart-not-required": "Restart not required", + "restart-required": "Restart required", + "search-plugin-installed": "Search Plugin installed", + "search-plugin-not-installed": "Search Plugin not installed", + "search-plugin-tooltip": "Install a search plugin from the plugin page in order to activate search functionality", "control-panel": "System Control", "reload": "Reload", @@ -52,4 +60,4 @@ "graphs.unique-visitors": "Unique Visitors", "graphs.registered-users": "Registered Users", "graphs.anonymous-users": "Anonymous Users" -} \ No newline at end of file +} diff --git a/public/language/id/admin/general/dashboard.json b/public/language/id/admin/general/dashboard.json index b82802db1b..a70dda322e 100644 --- a/public/language/id/admin/general/dashboard.json +++ b/public/language/id/admin/general/dashboard.json @@ -2,6 +2,9 @@ "forum-traffic": "Forum Traffic", "page-views": "Page Views", "unique-visitors": "Unique Visitors", + "users": "Users", + "posts": "Posts", + "topics": "Topics", "page-views-last-month": "Page views Last Month", "page-views-this-month": "Page views This Month", "page-views-last-day": "Page views in last 24 hours", @@ -20,6 +23,11 @@ "prerelease-warning": "

This is a pre-release version of NodeBB. Unintended bugs may occur.

", "notices": "Notices", + "restart-not-required": "Restart not required", + "restart-required": "Restart required", + "search-plugin-installed": "Search Plugin installed", + "search-plugin-not-installed": "Search Plugin not installed", + "search-plugin-tooltip": "Install a search plugin from the plugin page in order to activate search functionality", "control-panel": "System Control", "reload": "Reload", @@ -52,4 +60,4 @@ "graphs.unique-visitors": "Unique Visitors", "graphs.registered-users": "Registered Users", "graphs.anonymous-users": "Anonymous Users" -} \ No newline at end of file +} diff --git a/public/language/it/admin/general/dashboard.json b/public/language/it/admin/general/dashboard.json index b82802db1b..a70dda322e 100644 --- a/public/language/it/admin/general/dashboard.json +++ b/public/language/it/admin/general/dashboard.json @@ -2,6 +2,9 @@ "forum-traffic": "Forum Traffic", "page-views": "Page Views", "unique-visitors": "Unique Visitors", + "users": "Users", + "posts": "Posts", + "topics": "Topics", "page-views-last-month": "Page views Last Month", "page-views-this-month": "Page views This Month", "page-views-last-day": "Page views in last 24 hours", @@ -20,6 +23,11 @@ "prerelease-warning": "

This is a pre-release version of NodeBB. Unintended bugs may occur.

", "notices": "Notices", + "restart-not-required": "Restart not required", + "restart-required": "Restart required", + "search-plugin-installed": "Search Plugin installed", + "search-plugin-not-installed": "Search Plugin not installed", + "search-plugin-tooltip": "Install a search plugin from the plugin page in order to activate search functionality", "control-panel": "System Control", "reload": "Reload", @@ -52,4 +60,4 @@ "graphs.unique-visitors": "Unique Visitors", "graphs.registered-users": "Registered Users", "graphs.anonymous-users": "Anonymous Users" -} \ No newline at end of file +} diff --git a/public/language/ja/admin/general/dashboard.json b/public/language/ja/admin/general/dashboard.json index c650f6043c..813f3d272a 100644 --- a/public/language/ja/admin/general/dashboard.json +++ b/public/language/ja/admin/general/dashboard.json @@ -2,6 +2,9 @@ "forum-traffic": "フォーラムのトラフィック", "page-views": "ページビュー", "unique-visitors": "ユニークな訪問者", + "users": "Users", + "posts": "Posts", + "topics": "Topics", "page-views-last-month": "先月のページビュー数", "page-views-this-month": "今月のページビュー数", "page-views-last-day": "過去24時間のページビュー", @@ -20,6 +23,11 @@ "prerelease-warning": "

これはNodeBBのプレリリース版です。意図しないバグが発生することがあります。

", "notices": "通知", + "restart-not-required": "Restart not required", + "restart-required": "Restart required", + "search-plugin-installed": "Search Plugin installed", + "search-plugin-not-installed": "Search Plugin not installed", + "search-plugin-tooltip": "Install a search plugin from the plugin page in order to activate search functionality", "control-panel": "システムコントロール", "reload": "再読み込み", @@ -52,4 +60,4 @@ "graphs.unique-visitors": "ユニークな訪問者", "graphs.registered-users": "登録したユーザー", "graphs.anonymous-users": "匿名ユーザー" -} \ No newline at end of file +} diff --git a/public/language/ko/admin/general/dashboard.json b/public/language/ko/admin/general/dashboard.json index b82802db1b..a70dda322e 100644 --- a/public/language/ko/admin/general/dashboard.json +++ b/public/language/ko/admin/general/dashboard.json @@ -2,6 +2,9 @@ "forum-traffic": "Forum Traffic", "page-views": "Page Views", "unique-visitors": "Unique Visitors", + "users": "Users", + "posts": "Posts", + "topics": "Topics", "page-views-last-month": "Page views Last Month", "page-views-this-month": "Page views This Month", "page-views-last-day": "Page views in last 24 hours", @@ -20,6 +23,11 @@ "prerelease-warning": "

This is a pre-release version of NodeBB. Unintended bugs may occur.

", "notices": "Notices", + "restart-not-required": "Restart not required", + "restart-required": "Restart required", + "search-plugin-installed": "Search Plugin installed", + "search-plugin-not-installed": "Search Plugin not installed", + "search-plugin-tooltip": "Install a search plugin from the plugin page in order to activate search functionality", "control-panel": "System Control", "reload": "Reload", @@ -52,4 +60,4 @@ "graphs.unique-visitors": "Unique Visitors", "graphs.registered-users": "Registered Users", "graphs.anonymous-users": "Anonymous Users" -} \ No newline at end of file +} diff --git a/public/language/lt/admin/general/dashboard.json b/public/language/lt/admin/general/dashboard.json index b82802db1b..a70dda322e 100644 --- a/public/language/lt/admin/general/dashboard.json +++ b/public/language/lt/admin/general/dashboard.json @@ -2,6 +2,9 @@ "forum-traffic": "Forum Traffic", "page-views": "Page Views", "unique-visitors": "Unique Visitors", + "users": "Users", + "posts": "Posts", + "topics": "Topics", "page-views-last-month": "Page views Last Month", "page-views-this-month": "Page views This Month", "page-views-last-day": "Page views in last 24 hours", @@ -20,6 +23,11 @@ "prerelease-warning": "

This is a pre-release version of NodeBB. Unintended bugs may occur.

", "notices": "Notices", + "restart-not-required": "Restart not required", + "restart-required": "Restart required", + "search-plugin-installed": "Search Plugin installed", + "search-plugin-not-installed": "Search Plugin not installed", + "search-plugin-tooltip": "Install a search plugin from the plugin page in order to activate search functionality", "control-panel": "System Control", "reload": "Reload", @@ -52,4 +60,4 @@ "graphs.unique-visitors": "Unique Visitors", "graphs.registered-users": "Registered Users", "graphs.anonymous-users": "Anonymous Users" -} \ No newline at end of file +} diff --git a/public/language/ms/admin/general/dashboard.json b/public/language/ms/admin/general/dashboard.json index b82802db1b..a70dda322e 100644 --- a/public/language/ms/admin/general/dashboard.json +++ b/public/language/ms/admin/general/dashboard.json @@ -2,6 +2,9 @@ "forum-traffic": "Forum Traffic", "page-views": "Page Views", "unique-visitors": "Unique Visitors", + "users": "Users", + "posts": "Posts", + "topics": "Topics", "page-views-last-month": "Page views Last Month", "page-views-this-month": "Page views This Month", "page-views-last-day": "Page views in last 24 hours", @@ -20,6 +23,11 @@ "prerelease-warning": "

This is a pre-release version of NodeBB. Unintended bugs may occur.

", "notices": "Notices", + "restart-not-required": "Restart not required", + "restart-required": "Restart required", + "search-plugin-installed": "Search Plugin installed", + "search-plugin-not-installed": "Search Plugin not installed", + "search-plugin-tooltip": "Install a search plugin from the plugin page in order to activate search functionality", "control-panel": "System Control", "reload": "Reload", @@ -52,4 +60,4 @@ "graphs.unique-visitors": "Unique Visitors", "graphs.registered-users": "Registered Users", "graphs.anonymous-users": "Anonymous Users" -} \ No newline at end of file +} diff --git a/public/language/nb/admin/general/dashboard.json b/public/language/nb/admin/general/dashboard.json index b82802db1b..a70dda322e 100644 --- a/public/language/nb/admin/general/dashboard.json +++ b/public/language/nb/admin/general/dashboard.json @@ -2,6 +2,9 @@ "forum-traffic": "Forum Traffic", "page-views": "Page Views", "unique-visitors": "Unique Visitors", + "users": "Users", + "posts": "Posts", + "topics": "Topics", "page-views-last-month": "Page views Last Month", "page-views-this-month": "Page views This Month", "page-views-last-day": "Page views in last 24 hours", @@ -20,6 +23,11 @@ "prerelease-warning": "

This is a pre-release version of NodeBB. Unintended bugs may occur.

", "notices": "Notices", + "restart-not-required": "Restart not required", + "restart-required": "Restart required", + "search-plugin-installed": "Search Plugin installed", + "search-plugin-not-installed": "Search Plugin not installed", + "search-plugin-tooltip": "Install a search plugin from the plugin page in order to activate search functionality", "control-panel": "System Control", "reload": "Reload", @@ -52,4 +60,4 @@ "graphs.unique-visitors": "Unique Visitors", "graphs.registered-users": "Registered Users", "graphs.anonymous-users": "Anonymous Users" -} \ No newline at end of file +} diff --git a/public/language/nl/admin/general/dashboard.json b/public/language/nl/admin/general/dashboard.json index b82802db1b..a70dda322e 100644 --- a/public/language/nl/admin/general/dashboard.json +++ b/public/language/nl/admin/general/dashboard.json @@ -2,6 +2,9 @@ "forum-traffic": "Forum Traffic", "page-views": "Page Views", "unique-visitors": "Unique Visitors", + "users": "Users", + "posts": "Posts", + "topics": "Topics", "page-views-last-month": "Page views Last Month", "page-views-this-month": "Page views This Month", "page-views-last-day": "Page views in last 24 hours", @@ -20,6 +23,11 @@ "prerelease-warning": "

This is a pre-release version of NodeBB. Unintended bugs may occur.

", "notices": "Notices", + "restart-not-required": "Restart not required", + "restart-required": "Restart required", + "search-plugin-installed": "Search Plugin installed", + "search-plugin-not-installed": "Search Plugin not installed", + "search-plugin-tooltip": "Install a search plugin from the plugin page in order to activate search functionality", "control-panel": "System Control", "reload": "Reload", @@ -52,4 +60,4 @@ "graphs.unique-visitors": "Unique Visitors", "graphs.registered-users": "Registered Users", "graphs.anonymous-users": "Anonymous Users" -} \ No newline at end of file +} diff --git a/public/language/pl/admin/general/dashboard.json b/public/language/pl/admin/general/dashboard.json index 00dea84351..d20af29013 100644 --- a/public/language/pl/admin/general/dashboard.json +++ b/public/language/pl/admin/general/dashboard.json @@ -2,6 +2,9 @@ "forum-traffic": "Ruch na forum", "page-views": "Wyświetlenia strony", "unique-visitors": "Unikalni goście", + "users": "Users", + "posts": "Posts", + "topics": "Topics", "page-views-last-month": "Wyświetlenia strony w ostatnim miesiącu", "page-views-this-month": "Wyświetlenia strony w tym miesiącu", "page-views-last-day": "Wyświetlenia strony z ostatnich 24 godzin", @@ -20,6 +23,11 @@ "prerelease-warning": "

This is a pre-release version of NodeBB. Unintended bugs may occur.

", "notices": "Powiadomienia", + "restart-not-required": "Restart not required", + "restart-required": "Restart required", + "search-plugin-installed": "Search Plugin installed", + "search-plugin-not-installed": "Search Plugin not installed", + "search-plugin-tooltip": "Install a search plugin from the plugin page in order to activate search functionality", "control-panel": "Zarządzanie systemem", "reload": "Odśwież", @@ -52,4 +60,4 @@ "graphs.unique-visitors": "Unikalni Użytkownicy", "graphs.registered-users": "Zarejestrowani Użytkownicy", "graphs.anonymous-users": "Anonimowi Użytkownicy" -} \ No newline at end of file +} diff --git a/public/language/pt-BR/admin/general/dashboard.json b/public/language/pt-BR/admin/general/dashboard.json index 0642d2b51e..d818f5f754 100644 --- a/public/language/pt-BR/admin/general/dashboard.json +++ b/public/language/pt-BR/admin/general/dashboard.json @@ -2,6 +2,9 @@ "forum-traffic": "Tráfego do Forum", "page-views": "Visualizações de Página", "unique-visitors": "Visitantes Únicos", + "users": "Users", + "posts": "Posts", + "topics": "Topics", "page-views-last-month": "Visualizações de página no Último Mês", "page-views-this-month": "Visualizações de Página Este Mês", "page-views-last-day": "Visualizações de página nas últimas 24 horas", @@ -20,6 +23,11 @@ "prerelease-warning": "

Esta é uma versão pre-release do NodeBB. Bugs inesperados podem ocorrer.

", "notices": "Avisos", + "restart-not-required": "Restart not required", + "restart-required": "Restart required", + "search-plugin-installed": "Search Plugin installed", + "search-plugin-not-installed": "Search Plugin not installed", + "search-plugin-tooltip": "Install a search plugin from the plugin page in order to activate search functionality", "control-panel": "Controle do Sistema", "reload": "Recarregar", @@ -52,4 +60,4 @@ "graphs.unique-visitors": "Visitantes Únicos", "graphs.registered-users": "Usuários Registrados", "graphs.anonymous-users": "Usuários Anônimos" -} \ No newline at end of file +} diff --git a/public/language/pt-PT/admin/general/dashboard.json b/public/language/pt-PT/admin/general/dashboard.json index b82802db1b..a70dda322e 100644 --- a/public/language/pt-PT/admin/general/dashboard.json +++ b/public/language/pt-PT/admin/general/dashboard.json @@ -2,6 +2,9 @@ "forum-traffic": "Forum Traffic", "page-views": "Page Views", "unique-visitors": "Unique Visitors", + "users": "Users", + "posts": "Posts", + "topics": "Topics", "page-views-last-month": "Page views Last Month", "page-views-this-month": "Page views This Month", "page-views-last-day": "Page views in last 24 hours", @@ -20,6 +23,11 @@ "prerelease-warning": "

This is a pre-release version of NodeBB. Unintended bugs may occur.

", "notices": "Notices", + "restart-not-required": "Restart not required", + "restart-required": "Restart required", + "search-plugin-installed": "Search Plugin installed", + "search-plugin-not-installed": "Search Plugin not installed", + "search-plugin-tooltip": "Install a search plugin from the plugin page in order to activate search functionality", "control-panel": "System Control", "reload": "Reload", @@ -52,4 +60,4 @@ "graphs.unique-visitors": "Unique Visitors", "graphs.registered-users": "Registered Users", "graphs.anonymous-users": "Anonymous Users" -} \ No newline at end of file +} diff --git a/public/language/ro/admin/general/dashboard.json b/public/language/ro/admin/general/dashboard.json index b82802db1b..a70dda322e 100644 --- a/public/language/ro/admin/general/dashboard.json +++ b/public/language/ro/admin/general/dashboard.json @@ -2,6 +2,9 @@ "forum-traffic": "Forum Traffic", "page-views": "Page Views", "unique-visitors": "Unique Visitors", + "users": "Users", + "posts": "Posts", + "topics": "Topics", "page-views-last-month": "Page views Last Month", "page-views-this-month": "Page views This Month", "page-views-last-day": "Page views in last 24 hours", @@ -20,6 +23,11 @@ "prerelease-warning": "

This is a pre-release version of NodeBB. Unintended bugs may occur.

", "notices": "Notices", + "restart-not-required": "Restart not required", + "restart-required": "Restart required", + "search-plugin-installed": "Search Plugin installed", + "search-plugin-not-installed": "Search Plugin not installed", + "search-plugin-tooltip": "Install a search plugin from the plugin page in order to activate search functionality", "control-panel": "System Control", "reload": "Reload", @@ -52,4 +60,4 @@ "graphs.unique-visitors": "Unique Visitors", "graphs.registered-users": "Registered Users", "graphs.anonymous-users": "Anonymous Users" -} \ No newline at end of file +} diff --git a/public/language/ru/admin/general/dashboard.json b/public/language/ru/admin/general/dashboard.json index c5c6a3e2f3..ea879e2ff8 100644 --- a/public/language/ru/admin/general/dashboard.json +++ b/public/language/ru/admin/general/dashboard.json @@ -2,6 +2,9 @@ "forum-traffic": "Трафик ", "page-views": "Просмотров", "unique-visitors": "Посетителей", + "users": "Users", + "posts": "Posts", + "topics": "Topics", "page-views-last-month": "Просмотров за прошлый месяц", "page-views-this-month": "Просмотров за этот месяц", "page-views-last-day": "Просмотров за 24 часа", @@ -20,6 +23,11 @@ "prerelease-warning": "

This is a pre-release version of NodeBB. Unintended bugs may occur.

", "notices": "Уведомления", + "restart-not-required": "Restart not required", + "restart-required": "Restart required", + "search-plugin-installed": "Search Plugin installed", + "search-plugin-not-installed": "Search Plugin not installed", + "search-plugin-tooltip": "Install a search plugin from the plugin page in order to activate search functionality", "control-panel": "Управление", "reload": "Перезапустить", @@ -52,4 +60,4 @@ "graphs.unique-visitors": "Уникальных пользователей", "graphs.registered-users": "Зарегистрированных пользователей", "graphs.anonymous-users": "Анонимных пользователей" -} \ No newline at end of file +} diff --git a/public/language/rw/admin/general/dashboard.json b/public/language/rw/admin/general/dashboard.json index b82802db1b..a70dda322e 100644 --- a/public/language/rw/admin/general/dashboard.json +++ b/public/language/rw/admin/general/dashboard.json @@ -2,6 +2,9 @@ "forum-traffic": "Forum Traffic", "page-views": "Page Views", "unique-visitors": "Unique Visitors", + "users": "Users", + "posts": "Posts", + "topics": "Topics", "page-views-last-month": "Page views Last Month", "page-views-this-month": "Page views This Month", "page-views-last-day": "Page views in last 24 hours", @@ -20,6 +23,11 @@ "prerelease-warning": "

This is a pre-release version of NodeBB. Unintended bugs may occur.

", "notices": "Notices", + "restart-not-required": "Restart not required", + "restart-required": "Restart required", + "search-plugin-installed": "Search Plugin installed", + "search-plugin-not-installed": "Search Plugin not installed", + "search-plugin-tooltip": "Install a search plugin from the plugin page in order to activate search functionality", "control-panel": "System Control", "reload": "Reload", @@ -52,4 +60,4 @@ "graphs.unique-visitors": "Unique Visitors", "graphs.registered-users": "Registered Users", "graphs.anonymous-users": "Anonymous Users" -} \ No newline at end of file +} diff --git a/public/language/sc/admin/general/dashboard.json b/public/language/sc/admin/general/dashboard.json index b82802db1b..a70dda322e 100644 --- a/public/language/sc/admin/general/dashboard.json +++ b/public/language/sc/admin/general/dashboard.json @@ -2,6 +2,9 @@ "forum-traffic": "Forum Traffic", "page-views": "Page Views", "unique-visitors": "Unique Visitors", + "users": "Users", + "posts": "Posts", + "topics": "Topics", "page-views-last-month": "Page views Last Month", "page-views-this-month": "Page views This Month", "page-views-last-day": "Page views in last 24 hours", @@ -20,6 +23,11 @@ "prerelease-warning": "

This is a pre-release version of NodeBB. Unintended bugs may occur.

", "notices": "Notices", + "restart-not-required": "Restart not required", + "restart-required": "Restart required", + "search-plugin-installed": "Search Plugin installed", + "search-plugin-not-installed": "Search Plugin not installed", + "search-plugin-tooltip": "Install a search plugin from the plugin page in order to activate search functionality", "control-panel": "System Control", "reload": "Reload", @@ -52,4 +60,4 @@ "graphs.unique-visitors": "Unique Visitors", "graphs.registered-users": "Registered Users", "graphs.anonymous-users": "Anonymous Users" -} \ No newline at end of file +} diff --git a/public/language/sk/admin/general/dashboard.json b/public/language/sk/admin/general/dashboard.json index b82802db1b..a70dda322e 100644 --- a/public/language/sk/admin/general/dashboard.json +++ b/public/language/sk/admin/general/dashboard.json @@ -2,6 +2,9 @@ "forum-traffic": "Forum Traffic", "page-views": "Page Views", "unique-visitors": "Unique Visitors", + "users": "Users", + "posts": "Posts", + "topics": "Topics", "page-views-last-month": "Page views Last Month", "page-views-this-month": "Page views This Month", "page-views-last-day": "Page views in last 24 hours", @@ -20,6 +23,11 @@ "prerelease-warning": "

This is a pre-release version of NodeBB. Unintended bugs may occur.

", "notices": "Notices", + "restart-not-required": "Restart not required", + "restart-required": "Restart required", + "search-plugin-installed": "Search Plugin installed", + "search-plugin-not-installed": "Search Plugin not installed", + "search-plugin-tooltip": "Install a search plugin from the plugin page in order to activate search functionality", "control-panel": "System Control", "reload": "Reload", @@ -52,4 +60,4 @@ "graphs.unique-visitors": "Unique Visitors", "graphs.registered-users": "Registered Users", "graphs.anonymous-users": "Anonymous Users" -} \ No newline at end of file +} diff --git a/public/language/sl/admin/general/dashboard.json b/public/language/sl/admin/general/dashboard.json index b82802db1b..a70dda322e 100644 --- a/public/language/sl/admin/general/dashboard.json +++ b/public/language/sl/admin/general/dashboard.json @@ -2,6 +2,9 @@ "forum-traffic": "Forum Traffic", "page-views": "Page Views", "unique-visitors": "Unique Visitors", + "users": "Users", + "posts": "Posts", + "topics": "Topics", "page-views-last-month": "Page views Last Month", "page-views-this-month": "Page views This Month", "page-views-last-day": "Page views in last 24 hours", @@ -20,6 +23,11 @@ "prerelease-warning": "

This is a pre-release version of NodeBB. Unintended bugs may occur.

", "notices": "Notices", + "restart-not-required": "Restart not required", + "restart-required": "Restart required", + "search-plugin-installed": "Search Plugin installed", + "search-plugin-not-installed": "Search Plugin not installed", + "search-plugin-tooltip": "Install a search plugin from the plugin page in order to activate search functionality", "control-panel": "System Control", "reload": "Reload", @@ -52,4 +60,4 @@ "graphs.unique-visitors": "Unique Visitors", "graphs.registered-users": "Registered Users", "graphs.anonymous-users": "Anonymous Users" -} \ No newline at end of file +} diff --git a/public/language/sr/admin/general/dashboard.json b/public/language/sr/admin/general/dashboard.json index b82802db1b..a70dda322e 100644 --- a/public/language/sr/admin/general/dashboard.json +++ b/public/language/sr/admin/general/dashboard.json @@ -2,6 +2,9 @@ "forum-traffic": "Forum Traffic", "page-views": "Page Views", "unique-visitors": "Unique Visitors", + "users": "Users", + "posts": "Posts", + "topics": "Topics", "page-views-last-month": "Page views Last Month", "page-views-this-month": "Page views This Month", "page-views-last-day": "Page views in last 24 hours", @@ -20,6 +23,11 @@ "prerelease-warning": "

This is a pre-release version of NodeBB. Unintended bugs may occur.

", "notices": "Notices", + "restart-not-required": "Restart not required", + "restart-required": "Restart required", + "search-plugin-installed": "Search Plugin installed", + "search-plugin-not-installed": "Search Plugin not installed", + "search-plugin-tooltip": "Install a search plugin from the plugin page in order to activate search functionality", "control-panel": "System Control", "reload": "Reload", @@ -52,4 +60,4 @@ "graphs.unique-visitors": "Unique Visitors", "graphs.registered-users": "Registered Users", "graphs.anonymous-users": "Anonymous Users" -} \ No newline at end of file +} diff --git a/public/language/sv/admin/general/dashboard.json b/public/language/sv/admin/general/dashboard.json index b82802db1b..a70dda322e 100644 --- a/public/language/sv/admin/general/dashboard.json +++ b/public/language/sv/admin/general/dashboard.json @@ -2,6 +2,9 @@ "forum-traffic": "Forum Traffic", "page-views": "Page Views", "unique-visitors": "Unique Visitors", + "users": "Users", + "posts": "Posts", + "topics": "Topics", "page-views-last-month": "Page views Last Month", "page-views-this-month": "Page views This Month", "page-views-last-day": "Page views in last 24 hours", @@ -20,6 +23,11 @@ "prerelease-warning": "

This is a pre-release version of NodeBB. Unintended bugs may occur.

", "notices": "Notices", + "restart-not-required": "Restart not required", + "restart-required": "Restart required", + "search-plugin-installed": "Search Plugin installed", + "search-plugin-not-installed": "Search Plugin not installed", + "search-plugin-tooltip": "Install a search plugin from the plugin page in order to activate search functionality", "control-panel": "System Control", "reload": "Reload", @@ -52,4 +60,4 @@ "graphs.unique-visitors": "Unique Visitors", "graphs.registered-users": "Registered Users", "graphs.anonymous-users": "Anonymous Users" -} \ No newline at end of file +} diff --git a/public/language/th/admin/general/dashboard.json b/public/language/th/admin/general/dashboard.json index b82802db1b..a70dda322e 100644 --- a/public/language/th/admin/general/dashboard.json +++ b/public/language/th/admin/general/dashboard.json @@ -2,6 +2,9 @@ "forum-traffic": "Forum Traffic", "page-views": "Page Views", "unique-visitors": "Unique Visitors", + "users": "Users", + "posts": "Posts", + "topics": "Topics", "page-views-last-month": "Page views Last Month", "page-views-this-month": "Page views This Month", "page-views-last-day": "Page views in last 24 hours", @@ -20,6 +23,11 @@ "prerelease-warning": "

This is a pre-release version of NodeBB. Unintended bugs may occur.

", "notices": "Notices", + "restart-not-required": "Restart not required", + "restart-required": "Restart required", + "search-plugin-installed": "Search Plugin installed", + "search-plugin-not-installed": "Search Plugin not installed", + "search-plugin-tooltip": "Install a search plugin from the plugin page in order to activate search functionality", "control-panel": "System Control", "reload": "Reload", @@ -52,4 +60,4 @@ "graphs.unique-visitors": "Unique Visitors", "graphs.registered-users": "Registered Users", "graphs.anonymous-users": "Anonymous Users" -} \ No newline at end of file +} diff --git a/public/language/tr/admin/general/dashboard.json b/public/language/tr/admin/general/dashboard.json index 3379d19afa..2f2493e435 100644 --- a/public/language/tr/admin/general/dashboard.json +++ b/public/language/tr/admin/general/dashboard.json @@ -2,6 +2,9 @@ "forum-traffic": "Forum Trafiği", "page-views": "Sayfa Gösterimi", "unique-visitors": "Unique Visitors", + "users": "Users", + "posts": "Posts", + "topics": "Topics", "page-views-last-month": "Page views Last Month", "page-views-this-month": "Page views This Month", "page-views-last-day": "Page views in last 24 hours", @@ -20,6 +23,11 @@ "prerelease-warning": "

This is a pre-release version of NodeBB. Unintended bugs may occur.

", "notices": "Notices", + "restart-not-required": "Restart not required", + "restart-required": "Restart required", + "search-plugin-installed": "Search Plugin installed", + "search-plugin-not-installed": "Search Plugin not installed", + "search-plugin-tooltip": "Install a search plugin from the plugin page in order to activate search functionality", "control-panel": "System Control", "reload": "Reload", @@ -52,4 +60,4 @@ "graphs.unique-visitors": "Unique Visitors", "graphs.registered-users": "Registered Users", "graphs.anonymous-users": "Anonymous Users" -} \ No newline at end of file +} diff --git a/public/language/vi/admin/general/dashboard.json b/public/language/vi/admin/general/dashboard.json index b82802db1b..a70dda322e 100644 --- a/public/language/vi/admin/general/dashboard.json +++ b/public/language/vi/admin/general/dashboard.json @@ -2,6 +2,9 @@ "forum-traffic": "Forum Traffic", "page-views": "Page Views", "unique-visitors": "Unique Visitors", + "users": "Users", + "posts": "Posts", + "topics": "Topics", "page-views-last-month": "Page views Last Month", "page-views-this-month": "Page views This Month", "page-views-last-day": "Page views in last 24 hours", @@ -20,6 +23,11 @@ "prerelease-warning": "

This is a pre-release version of NodeBB. Unintended bugs may occur.

", "notices": "Notices", + "restart-not-required": "Restart not required", + "restart-required": "Restart required", + "search-plugin-installed": "Search Plugin installed", + "search-plugin-not-installed": "Search Plugin not installed", + "search-plugin-tooltip": "Install a search plugin from the plugin page in order to activate search functionality", "control-panel": "System Control", "reload": "Reload", @@ -52,4 +60,4 @@ "graphs.unique-visitors": "Unique Visitors", "graphs.registered-users": "Registered Users", "graphs.anonymous-users": "Anonymous Users" -} \ No newline at end of file +} diff --git a/public/language/zh-CN/admin/general/dashboard.json b/public/language/zh-CN/admin/general/dashboard.json index dd4035371e..72c80aa352 100644 --- a/public/language/zh-CN/admin/general/dashboard.json +++ b/public/language/zh-CN/admin/general/dashboard.json @@ -2,6 +2,9 @@ "forum-traffic": "论坛流量", "page-views": "PV 数量", "unique-visitors": "单一访客", + "users": "Users", + "posts": "Posts", + "topics": "Topics", "page-views-last-month": "上个月 PV 数量", "page-views-this-month": "本月 PV 数量", "page-views-last-day": "过去24小时 PV 数量", @@ -20,6 +23,11 @@ "prerelease-warning": "

正在使用测试版 NodeBB。可能会出现意外的 Bug。

", "notices": "提醒", + "restart-not-required": "Restart not required", + "restart-required": "Restart required", + "search-plugin-installed": "Search Plugin installed", + "search-plugin-not-installed": "Search Plugin not installed", + "search-plugin-tooltip": "Install a search plugin from the plugin page in order to activate search functionality", "control-panel": "系统控制", "reload": "重载", @@ -52,4 +60,4 @@ "graphs.unique-visitors": "单一访客", "graphs.registered-users": "已注册用户", "graphs.anonymous-users": "匿名用户" -} \ No newline at end of file +} diff --git a/public/language/zh-TW/admin/general/dashboard.json b/public/language/zh-TW/admin/general/dashboard.json index b82802db1b..a70dda322e 100644 --- a/public/language/zh-TW/admin/general/dashboard.json +++ b/public/language/zh-TW/admin/general/dashboard.json @@ -2,6 +2,9 @@ "forum-traffic": "Forum Traffic", "page-views": "Page Views", "unique-visitors": "Unique Visitors", + "users": "Users", + "posts": "Posts", + "topics": "Topics", "page-views-last-month": "Page views Last Month", "page-views-this-month": "Page views This Month", "page-views-last-day": "Page views in last 24 hours", @@ -20,6 +23,11 @@ "prerelease-warning": "

This is a pre-release version of NodeBB. Unintended bugs may occur.

", "notices": "Notices", + "restart-not-required": "Restart not required", + "restart-required": "Restart required", + "search-plugin-installed": "Search Plugin installed", + "search-plugin-not-installed": "Search Plugin not installed", + "search-plugin-tooltip": "Install a search plugin from the plugin page in order to activate search functionality", "control-panel": "System Control", "reload": "Reload", @@ -52,4 +60,4 @@ "graphs.unique-visitors": "Unique Visitors", "graphs.registered-users": "Registered Users", "graphs.anonymous-users": "Anonymous Users" -} \ No newline at end of file +}