0
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2025-02-03 23:00:14 -05:00

Rss support for tags

closes #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
This commit is contained in:
Johan Stenehall 2014-03-05 23:03:39 +01:00
parent a806f3e097
commit 4556e1df0a
3 changed files with 93 additions and 27 deletions

View file

@ -252,11 +252,16 @@ frontendControllers = {
'rss': function (req, res, next) { 'rss': function (req, res, next) {
// Initialize RSS // Initialize RSS
var pageParam = req.params.page !== undefined ? parseInt(req.params.page, 10) : 1, var pageParam = req.params.page !== undefined ? parseInt(req.params.page, 10) : 1,
feed; tagParam = req.params.slug;
// No negative pages, or page 1 // No negative pages, or page 1
if (isNaN(pageParam) || pageParam < 1 || (pageParam === 1 && req.route.path === '/rss/:page/')) { if (isNaN(pageParam) || pageParam < 1 ||
return res.redirect(config().paths.subdir + '/rss/'); (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 // TODO: needs refactor for multi user to not use first user as default
@ -266,25 +271,37 @@ frontendControllers = {
api.settings.read('description'), api.settings.read('description'),
api.settings.read('permalinks') api.settings.read('permalinks')
]).then(function (result) { ]).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({ var options = {};
title: title, if (pageParam) { options.page = pageParam; }
description: description, if (tagParam) { options.tag = tagParam; }
generator: 'Ghost v' + res.locals.version,
feed_url: feedUrl, return api.posts.browse(options).then(function (page) {
site_url: siteUrl,
ttl: '60' 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'
});
return api.posts.browse({page: pageParam}).then(function (page) {
var maxPage = page.pages,
feedItems = [];
// A bit of a hack for situations with no content. // A bit of a hack for situations with no content.
if (maxPage === 0) { if (maxPage === 0) {
@ -294,7 +311,11 @@ frontendControllers = {
// If page is greater than number of pages we have, redirect to last page // If page is greater than number of pages we have, redirect to last page
if (pageParam > maxPage) { 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) { filters.doFilter('prePostsRender', page.posts).then(function (posts) {

View file

@ -6,6 +6,8 @@ module.exports = function (server) {
// ### Frontend routes // ### Frontend routes
server.get('/rss/', frontend.rss); server.get('/rss/', frontend.rss);
server.get('/rss/:page/', 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/page/:page/', frontend.tag);
server.get('/tag/:slug/', frontend.tag); server.get('/tag/:slug/', frontend.tag);
server.get('/page/:page/', frontend.homepage); server.get('/page/:page/', frontend.homepage);

View file

@ -171,7 +171,7 @@ describe('Frontend Routing', function () {
.end(doEnd(done)); .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/') request.get('/page/4/')
.expect('Location', '/page/3/') .expect('Location', '/page/3/')
.expect('Cache-Control', cacheRules['public']) .expect('Cache-Control', cacheRules['public'])
@ -179,7 +179,7 @@ describe('Frontend Routing', function () {
.end(doEnd(done)); .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/') request.get('/page/0/')
.expect('Location', '/') .expect('Location', '/')
.expect('Cache-Control', cacheRules['public']) .expect('Cache-Control', cacheRules['public'])
@ -214,7 +214,7 @@ describe('Frontend Routing', function () {
.end(doEnd(done)); .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/') request.get('/rss/3/')
.expect('Location', '/rss/2/') .expect('Location', '/rss/2/')
.expect('Cache-Control', cacheRules['public']) .expect('Cache-Control', cacheRules['public'])
@ -222,7 +222,7 @@ describe('Frontend Routing', function () {
.end(doEnd(done)); .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/') request.get('/rss/0/')
.expect('Location', '/rss/') .expect('Location', '/rss/')
.expect('Cache-Control', cacheRules['public']) .expect('Cache-Control', cacheRules['public'])
@ -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 () { describe('Static page', function () {
it('should redirect without slash', function (done) { it('should redirect without slash', function (done) {
request.get('/static-page-test') request.get('/static-page-test')
@ -335,7 +378,7 @@ describe('Frontend Routing', function () {
.end(doEnd(done)); .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/') request.get('/tag/injection/page/4/')
.expect('Location', '/tag/injection/page/2/') .expect('Location', '/tag/injection/page/2/')
.expect('Cache-Control', cacheRules['public']) .expect('Cache-Control', cacheRules['public'])
@ -343,7 +386,7 @@ describe('Frontend Routing', function () {
.end(doEnd(done)); .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/') request.get('/tag/injection/page/0/')
.expect('Location', '/tag/injection/') .expect('Location', '/tag/injection/')
.expect('Cache-Control', cacheRules['public']) .expect('Cache-Control', cacheRules['public'])