From 8ac168794ecda3ec0251c11d57e0528719669370 Mon Sep 17 00:00:00 2001 From: Austin Burdine Date: Tue, 5 May 2015 00:21:29 -0500 Subject: [PATCH] refactors the frontend controller closes #5192 - combines homepage, author, tag routes into one function (with different hash params) - provides some abstraction for channels --- core/server/controllers/frontend.js | 166 +++++++----------- core/server/helpers/template.js | 20 +-- .../test/unit/server_helpers_template_spec.js | 13 +- 3 files changed, 76 insertions(+), 123 deletions(-) diff --git a/core/server/controllers/frontend.js b/core/server/controllers/frontend.js index 42ba420525..d29237f8b2 100644 --- a/core/server/controllers/frontend.js +++ b/core/server/controllers/frontend.js @@ -143,56 +143,30 @@ function renderPost(req, res) { }; } -frontendControllers = { - homepage: function (req, res, next) { - // Parse the page number +function renderChannel(channelOpts) { + channelOpts = channelOpts || {}; + + return function renderChannel(req, res, next) { var pageParam = req.params.page !== undefined ? parseInt(req.params.page, 10) : 1, options = { page: pageParam - }; + }, + hasSlug, + filter, filterKey; - // No negative pages, or page 1 - if (isNaN(pageParam) || pageParam < 1 || (pageParam === 1 && req.route.path === '/page/:page/')) { - return res.redirect(config.paths.subdir + '/'); + // Add the slug if it exists in the route + if (channelOpts.route.indexOf(':slug') !== -1) { + options[channelOpts.name] = req.params.slug; + hasSlug = true; } - return getPostPage(options).then(function (page) { - // If page is greater than number of pages we have, redirect to last page - if (pageParam > page.meta.pagination.pages) { - return res.redirect(page.meta.pagination.pages === 1 ? config.paths.subdir + '/' : (config.paths.subdir + '/page/' + page.meta.pagination.pages + '/')); + function createUrl(page) { + var url = config.paths.subdir + channelOpts.route; + + if (hasSlug) { + url = url.replace(':slug', options[channelOpts.name]); } - setReqCtx(req, page.posts); - - // Render the page of posts - filters.doFilter('prePostsRender', page.posts, res.locals).then(function (posts) { - getActiveThemePaths().then(function (paths) { - var view = paths.hasOwnProperty('home.hbs') ? 'home' : 'index'; - - // If we're on a page then we always render the index - // template. - if (pageParam > 1) { - view = 'index'; - } - - setResponseContext(req, res); - res.render(view, formatPageResponse(posts, page)); - }); - }); - }).catch(handleError(next)); - }, - tag: function (req, res, next) { - // Parse the page number - var pageParam = req.params.page !== undefined ? parseInt(req.params.page, 10) : 1, - options = { - page: pageParam, - tag: req.params.slug - }; - - // Get url for tag page - function tagUrl(tag, page) { - var url = config.paths.subdir + '/' + config.routeKeywords.tag + '/' + tag + '/'; - if (page && page > 1) { url += 'page/' + page + '/'; } @@ -200,88 +174,47 @@ frontendControllers = { return url; } - // No negative pages, or page 1 if (isNaN(pageParam) || pageParam < 1 || (req.params.page !== undefined && pageParam === 1)) { - return res.redirect(tagUrl(options.tag)); + return res.redirect(createUrl()); } return getPostPage(options).then(function (page) { // If page is greater than number of pages we have, redirect to last page if (pageParam > page.meta.pagination.pages) { - return res.redirect(tagUrl(options.tag, page.meta.pagination.pages)); + return res.redirect(createUrl(page.meta.pagination.pages)); } setReqCtx(req, page.posts); - if (page.meta.filters.tags) { - setReqCtx(req, page.meta.filters.tags[0]); + if (channelOpts.filter && page.meta.filters[channelOpts.filter]) { + filterKey = page.meta.filters[channelOpts.filter]; + filter = (_.isArray(filterKey)) ? filterKey[0] : filterKey; + setReqCtx(req, filter); } - // Render the page of posts filters.doFilter('prePostsRender', page.posts, res.locals).then(function (posts) { getActiveThemePaths().then(function (paths) { - var view = template.getThemeViewForTag(paths, options.tag), - // Format data for template - result = formatPageResponse(posts, page, { - tag: page.meta.filters.tags ? page.meta.filters.tags[0] : '' - }); + var view = 'index', + result, + extra = {}; - // If the resulting tag is '' then 404. - if (!result.tag) { - return next(); + if (channelOpts.firstPageTemplate && paths.hasOwnProperty(channelOpts.firstPageTemplate + '.hbs')) { + view = (pageParam > 1) ? 'index' : channelOpts.firstPageTemplate; + } else if (channelOpts.slugTemplate) { + view = template.getThemeViewForChannel(paths, channelOpts.name, options[channelOpts.name]); + } else if (paths.hasOwnProperty(channelOpts.name + '.hbs')) { + view = channelOpts.name; } - setResponseContext(req, res); - res.render(view, result); - }); - }); - }).catch(handleError(next)); - }, - author: function (req, res, next) { - // Parse the page number - var pageParam = req.params.page !== undefined ? parseInt(req.params.page, 10) : 1, - options = { - page: pageParam, - author: req.params.slug - }; - // Get url for tag page - function authorUrl(author, page) { - var url = config.paths.subdir + '/' + config.routeKeywords.author + '/' + author + '/'; + if (channelOpts.filter) { + extra[channelOpts.name] = (filterKey) ? filter : ''; - if (page && page > 1) { - url += config.routeKeywords.page + '/' + page + '/'; - } + if (!extra[channelOpts.name]) { + return next(); + } - return url; - } - - // No negative pages, or page 1 - if (isNaN(pageParam) || pageParam < 1 || (req.params.page !== undefined && pageParam === 1)) { - return res.redirect(authorUrl(options.author)); - } - - return getPostPage(options).then(function (page) { - // If page is greater than number of pages we have, redirect to last page - if (pageParam > page.meta.pagination.pages) { - return res.redirect(authorUrl(options.author, page.meta.pagination.pages)); - } - - setReqCtx(req, page.posts); - if (page.meta.filters.author) { - setReqCtx(req, page.meta.filters.author); - } - - // Render the page of posts - filters.doFilter('prePostsRender', page.posts, res.locals).then(function (posts) { - getActiveThemePaths().then(function (paths) { - var view = paths.hasOwnProperty('author.hbs') ? 'author' : 'index', - // Format data for template - result = formatPageResponse(posts, page, { - author: page.meta.filters.author ? page.meta.filters.author : '' - }); - - // If the resulting author is '' then 404. - if (!result.author) { - return next(); + result = formatPageResponse(posts, page, extra); + } else { + result = formatPageResponse(posts, page); } setResponseContext(req, res); @@ -289,8 +222,27 @@ frontendControllers = { }); }); }).catch(handleError(next)); - }, + }; +} +frontendControllers = { + homepage: renderChannel({ + name: 'home', + route: '/', + firstPageTemplate: 'home' + }), + tag: renderChannel({ + name: 'tag', + route: '/' + config.routeKeywords.tag + '/:slug/', + filter: 'tags', + slugTemplate: true + }), + author: renderChannel({ + name: 'author', + route: '/' + config.routeKeywords.author + '/:slug/', + filter: 'author', + slugTemplate: true + }), preview: function (req, res, next) { var params = { uuid: req.params.uuid, diff --git a/core/server/helpers/template.js b/core/server/helpers/template.js index 3414e7c27b..e3ac69bc08 100644 --- a/core/server/helpers/template.js +++ b/core/server/helpers/template.js @@ -44,21 +44,21 @@ templates.getThemeViewForPost = function (themePaths, post) { return view; }; -// Given a theme object and a tag slug this will return +// Given a theme object and a slug this will return // which theme template page should be used. // If no default or custom tag template exists then 'index' // will be returned -// If no custom tag template exists but a default does then -// 'tag' will be returned -// If given a tag slug and a custom tag template +// If no custom template exists but a default does then +// the default will be returned +// If given a slug and a custom template // exits it will return that view. -templates.getThemeViewForTag = function (themePaths, tag) { - var customTagView = 'tag-' + tag, - view = 'tag'; +templates.getThemeViewForChannel = function (themePaths, channelName, slug) { + var customChannelView = channelName + '-' + slug, + view = channelName; - if (themePaths.hasOwnProperty(customTagView + '.hbs')) { - view = customTagView; - } else if (!themePaths.hasOwnProperty('tag.hbs')) { + if (themePaths.hasOwnProperty(customChannelView + '.hbs')) { + view = customChannelView; + } else if (!themePaths.hasOwnProperty(channelName + '.hbs')) { view = 'index'; } diff --git a/core/test/unit/server_helpers_template_spec.js b/core/test/unit/server_helpers_template_spec.js index 5e94ebb403..d4b1fa0bef 100644 --- a/core/test/unit/server_helpers_template_spec.js +++ b/core/test/unit/server_helpers_template_spec.js @@ -51,7 +51,7 @@ describe('Helpers Template', function () { }); }); - describe('getThemeViewForTag', function () { + describe('getThemeViewForChannel', function () { var themePathsWithTagViews = { assets: null, 'default.hbs': '/content/themes/casper/default.hbs', @@ -64,19 +64,20 @@ describe('Helpers Template', function () { 'default.hbs': '/content/themes/casper/default.hbs', 'index.hbs': '/content/themes/casper/index.hbs' }, - TAG_CUSTOM_EXISTS = 'design', - TAG_DEFAULT = 'development'; + CHANNEL = 'tag', + CUSTOM_EXISTS = 'design', + DEFAULT = 'development'; it('will return correct view for a tag', function () { - var view = template.getThemeViewForTag(themePathsWithTagViews, TAG_CUSTOM_EXISTS); + var view = template.getThemeViewForChannel(themePathsWithTagViews, CHANNEL, CUSTOM_EXISTS); view.should.exist; view.should.eql('tag-design'); - view = template.getThemeViewForTag(themePathsWithTagViews, TAG_DEFAULT); + view = template.getThemeViewForChannel(themePathsWithTagViews, CHANNEL, DEFAULT); view.should.exist; view.should.eql('tag'); - view = template.getThemeViewForTag(themePaths, TAG_DEFAULT); + view = template.getThemeViewForChannel(themePaths, CHANNEL, DEFAULT); view.should.exist; view.should.eql('index'); });