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

Dynamic Routing Beta: Added ability to disable+override rss (#9693)

refs #9601

- you can now use `rss:false`
- ability to define a custom rss url with a target template (+ content_type)
- ability to disable rss for channel or collection
This commit is contained in:
Katharina Irrgang 2018-06-26 01:33:29 +02:00 committed by GitHub
parent 13cccfa9ee
commit fc9da07025
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 200 additions and 14 deletions

View file

@ -19,6 +19,8 @@ class CollectionRouter extends ParentRouter {
value: mainRoute
};
this.rss = object.rss !== false;
this.permalinks = {
originalValue: object.permalink,
value: object.permalink
@ -72,10 +74,11 @@ class CollectionRouter extends ParentRouter {
this.router().param('page', middlewares.pageParam);
this.mountRoute(urlService.utils.urlJoin(this.route.value, 'page', ':page(\\d+)'), controllers.collection);
this.rssRouter = new RSSRouter();
// REGISTER: enable rss by default
this.mountRouter(this.route.value, this.rssRouter.router());
// REGISTER: is rss enabled?
if (this.rss) {
this.rssRouter = new RSSRouter();
this.mountRouter(this.route.value, this.rssRouter.router());
}
// REGISTER: context middleware for entries
this.router().use(this._prepareEntryContext.bind(this));
@ -151,6 +154,10 @@ class CollectionRouter extends ParentRouter {
}
getRssUrl(options) {
if (!this.rss) {
return null;
}
return urlService.utils.createUrl(urlService.utils.urlJoin(this.route.value, this.rssRouter.route.value), options.absolute, options.secure);
}

View file

@ -16,6 +16,7 @@ class StaticRoutesRouter extends ParentRouter {
debug(this.route.value, this.templates);
if (this.isChannel(object)) {
this.rss = object.rss !== false;
this.filter = object.filter;
this.limit = object.limit;
this.order = object.order;
@ -26,6 +27,7 @@ class StaticRoutesRouter extends ParentRouter {
debug(this.route.value, this.templates, this.filter, this.data);
this._registerChannelRoutes();
} else {
this.contentType = object.content_type;
debug(this.route.value, this.templates);
this._registerStaticRoute();
}
@ -34,9 +36,11 @@ class StaticRoutesRouter extends ParentRouter {
_registerChannelRoutes() {
this.router().use(this._prepareChannelContext.bind(this));
// REGISTER: enable rss by default
this.rssRouter = new RSSRouter();
this.mountRouter(this.route.value, this.rssRouter.router());
// REGISTER: is rss enabled?
if (this.rss) {
this.rssRouter = new RSSRouter();
this.mountRouter(this.route.value, this.rssRouter.router());
}
// REGISTER: channel route
this.mountRoute(this.route.value, controllers[this.controller]);
@ -76,7 +80,8 @@ class StaticRoutesRouter extends ParentRouter {
templates: this.templates,
defaultTemplate: 'default',
data: this.data.query,
context: []
context: [],
contentType: this.contentType
};
next();

View file

@ -13,5 +13,11 @@ module.exports = function renderer(req, res, data) {
debug('Rendering template: ' + res._template + ' for: ' + req.originalUrl);
debug('res.locals', res.locals);
if (res.routerOptions && res.routerOptions.contentType) {
if (res.routerOptions.templates.indexOf(res._template) !== -1) {
res.type(res.routerOptions.contentType);
}
}
res.render(res._template, data);
};

View file

@ -1496,4 +1496,154 @@ describe('Integration - Web - Site', function () {
});
});
});
describe('extended routes.yaml (5): rss override', function () {
before(function () {
sandbox.stub(settingsService, 'get').returns({
routes: {
'/about/': 'about',
'/podcast/rss/': {
templates: ['podcast/rss'],
content_type: 'xml'
},
'/cooking/': {
controller: 'channel',
rss: false
},
'/flat/': {
controller: 'channel'
}
},
collections: {
'/podcast/': {
permalink: '/:slug/',
filter: 'featured:true',
templates: ['home'],
rss: false
},
'/music/': {
permalink: '/:slug/',
rss: false
},
'/': {
permalink: '/:slug/'
}
},
taxonomies: {}
});
testUtils.integrationTesting.urlService.resetGenerators();
testUtils.integrationTesting.defaultMocks(sandbox, {theme: 'test-theme'});
return testUtils.integrationTesting.initGhost()
.then(function () {
app = siteApp();
return testUtils.integrationTesting.urlService.waitTillFinished();
});
});
beforeEach(function () {
testUtils.integrationTesting.overrideGhostConfig(configUtils);
});
afterEach(function () {
configUtils.restore();
});
after(function () {
sandbox.restore();
});
it('serve /rss/', function () {
const req = {
secure: true,
method: 'GET',
url: '/rss/',
host: 'example.com'
};
return testUtils.mocks.express.invoke(app, req)
.then(function (response) {
response.statusCode.should.eql(200);
});
});
it('serve /music/rss/', function () {
const req = {
secure: true,
method: 'GET',
url: '/music/rss/',
host: 'example.com'
};
return testUtils.mocks.express.invoke(app, req)
.then(function (response) {
response.statusCode.should.eql(404);
});
});
it('serve /cooking/rss/', function () {
const req = {
secure: true,
method: 'GET',
url: '/cooking/rss/',
host: 'example.com'
};
return testUtils.mocks.express.invoke(app, req)
.then(function (response) {
response.statusCode.should.eql(404);
});
});
it('serve /flat/rss/', function () {
const req = {
secure: true,
method: 'GET',
url: '/flat/rss/',
host: 'example.com'
};
return testUtils.mocks.express.invoke(app, req)
.then(function (response) {
response.statusCode.should.eql(200);
});
});
it('serve /podcast/rss/', function () {
const req = {
secure: true,
method: 'GET',
url: '/podcast/rss/',
host: 'example.com'
};
return testUtils.mocks.express.invoke(app, req)
.then(function (response) {
response.statusCode.should.eql(200);
response.template.should.eql('podcast/rss');
response.headers['content-type'].should.eql('text/xml; charset=utf-8');
response.body.match(/<link>/g).length.should.eql(2);
});
});
it('serve /podcast/', function () {
const req = {
secure: true,
method: 'GET',
url: '/podcast/',
host: 'example.com'
};
return testUtils.mocks.express.invoke(app, req)
.then(function (response) {
const $ = cheerio.load(response.body);
response.statusCode.should.eql(200);
$('head link')[2].attribs.href.should.eql('https://127.0.0.1:2369/rss/');
});
});
});
});

View file

@ -86,7 +86,8 @@ describe('UNIT - services/routing/StaticRoutesRouter', function () {
templates: [],
defaultTemplate: 'default',
context: [],
data: {}
data: {},
contentType: undefined
});
should.not.exist(res.locals.slug);
});

View file

@ -1 +1,8 @@
home.hbs
<html>
<head>
{{ghost_head}}
</head>
<body>
home.hbs
</body>
</html>

View file

@ -0,0 +1,10 @@
<rss>
<channel>
<title>{{@blog.title}}</title>
{{#get "posts" filter="featured:true" limit="20"}}
{{#foreach posts}}
<link>{{url}}</link>
{{/foreach}}
{{/get}}
</channel>
</rss>

View file

@ -57,7 +57,7 @@
"ghost-storage-base": "0.0.3",
"glob": "5.0.15",
"got": "7.1.0",
"gscan": "1.4.3",
"gscan": "1.5.0",
"html-to-text": "3.3.0",
"image-size": "0.6.3",
"intl": "1.2.5",

View file

@ -2533,9 +2533,9 @@ grunt@~0.4.0:
underscore.string "~2.2.1"
which "~1.0.5"
gscan@1.4.3:
version "1.4.3"
resolved "https://registry.yarnpkg.com/gscan/-/gscan-1.4.3.tgz#ebea3c78106f4d8562225d46754d0a41c3e0a348"
gscan@1.5.0:
version "1.5.0"
resolved "https://registry.yarnpkg.com/gscan/-/gscan-1.5.0.tgz#b94446ab1ebc058c36e26f086ab0c0b97634832f"
dependencies:
"@tryghost/extract-zip" "1.6.6"
bluebird "^3.4.6"