Skip to content

Commit

Permalink
Merge pull request #5219 from acburdine/controller-refactor
Browse files Browse the repository at this point in the history
Frontend Controller Refactor
  • Loading branch information
ErisDS committed May 5, 2015
2 parents 2ac3b14 + 8ac1687 commit 15b434d
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 125 deletions.
170 changes: 61 additions & 109 deletions core/server/controllers/frontend.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,55 +143,29 @@ 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
};

// No negative pages, or page 1
if (isNaN(pageParam) || pageParam < 1 || (pageParam === 1 && req.route.path === '/page/:page/')) {
return res.redirect(config.paths.subdir + '/');
},
hasSlug,
filter, filterKey;

// 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 + '/'));
}

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
};
function createUrl(page) {
var url = config.paths.subdir + channelOpts.route;

// Get url for tag page
function tagUrl(tag, page) {
var url = config.paths.subdir + '/' + config.routeKeywords.tag + '/' + tag + '/';
if (hasSlug) {
url = url.replace(':slug', options[channelOpts.name]);
}

if (page && page > 1) {
url += 'page/' + page + '/';
Expand All @@ -200,97 +174,75 @@ 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] : ''
});

// If the resulting tag is '' then 404.
if (!result.tag) {
return next();
var view = 'index',
result,
extra = {};

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 (page && page > 1) {
url += config.routeKeywords.page + '/' + page + '/';
}

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));
}
if (channelOpts.filter) {
extra[channelOpts.name] = (filterKey) ? filter : '';

setReqCtx(req, page.posts);
if (page.meta.filters.author) {
setReqCtx(req, page.meta.filters.author);
}
if (!extra[channelOpts.name]) {
return next();
}

// 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);
res.render(view, result);
});
});
}).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,
Expand Down
20 changes: 10 additions & 10 deletions core/server/helpers/template.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';
}

Expand Down
13 changes: 7 additions & 6 deletions core/test/unit/server_helpers_template_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand All @@ -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');
});
Expand Down

0 comments on commit 15b434d

Please sign in to comment.