diff --git a/install/data/defaults.json b/install/data/defaults.json index 4ddf385e8a..c471db6b89 100644 --- a/install/data/defaults.json +++ b/install/data/defaults.json @@ -34,5 +34,6 @@ "teaserPost": "last-reply", "allowPrivateGroups": 1, "unreadCutoff": 2, - "bookmarkThreshold": 5 + "bookmarkThreshold": 5, + "topicsPerList": 20 } diff --git a/src/controllers/categories.js b/src/controllers/categories.js index aa882b9b43..7e3e4b0efe 100644 --- a/src/controllers/categories.js +++ b/src/controllers/categories.js @@ -1,14 +1,11 @@ "use strict"; - var async = require('async'); var nconf = require('nconf'); var validator = require('validator'); var categories = require('../categories'); var meta = require('../meta'); -var plugins = require('../plugins'); - var helpers = require('./helpers'); var categoriesController = {}; @@ -51,34 +48,32 @@ categoriesController.list = function(req, res, next) { categories.flattenCategories(allCategories, categoryData); categories.getRecentTopicReplies(allCategories, req.uid, next); - }, - function (next) { - var data = { - title: '[[pages:categories]]', - categories: categoryData - }; - - if (req.path.startsWith('/api/categories') || req.path.startsWith('/categories')) { - data.breadcrumbs = helpers.buildBreadcrumbs([{text: data.title}]); - } - - data.categories.forEach(function(category) { - if (category && Array.isArray(category.posts) && category.posts.length) { - category.teaser = { - url: nconf.get('relative_path') + '/topic/' + category.posts[0].topic.slug + '/' + category.posts[0].index, - timestampISO: category.posts[0].timestampISO, - pid: category.posts[0].pid - }; - } - }); - - plugins.fireHook('filter:categories.build', {req: req, res: res, templateData: data}, next); } - ], function(err, data) { + ], function(err) { if (err) { return next(err); } - res.render('categories', data.templateData); + + var data = { + title: '[[pages:categories]]', + categories: categoryData + }; + + if (req.path.startsWith('/api/categories') || req.path.startsWith('/categories')) { + data.breadcrumbs = helpers.buildBreadcrumbs([{text: data.title}]); + } + + data.categories.forEach(function(category) { + if (category && Array.isArray(category.posts) && category.posts.length) { + category.teaser = { + url: nconf.get('relative_path') + '/topic/' + category.posts[0].topic.slug + '/' + category.posts[0].index, + timestampISO: category.posts[0].timestampISO, + pid: category.posts[0].pid + }; + } + }); + + res.render('categories', data); }); }; diff --git a/src/controllers/category.js b/src/controllers/category.js index f80ad122a7..f2bc7510c6 100644 --- a/src/controllers/category.js +++ b/src/controllers/category.js @@ -9,7 +9,6 @@ var privileges = require('../privileges'); var user = require('../user'); var categories = require('../categories'); var meta = require('../meta'); -var plugins = require('../plugins'); var pagination = require('../pagination'); var helpers = require('./helpers'); var utils = require('../../public/src/utils'); @@ -143,65 +142,63 @@ categoryController.get = function(req, res, callback) { categories.getRecentTopicReplies(allCategories, req.uid, function(err) { next(err, categoryData); }); - }, - function (categoryData, next) { - categoryData.privileges = userPrivileges; - categoryData.showSelect = categoryData.privileges.editable; - - res.locals.metaTags = [ - { - name: 'title', - content: categoryData.name - }, - { - property: 'og:title', - content: categoryData.name - }, - { - name: 'description', - content: categoryData.description - }, - { - property: "og:type", - content: 'website' - } - ]; + } + ], function (err, categoryData) { + if (err) { + return callback(err); + } - if (categoryData.backgroundImage) { - res.locals.metaTags.push({ - name: 'og:image', - content: categoryData.backgroundImage - }); + categoryData.privileges = userPrivileges; + categoryData.showSelect = categoryData.privileges.editable; + + res.locals.metaTags = [ + { + name: 'title', + content: categoryData.name + }, + { + property: 'og:title', + content: categoryData.name + }, + { + name: 'description', + content: categoryData.description + }, + { + property: "og:type", + content: 'website' } + ]; - res.locals.linkTags = [ - { - rel: 'alternate', - type: 'application/rss+xml', - href: nconf.get('url') + '/category/' + cid + '.rss' - }, - { - rel: 'up', - href: nconf.get('url') - } - ]; - - categoryData['feeds:disableRSS'] = parseInt(meta.config['feeds:disableRSS'], 10) === 1; - categoryData.rssFeedUrl = nconf.get('relative_path') + '/category/' + categoryData.cid + '.rss'; - categoryData.title = categoryData.name; - categoryData.pagination = pagination.create(currentPage, pageCount); - categoryData.pagination.rel.forEach(function(rel) { - rel.href = nconf.get('url') + '/category/' + categoryData.slug + rel.href; - res.locals.linkTags.push(rel); + if (categoryData.backgroundImage) { + res.locals.metaTags.push({ + name: 'og:image', + content: categoryData.backgroundImage }); - - plugins.fireHook('filter:category.build', {req: req, res: res, templateData: categoryData}, next); } - ], function (err, data) { - if (err) { - return callback(err); - } - res.render('category', data.templateData); + + res.locals.linkTags = [ + { + rel: 'alternate', + type: 'application/rss+xml', + href: nconf.get('url') + '/category/' + cid + '.rss' + }, + { + rel: 'up', + href: nconf.get('url') + } + ]; + + categoryData['feeds:disableRSS'] = parseInt(meta.config['feeds:disableRSS'], 10) === 1; + categoryData.rssFeedUrl = nconf.get('relative_path') + '/category/' + categoryData.cid + '.rss'; + categoryData.title = categoryData.name; + categoryData.pagination = pagination.create(currentPage, pageCount); + categoryData.pagination.rel.forEach(function(rel) { + rel.href = nconf.get('url') + '/category/' + categoryData.slug + rel.href; + res.locals.linkTags.push(rel); + }); + + res.render('category', categoryData); }); }; diff --git a/src/controllers/groups.js b/src/controllers/groups.js index 837ba3b1f6..588a44d56f 100644 --- a/src/controllers/groups.js +++ b/src/controllers/groups.js @@ -1,14 +1,15 @@ "use strict"; -var async = require('async'), - nconf = require('nconf'), - validator = require('validator'), - meta = require('../meta'), - groups = require('../groups'), - user = require('../user'), - helpers = require('./helpers'), - plugins = require('../plugins'), - groupsController = {}; +var async = require('async'); +var nconf = require('nconf'); +var validator = require('validator'); + +var meta = require('../meta'); +var groups = require('../groups'); +var user = require('../user'); +var helpers = require('./helpers'); + +var groupsController = {}; groupsController.list = function(req, res, next) { var sort = req.query.sort || 'alpha'; @@ -83,22 +84,20 @@ groupsController.details = function(req, res, callback) { }, isAdmin: async.apply(user.isAdministrator, req.uid) }, next); - }, - function (results, next) { - if (!results.group) { - return callback(); - } - results.title = '[[pages:group, ' + results.group.displayName + ']]'; - results.breadcrumbs = helpers.buildBreadcrumbs([{text: '[[pages:groups]]', url: '/groups' }, {text: results.group.displayName}]); - results.allowPrivateGroups = parseInt(meta.config.allowPrivateGroups, 10) === 1; - plugins.fireHook('filter:group.build', {req: req, res: res, templateData: results}, next); } ], function(err, results) { if (err) { return callback(err); } - res.render('groups/details', results.templateData); + if (!results.group) { + return callback(); + } + results.title = '[[pages:group, ' + results.group.displayName + ']]'; + results.breadcrumbs = helpers.buildBreadcrumbs([{text: '[[pages:groups]]', url: '/groups' }, {text: results.group.displayName}]); + results.allowPrivateGroups = parseInt(meta.config.allowPrivateGroups, 10) === 1; + + res.render('groups/details', results); }); }; diff --git a/src/controllers/index.js b/src/controllers/index.js index 598587a434..282d6c1f0a 100644 --- a/src/controllers/index.js +++ b/src/controllers/index.js @@ -134,32 +134,29 @@ Controllers.register = function(req, res, next) { }, function(next) { plugins.fireHook('filter:parse.post', {postData: {content: meta.config.termsOfUse || ''}}, next); - }, - function(tos, next) { - var loginStrategies = require('../routes/authentication').getLoginStrategies(); - var data = { - 'register_window:spansize': loginStrategies.length ? 'col-md-6' : 'col-md-12', - 'alternate_logins': !!loginStrategies.length - }; - - data.authentication = loginStrategies; - - data.minimumUsernameLength = parseInt(meta.config.minimumUsernameLength, 10); - data.maximumUsernameLength = parseInt(meta.config.maximumUsernameLength, 10); - data.minimumPasswordLength = parseInt(meta.config.minimumPasswordLength, 10); - data.termsOfUse = tos.postData.content; - data.breadcrumbs = helpers.buildBreadcrumbs([{text: '[[register:register]]'}]); - data.regFormEntry = []; - data.error = req.flash('error')[0]; - data.title = '[[pages:register]]'; - - plugins.fireHook('filter:register.build', {req: req, res: res, templateData: data}, next); } - ], function(err, data) { + ], function(err, termsOfUse) { if (err) { return next(err); } - res.render('register', data.templateData); + var loginStrategies = require('../routes/authentication').getLoginStrategies(); + var data = { + 'register_window:spansize': loginStrategies.length ? 'col-md-6' : 'col-md-12', + 'alternate_logins': !!loginStrategies.length + }; + + data.authentication = loginStrategies; + + data.minimumUsernameLength = parseInt(meta.config.minimumUsernameLength, 10); + data.maximumUsernameLength = parseInt(meta.config.maximumUsernameLength, 10); + data.minimumPasswordLength = parseInt(meta.config.minimumPasswordLength, 10); + data.termsOfUse = termsOfUse.postData.content; + data.breadcrumbs = helpers.buildBreadcrumbs([{text: '[[register:register]]'}]); + data.regFormEntry = []; + data.error = req.flash('error')[0]; + data.title = '[[pages:register]]'; + + res.render('register', data); }); }; diff --git a/src/controllers/popular.js b/src/controllers/popular.js index 813f3527b8..353fd9e33c 100644 --- a/src/controllers/popular.js +++ b/src/controllers/popular.js @@ -1,15 +1,15 @@ 'use strict'; -var nconf = require('nconf'), - topics = require('../topics'), - plugins = require('../plugins'), - meta = require('../meta'), - helpers = require('./helpers'); +var nconf = require('nconf'); +var topics = require('../topics'); +var meta = require('../meta'); +var helpers = require('./helpers'); var popularController = {}; -var anonCache = {}, lastUpdateTime = 0; +var anonCache = {}; +var lastUpdateTime = 0; var terms = { daily: 'day', @@ -48,7 +48,8 @@ popularController.get = function(req, res, next) { topics: topics, 'feeds:disableRSS': parseInt(meta.config['feeds:disableRSS'], 10) === 1, rssFeedUrl: nconf.get('relative_path') + '/popular/' + (req.params.term || 'daily') + '.rss', - title: '[[pages:popular-' + term + ']]' + title: '[[pages:popular-' + term + ']]', + term: term }; if (req.path.startsWith('/api/popular') || req.path.startsWith('/popular')) { @@ -66,12 +67,7 @@ popularController.get = function(req, res, next) { lastUpdateTime = Date.now(); } - plugins.fireHook('filter:popular.build', {req: req, res: res, term: term, templateData: data}, function(err, data) { - if (err) { - return next(err); - } - res.render('popular', data.templateData); - }); + res.render('popular', data); }); }; diff --git a/src/controllers/recent.js b/src/controllers/recent.js index 242d26ac12..6883929be4 100644 --- a/src/controllers/recent.js +++ b/src/controllers/recent.js @@ -2,11 +2,10 @@ 'use strict'; var nconf = require('nconf'); -var async = require('async'); + var topics = require('../topics'); var meta = require('../meta'); var helpers = require('./helpers'); -var plugins = require('../plugins'); var recentController = {}; @@ -14,25 +13,19 @@ recentController.get = function(req, res, next) { var stop = (parseInt(meta.config.topicsPerList, 10) || 20) - 1; - async.waterfall([ - function (next) { - topics.getTopicsFromSet('topics:recent', req.uid, 0, stop, next); - }, - function (data, next) { - data['feeds:disableRSS'] = parseInt(meta.config['feeds:disableRSS'], 10) === 1; - data.rssFeedUrl = nconf.get('relative_path') + '/recent.rss'; - data.title = '[[pages:recent]]'; - if (req.path.startsWith('/api/recent') || req.path.startsWith('/recent')) { - data.breadcrumbs = helpers.buildBreadcrumbs([{text: '[[recent:title]]'}]); - } - - plugins.fireHook('filter:recent.build', {req: req, res: res, templateData: data}, next); - } - ], function(err, data) { + topics.getTopicsFromSet('topics:recent', req.uid, 0, stop, function(err, data) { if (err) { return next(err); } - res.render('recent', data.templateData); + + data['feeds:disableRSS'] = parseInt(meta.config['feeds:disableRSS'], 10) === 1; + data.rssFeedUrl = nconf.get('relative_path') + '/recent.rss'; + data.title = '[[pages:recent]]'; + if (req.path.startsWith('/api/recent') || req.path.startsWith('/recent')) { + data.breadcrumbs = helpers.buildBreadcrumbs([{text: '[[recent:title]]'}]); + } + + res.render('recent', data); }); }; diff --git a/src/controllers/search.js b/src/controllers/search.js index dee14e7c1f..2a7f6b145c 100644 --- a/src/controllers/search.js +++ b/src/controllers/search.js @@ -1,14 +1,14 @@ 'use strict'; -var async = require('async'), +var async = require('async'); - meta = require('../meta'), - plugins = require('../plugins'), - search = require('../search'), - categories = require('../categories'), - pagination = require('../pagination'), - helpers = require('./helpers'); +var meta = require('../meta'); +var plugins = require('../plugins'); +var search = require('../search'); +var categories = require('../categories'); +var pagination = require('../pagination'); +var helpers = require('./helpers'); var searchController = {}; @@ -61,12 +61,7 @@ searchController.search = function(req, res, next) { searchData.breadcrumbs = helpers.buildBreadcrumbs([{text: '[[global:search]]'}]); searchData.expandSearch = !req.params.term; - plugins.fireHook('filter:search.build', {data: data, results: searchData}, function(err, data) { - if (err) { - return next(err); - } - res.render('search', data.results); - }); + res.render('search', searchData); }); }; diff --git a/src/controllers/topics.js b/src/controllers/topics.js index c62ad30545..6b7793f58c 100644 --- a/src/controllers/topics.js +++ b/src/controllers/topics.js @@ -288,12 +288,7 @@ topicsController.get = function(req, res, callback) { }); } - plugins.fireHook('filter:topic.build', {req: req, res: res, templateData: data}, function(err, data) { - if (err) { - return callback(err); - } - res.render('topic', data.templateData); - }); + res.render('topic', data); }); }; diff --git a/src/controllers/unread.js b/src/controllers/unread.js index d3655fd050..1d80774fb0 100644 --- a/src/controllers/unread.js +++ b/src/controllers/unread.js @@ -8,7 +8,6 @@ var privileges = require('../privileges'); var user = require('../user'); var topics = require('../topics'); var helpers = require('./helpers'); -var plugins = require('../plugins'); var unreadController = {}; @@ -42,47 +41,44 @@ unreadController.get = function(req, res, next) { }, function(cids, next) { categories.getCategoriesFields(cids, ['cid', 'name', 'slug', 'icon', 'link', 'color', 'bgColor'], next); - }, - function(categories, next) { - categories = categories.filter(function(category) { - return category && !category.link; - }); - categories.forEach(function(category) { - category.selected = parseInt(category.cid, 10) === parseInt(cid, 10); - if (category.selected) { - results.unreadTopics.selectedCategory = category; - } - }); - results.unreadTopics.categories = categories; - - results.unreadTopics.breadcrumbs = helpers.buildBreadcrumbs([{text: '[[unread:title]]'}]); - results.unreadTopics.title = '[[pages:unread]]'; - results.unreadTopics.filters = [{ - name: '[[unread:all-topics]]', - url: 'unread', - selected: filter === '' - }, { - name: '[[unread:new-topics]]', - url: 'unread/new', - selected: filter === 'new' - }, { - name: '[[unread:watched-topics]]', - url: 'unread/watched', - selected: filter === 'watched' - }]; - - results.unreadTopics.selectedFilter = results.unreadTopics.filters.filter(function(filter) { - return filter && filter.selected; - })[0]; - - plugins.fireHook('filter:unread.build', {req: req, res: res, templateData: results.unreadTopics}, next); } - ], function(err, data) { + ], function(err, categories) { if (err) { return next(err); } - res.render('unread', data.templateData); + categories = categories.filter(function(category) { + return category && !category.link; + }); + categories.forEach(function(category) { + category.selected = parseInt(category.cid, 10) === parseInt(cid, 10); + if (category.selected) { + results.unreadTopics.selectedCategory = category; + } + }); + results.unreadTopics.categories = categories; + + results.unreadTopics.breadcrumbs = helpers.buildBreadcrumbs([{text: '[[unread:title]]'}]); + results.unreadTopics.title = '[[pages:unread]]'; + results.unreadTopics.filters = [{ + name: '[[unread:all-topics]]', + url: 'unread', + selected: filter === '' + }, { + name: '[[unread:new-topics]]', + url: 'unread/new', + selected: filter === 'new' + }, { + name: '[[unread:watched-topics]]', + url: 'unread/watched', + selected: filter === 'watched' + }]; + + results.unreadTopics.selectedFilter = results.unreadTopics.filters.filter(function(filter) { + return filter && filter.selected; + })[0]; + + res.render('unread', results.unreadTopics); }); }; diff --git a/src/controllers/users.js b/src/controllers/users.js index 31ac0bd1cc..476766e7ba 100644 --- a/src/controllers/users.js +++ b/src/controllers/users.js @@ -5,7 +5,6 @@ var user = require('../user'); var meta = require('../meta'); var pagination = require('../pagination'); -var plugins = require('../plugins'); var db = require('../database'); var helpers = require('./helpers'); @@ -165,26 +164,20 @@ usersController.getUsersAndCount = function(set, uid, start, stop, callback) { }; function render(req, res, data, next) { - plugins.fireHook('filter:users.build', {req: req, res: res, templateData: data }, function(err, data) { + var registrationType = meta.config.registrationType; + + data.maximumInvites = meta.config.maximumInvites; + data.inviteOnly = registrationType === 'invite-only' || registrationType === 'admin-invite-only'; + data.adminInviteOnly = registrationType === 'admin-invite-only'; + data['reputation:disabled'] = parseInt(meta.config['reputation:disabled'], 10) === 1; + + user.getInvitesNumber(req.uid, function(err, num) { if (err) { return next(err); } - var registrationType = meta.config.registrationType; - - data.templateData.maximumInvites = meta.config.maximumInvites; - data.templateData.inviteOnly = registrationType === 'invite-only' || registrationType === 'admin-invite-only'; - data.templateData.adminInviteOnly = registrationType === 'admin-invite-only'; - data.templateData['reputation:disabled'] = parseInt(meta.config['reputation:disabled'], 10) === 1; - - user.getInvitesNumber(req.uid, function(err, num) { - if (err) { - return next(err); - } - - data.templateData.invites = num; - res.render('users', data.templateData); - }); + data.invites = num; + res.render('users', data); }); } diff --git a/src/middleware/render.js b/src/middleware/render.js index 79911f71bd..0dd0543600 100644 --- a/src/middleware/render.js +++ b/src/middleware/render.js @@ -1,6 +1,8 @@ 'use strict'; var nconf = require('nconf'); + +var plugins = require('../plugins'); var translator = require('../../public/src/modules/translator'); module.exports = function(middleware) { @@ -9,78 +11,86 @@ module.exports = function(middleware) { // res.render post-processing, modified from here: https://gist.github.com/mrlannigan/5051687 var render = res.render; res.render = function(template, options, fn) { - var self = this, - req = this.req, - defaultFn = function(err, str){ - if (err) { - return next(err); - } + var self = this; + var req = this.req; + var defaultFn = function(err, str) { + if (err) { + return next(err); + } - self.send(str); - }; - options = options || {}; + self.send(str); + }; + options = options || {}; if ('function' === typeof options) { fn = options; options = {}; } - options.loggedIn = !!req.uid; - options.relative_path = nconf.get('relative_path'); - options.template = {name: template}; - options.template[template] = true; - options.bodyClass = buildBodyClass(req); + plugins.fireHook('filter:' + template + '.build', {req: req, res: res, templateData: options}, function(err, data) { + if (err) { + return next(err); + } - res.locals.template = template; - options._locals = undefined; + options = data.templateData; - if (res.locals.isAPI) { - if (req.route && req.route.path === '/api/') { - options.title = '[[pages:home]]'; - } + options.loggedIn = !!req.uid; + options.relative_path = nconf.get('relative_path'); + options.template = {name: template}; + options.template[template] = true; + options.bodyClass = buildBodyClass(req); - return res.json(options); - } + res.locals.template = template; + options._locals = undefined; - if ('function' !== typeof fn) { - fn = defaultFn; - } + if (res.locals.isAPI) { + if (req.route && req.route.path === '/api/') { + options.title = '[[pages:home]]'; + } - var ajaxifyData = JSON.stringify(options); - ajaxifyData = ajaxifyData.replace(/<\//g, '<\\/'); + return res.json(options); + } - render.call(self, template, options, function(err, str) { - if (err) { - return fn(err); + if ('function' !== typeof fn) { + fn = defaultFn; } - str = (res.locals.postHeader ? res.locals.postHeader : '') + str + (res.locals.preFooter ? res.locals.preFooter : ''); + var ajaxifyData = JSON.stringify(options); + ajaxifyData = ajaxifyData.replace(/<\//g, '<\\/'); - if (res.locals.footer) { - str = str + res.locals.footer; - } else if (res.locals.adminFooter) { - str = str + res.locals.adminFooter; - } + render.call(self, template, options, function(err, str) { + if (err) { + return fn(err); + } - if (res.locals.renderHeader || res.locals.renderAdminHeader) { - var method = res.locals.renderHeader ? middleware.renderHeader : middleware.admin.renderHeader; - method(req, res, options, function(err, template) { - if (err) { - return fn(err); - } - str = template + str; - var language = res.locals.config ? res.locals.config.userLang || 'en_GB' : 'en_GB'; - language = req.query.lang || language; - translator.translate(str, language, function(translated) { - translated = translator.unescape(translated); - translated = translated + ''; - fn(err, translated); + str = (res.locals.postHeader ? res.locals.postHeader : '') + str + (res.locals.preFooter ? res.locals.preFooter : ''); + + if (res.locals.footer) { + str = str + res.locals.footer; + } else if (res.locals.adminFooter) { + str = str + res.locals.adminFooter; + } + + if (res.locals.renderHeader || res.locals.renderAdminHeader) { + var method = res.locals.renderHeader ? middleware.renderHeader : middleware.admin.renderHeader; + method(req, res, options, function(err, template) { + if (err) { + return fn(err); + } + str = template + str; + var language = res.locals.config ? res.locals.config.userLang || 'en_GB' : 'en_GB'; + language = req.query.lang || language; + translator.translate(str, language, function(translated) { + translated = translator.unescape(translated); + translated = translated + ''; + fn(err, translated); + }); }); - }); - } else { - str = str + ''; - fn(err, str); - } + } else { + str = str + ''; + fn(err, str); + } + }); }); }; diff --git a/src/navigation/admin.js b/src/navigation/admin.js index a803b5465b..7db567b90b 100644 --- a/src/navigation/admin.js +++ b/src/navigation/admin.js @@ -62,12 +62,7 @@ function getAvailable(callback) { return item; }); - // DEPRECATION: backwards compatibility for filter:header.build, will be removed soon. - plugins.fireHook('filter:header.build', {navigation: []}, function(err, data) { - core = core.concat(data.navigation); - - plugins.fireHook('filter:navigation.available', core, callback); - }); + plugins.fireHook('filter:navigation.available', core, callback); } module.exports = admin; \ No newline at end of file diff --git a/src/topics/popular.js b/src/topics/popular.js index 88d5a6819a..5ab53ae613 100644 --- a/src/topics/popular.js +++ b/src/topics/popular.js @@ -1,10 +1,8 @@ 'use strict'; -var async = require('async'), - db = require('../database'), - privileges = require('../privileges'); - +var async = require('async'); +var privileges = require('../privileges'); module.exports = function(Topics) {