Skip to content

Commit

Permalink
Rss support for tags
Browse files Browse the repository at this point in the history
closes TryGhost#2260
- added routes for /tag/:slug/rss and /tag/:slug/rss/:page
- added support for tag in the rss controller
- added route tests for each extra case
- fixing a tiny typo in some test descriptions
  • Loading branch information
stenehall committed Mar 12, 2014
1 parent a806f3e commit 4556e1d
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 28 deletions.
65 changes: 43 additions & 22 deletions core/server/controllers/frontend.js
Original file line number Diff line number Diff line change
Expand Up @@ -252,11 +252,16 @@ frontendControllers = {
'rss': function (req, res, next) {
// Initialize RSS
var pageParam = req.params.page !== undefined ? parseInt(req.params.page, 10) : 1,
feed;
tagParam = req.params.slug;

// No negative pages, or page 1
if (isNaN(pageParam) || pageParam < 1 || (pageParam === 1 && req.route.path === '/rss/:page/')) {
return res.redirect(config().paths.subdir + '/rss/');
if (isNaN(pageParam) || pageParam < 1 ||
(pageParam === 1 && (req.route.path === '/rss/:page/' || req.route.path === '/tag/:slug/rss/:page/'))) {
if (tagParam !== undefined) {
return res.redirect(config().paths.subdir + '/tag/' + tagParam + '/rss/');
} else {
return res.redirect(config().paths.subdir + '/rss/');
}
}

// TODO: needs refactor for multi user to not use first user as default
Expand All @@ -266,25 +271,37 @@ frontendControllers = {
api.settings.read('description'),
api.settings.read('permalinks')
]).then(function (result) {
var user = result[0].value,
title = result[1].value.value,
description = result[2].value.value,
permalinks = result[3].value,
siteUrl = config.urlFor('home', null, true),
feedUrl = config.urlFor('rss', null, true);

feed = new RSS({
title: title,
description: description,
generator: 'Ghost v' + res.locals.version,
feed_url: feedUrl,
site_url: siteUrl,
ttl: '60'
});

return api.posts.browse({page: pageParam}).then(function (page) {
var maxPage = page.pages,
feedItems = [];
var options = {};
if (pageParam) { options.page = pageParam; }
if (tagParam) { options.tag = tagParam; }

return api.posts.browse(options).then(function (page) {

var user = result[0].value,
title = result[1].value.value,
description = result[2].value.value,
permalinks = result[3].value,
siteUrl = config.urlFor('home', null, true),
feedUrl = config.urlFor('rss', null, true),
maxPage = page.pages,
feedItems = [],
feed;

if (tagParam) {
title = page.aspect.tag.name + ' - ' + title;
feedUrl = feedUrl + 'tag/' + page.aspect.tag.slug + '/';
}

feed = new RSS({
title: title,
description: description,
generator: 'Ghost v' + res.locals.version,
feed_url: feedUrl,
site_url: siteUrl,
ttl: '60'
});


// A bit of a hack for situations with no content.
if (maxPage === 0) {
Expand All @@ -294,7 +311,11 @@ frontendControllers = {

// If page is greater than number of pages we have, redirect to last page
if (pageParam > maxPage) {
return res.redirect(config().paths.subdir + '/rss/' + maxPage + '/');
if (tagParam) {
return res.redirect(config().paths.subdir + '/tag/' + tagParam + '/rss/' + maxPage + '/');
} else {
return res.redirect(config().paths.subdir + '/rss/' + maxPage + '/');
}
}

filters.doFilter('prePostsRender', page.posts).then(function (posts) {
Expand Down
2 changes: 2 additions & 0 deletions core/server/routes/frontend.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ module.exports = function (server) {
// ### Frontend routes
server.get('/rss/', frontend.rss);
server.get('/rss/:page/', frontend.rss);
server.get('/tag/:slug/rss/', frontend.rss);
server.get('/tag/:slug/rss/:page/', frontend.rss);
server.get('/tag/:slug/page/:page/', frontend.tag);
server.get('/tag/:slug/', frontend.tag);
server.get('/page/:page/', frontend.homepage);
Expand Down
55 changes: 49 additions & 6 deletions core/test/functional/routes/frontend_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -171,15 +171,15 @@ describe('Frontend Routing', function () {
.end(doEnd(done));
});

it('should redirect to last page is page too high', function (done) {
it('should redirect to last page if page too high', function (done) {
request.get('/page/4/')
.expect('Location', '/page/3/')
.expect('Cache-Control', cacheRules['public'])
.expect(302)
.end(doEnd(done));
});

it('should redirect to first page is page too low', function (done) {
it('should redirect to first page if page too low', function (done) {
request.get('/page/0/')
.expect('Location', '/')
.expect('Cache-Control', cacheRules['public'])
Expand Down Expand Up @@ -214,15 +214,15 @@ describe('Frontend Routing', function () {
.end(doEnd(done));
});

it('should redirect to last page is page too high', function (done) {
it('should redirect to last page if page too high', function (done) {
request.get('/rss/3/')
.expect('Location', '/rss/2/')
.expect('Cache-Control', cacheRules['public'])
.expect(302)
.end(doEnd(done));
});

it('should redirect to first page is page too low', function (done) {
it('should redirect to first page if page too low', function (done) {
request.get('/rss/0/')
.expect('Location', '/rss/')
.expect('Cache-Control', cacheRules['public'])
Expand All @@ -231,6 +231,49 @@ describe('Frontend Routing', function () {
});
});

describe('Tag based RSS pages', function () {
it('should redirect without slash', function (done) {
request.get('/tag/getting-started/rss')
.expect('Location', '/tag/getting-started/rss/')
.expect('Cache-Control', cacheRules.year)
.expect(301)
.end(doEnd(done));
});

it('should respond with xml', function (done) {
request.get('/tag/getting-started/rss/')
.expect('Content-Type', /xml/)
.expect('Cache-Control', cacheRules['public'])
.expect(200)
.end(doEnd(done));
});

it('should redirect page 1', function (done) {
request.get('/tag/getting-started/rss/1/')
.expect('Location', '/tag/getting-started/rss/')
.expect('Cache-Control', cacheRules['public'])
// TODO: This should probably be a 301?
.expect(302)
.end(doEnd(done));
});

it('should redirect to last page if page too high', function (done) {
request.get('/tag/getting-started/rss/2/')
.expect('Location', '/tag/getting-started/rss/1/')
.expect('Cache-Control', cacheRules['public'])
.expect(302)
.end(doEnd(done));
});

it('should redirect to first page if page too low', function (done) {
request.get('/tag/getting-started/rss/0/')
.expect('Location', '/tag/getting-started/rss/')
.expect('Cache-Control', cacheRules['public'])
.expect(302)
.end(doEnd(done));
});
});

describe('Static page', function () {
it('should redirect without slash', function (done) {
request.get('/static-page-test')
Expand Down Expand Up @@ -335,15 +378,15 @@ describe('Frontend Routing', function () {
.end(doEnd(done));
});

it('should redirect to last page is page too high', function (done) {
it('should redirect to last page if page too high', function (done) {
request.get('/tag/injection/page/4/')
.expect('Location', '/tag/injection/page/2/')
.expect('Cache-Control', cacheRules['public'])
.expect(302)
.end(doEnd(done));
});

it('should redirect to first page is page too low', function (done) {
it('should redirect to first page if page too low', function (done) {
request.get('/tag/injection/page/0/')
.expect('Location', '/tag/injection/')
.expect('Cache-Control', cacheRules['public'])
Expand Down

0 comments on commit 4556e1d

Please sign in to comment.