2
1
Fork 0
mirror of https://github.com/TryGhost/Ghost.git synced 2023-12-13 21:00:40 +01:00

Simplify config for channels (#9158)

refs #5091

- remove the use of functions
- remove unnecessary quotes from tag filter
- move channel config to be a JSOn file called config.channels.json
- accept external config
- new channelUtils for tests
- remove channelConfig.get 
- refactor so tests work as expected
- refactor away duplicate 'name' value
This commit is contained in:
Hannah Wolfe 2017-10-24 17:18:35 +01:00 committed by GitHub
parent 6812af6eed
commit 050f1751c4
9 changed files with 121 additions and 88 deletions

2
.gitignore vendored
View file

@ -63,7 +63,7 @@ CHANGELOG.md
/core/test/coverage
# ignore all custom json files for config
config.*.json
/config.*.json
# Built asset files
/core/built

View file

@ -1,56 +1,27 @@
var _ = require('lodash'),
config = require('../../config'),
utils = require('../../utils'),
channelConfig;
channels = [];
channelConfig = function channelConfig() {
var defaults = {
index: {
name: 'index',
route: '/',
frontPageTemplate: 'home'
},
tag: {
name: 'tag',
route: utils.url.urlJoin('/', config.get('routeKeywords').tag, ':slug/'),
postOptions: {
filter: 'tags:\'%s\'+tags.visibility:\'public\''
},
data: {
tag: {
type: 'read',
resource: 'tags',
options: {slug: '%s', visibility: 'public'}
}
},
slugTemplate: true,
editRedirect: '#/settings/tags/:slug/'
},
author: {
name: 'author',
route: utils.url.urlJoin('/', config.get('routeKeywords').author, ':slug/'),
postOptions: {
filter: 'author:\'%s\''
},
data: {
author: {
type: 'read',
resource: 'users',
options: {slug: '%s'}
}
},
slugTemplate: true,
editRedirect: '#/team/:slug/'
}
};
function loadConfig() {
var channelConfig = {};
return defaults;
};
// This is a very dirty temporary hack so that we can test out channels with some Beta testers
// If you are reading this code, and considering using it, best reach out to us on Slack
// Definitely don't be angry at us if the structure of the JSON changes or this goes away.
try {
channelConfig = require('../../../../config.channels.json');
} catch (err) {
channelConfig = require('./config.channels.json');
}
return channelConfig;
}
module.exports.list = function list() {
return channelConfig();
};
_.each(loadConfig(), function (channelConfig, channelName) {
var channel = _.cloneDeep(channelConfig);
channel.name = channelName;
channels.push(channel);
});
module.exports.get = function get(name) {
return _.cloneDeep(channelConfig()[name]);
return channels;
};

View file

@ -96,8 +96,12 @@ channelsRouter = function router() {
var channelsRouter = express.Router({mergeParams: true});
_.each(channelConfig.list(), function (channel) {
var channelRoute = channel.route.replace(/:rkw-([a-zA-Z]+)/, function (fullMatch, keyword) {
return config.get('routeKeywords')[keyword];
});
// Mount this channel router on the parent channels router
channelsRouter.use(channel.route, buildChannelRouter(channel));
channelsRouter.use(channelRoute, buildChannelRouter(channel));
});
return channelsRouter;

View file

@ -0,0 +1,41 @@
{
"index": {
"route": "/",
"frontPageTemplate": "home"
},
"tag": {
"route": "/:rkw-tag/:slug/",
"postOptions": {
"filter": "tags:'%s'+tags.visibility:public"
},
"data": {
"tag": {
"type": "read",
"resource": "tags",
"options": {
"slug": "%s",
"visibility": "public"
}
}
},
"slugTemplate": true,
"editRedirect": "#/settings/tags/:slug/"
},
"author": {
"route": "/:rkw-author/:slug/",
"postOptions": {
"filter": "author:'%s'"
},
"data": {
"author": {
"type": "read",
"resource": "users",
"options": {
"slug": "%s"
}
}
},
"slugTemplate": true,
"editRedirect": "#/team/:slug/"
}
}

View file

@ -1,23 +1,26 @@
/*jshint expr:true*/
var should = require('should'),
channelConfig = require('../../../../server/controllers/frontend/channel-config');
var should = require('should'), // jshint ignore:line
_ = require('lodash'),
rewire = require('rewire'),
channelUtils = require('../../../utils/channelUtils'),
channelConfig = rewire('../../../../server/controllers/frontend/channel-config');
describe('Channel Config', function () {
it('should get the index config', function () {
var result = channelConfig.get('index');
should.exist(result);
result.name.should.eql('index');
var channelReset;
before(function () {
channelReset = channelConfig.__set__('loadConfig', function () {
return channelUtils.getDefaultChannels();
});
});
it('should get the author config', function () {
var result = channelConfig.get('author');
should.exist(result);
result.name.should.eql('author');
after(function () {
channelReset();
});
it('should get the tag config', function () {
var result = channelConfig.get('tag');
should.exist(result);
result.name.should.eql('tag');
it('should build a list of channels', function () {
var channels = channelConfig.list();
channels.should.be.an.Object();
_.map(channels, 'name').should.eql(['index', 'tag', 'author']);
});
});

View file

@ -3,7 +3,7 @@ var should = require('should'),
_ = require('lodash'),
// Stuff we are testing
channelConfig = require('../../../../server/controllers/frontend/channel-config'),
channelUtils = require('../../../utils/channelUtils'),
setResponseContext = require('../../../../server/controllers/frontend/context'),
labs = require('../../../../server/utils/labs'),
@ -38,7 +38,7 @@ describe('Contexts', function () {
res.locals.relativeUrl = url;
if (channel && _.isString(channel)) {
res.locals.channel = channelConfig.get(channel);
res.locals.channel = channelUtils.getTestChannel(channel);
} else if (channel && _.isNumber(channel)) {
pageParam = channel;
} else if (channel) {

View file

@ -3,7 +3,7 @@ var should = require('should'), // jshint ignore:line
sinon = require('sinon'),
rewire = require('rewire'),
channelConfig = require('../../../../server/controllers/frontend/channel-config').get,
channelUtils = require('../../../utils/channelUtils'),
// stuff being tested
renderChannel = rewire('../../../../server/controllers/frontend/render-channel'),
@ -28,7 +28,7 @@ describe('Render Channel', function () {
},
res = {
locals: {
channel: channelConfig('tag')
channel: channelUtils.getTestChannel('tag')
}
},
promise = {
@ -43,7 +43,7 @@ describe('Render Channel', function () {
it('should return correct tag config', function () {
renderChannel.__set__('fetchData', function (channelOpts) {
channelOpts.name.should.eql('tag');
channelOpts.postOptions.filter.should.eql('tags:\'%s\'+tags.visibility:\'public\'');
channelOpts.postOptions.filter.should.eql('tags:\'%s\'+tags.visibility:public');
channelOpts.data.tag.options.should.eql({slug: '%s', visibility: 'public'});
return promise;

View file

@ -4,7 +4,7 @@ var should = require('should'),
_ = require('lodash'),
Promise = require('bluebird'),
testUtils = require('../utils'),
channelConfig = require('../../server/controllers/frontend/channel-config'),
channelUtils = require('../utils/channelUtils'),
api = require('../../server/api'),
settingsCache = require('../../server/settings/cache'),
rss = rewire('../../server/data/xml/rss'),
@ -97,7 +97,7 @@ describe('RSS', function () {
done();
};
res.locals.channel = channelConfig.get('index');
res.locals.channel = channelUtils.getTestChannel('index');
res.locals.channel.isRSS = true;
rss(req, res, failTest(done));
});
@ -140,7 +140,7 @@ describe('RSS', function () {
done();
};
res.locals.channel = channelConfig.get('index');
res.locals.channel = channelUtils.getTestChannel('index');
res.locals.channel.isRSS = true;
rss(req, res, failTest(done));
});
@ -176,7 +176,7 @@ describe('RSS', function () {
done();
};
res.locals.channel = channelConfig.get('index');
res.locals.channel = channelUtils.getTestChannel('index');
res.locals.channel.isRSS = true;
rss(req, res, failTest(done));
});
@ -204,7 +204,7 @@ describe('RSS', function () {
done();
};
res.locals.channel = channelConfig.get('index');
res.locals.channel = channelUtils.getTestChannel('index');
res.locals.channel.isRSS = true;
rss(req, res, failTest(done));
});
@ -238,7 +238,7 @@ describe('RSS', function () {
done();
};
res.locals.channel = channelConfig.get('index');
res.locals.channel = channelUtils.getTestChannel('index');
res.locals.channel.isRSS = true;
rss(req, res, failTest(done));
});
@ -270,7 +270,7 @@ describe('RSS', function () {
done();
};
res.locals.channel = channelConfig.get('index');
res.locals.channel = channelUtils.getTestChannel('index');
res.locals.channel.isRSS = true;
rss(req, res, failTest(done));
});
@ -327,7 +327,7 @@ describe('RSS', function () {
done();
};
res.locals.channel = channelConfig.get('index');
res.locals.channel = channelUtils.getTestChannel('index');
res.locals.channel.isRSS = true;
rss(req, res, failTest(done));
});
@ -336,7 +336,7 @@ describe('RSS', function () {
// setup
req.originalUrl = '/tag/magic/rss/';
req.params.slug = 'magic';
res.locals.channel = channelConfig.get('tag');
res.locals.channel = channelUtils.getTestChannel('tag');
res.locals.channel.isRSS = true;
// test
@ -344,7 +344,7 @@ describe('RSS', function () {
apiBrowseStub.calledOnce.should.be.true();
apiBrowseStub.calledWith({
page: 1,
filter: 'tags:\'magic\'+tags.visibility:\'public\'',
filter: 'tags:\'magic\'+tags.visibility:public',
include: 'author,tags'
}).should.be.true();
apiTagStub.calledOnce.should.be.true();
@ -361,7 +361,7 @@ describe('RSS', function () {
req.originalUrl = '/tag/magic/rss/2/';
req.params.slug = 'magic';
req.params.page = '2';
res.locals.channel = channelConfig.get('tag');
res.locals.channel = channelUtils.getTestChannel('tag');
res.locals.channel.isRSS = true;
// test
@ -369,7 +369,7 @@ describe('RSS', function () {
apiBrowseStub.calledOnce.should.be.true();
apiBrowseStub.calledWith({
page: '2',
filter: 'tags:\'magic\'+tags.visibility:\'public\'',
filter: 'tags:\'magic\'+tags.visibility:public',
include: 'author,tags'
}).should.be.true();
@ -385,7 +385,7 @@ describe('RSS', function () {
it('should process the data correctly for an author feed', function (done) {
req.originalUrl = '/author/joe/rss/';
req.params.slug = 'joe';
res.locals.channel = channelConfig.get('author');
res.locals.channel = channelUtils.getTestChannel('author');
res.locals.channel.isRSS = true;
// test
@ -405,7 +405,7 @@ describe('RSS', function () {
req.originalUrl = '/author/joe/rss/2/';
req.params.slug = 'joe';
req.params.page = '2';
res.locals.channel = channelConfig.get('author');
res.locals.channel = channelUtils.getTestChannel('author');
res.locals.channel.isRSS = true;
// test
@ -449,7 +449,7 @@ describe('RSS', function () {
results: {posts: [], meta: {pagination: {pages: 1}}}
});
});
res.locals.channel = channelConfig.get('index');
res.locals.channel = channelUtils.getTestChannel('index');
res.locals.channel.isRSS = true;
function secondCall() {
@ -502,7 +502,7 @@ describe('RSS', function () {
req = {params: {page: 4}, route: {path: '/rss/:page/'}};
req.originalUrl = req.route.path.replace(':page', req.params.page);
res.locals.channel = channelConfig.get('index');
res.locals.channel = channelUtils.getTestChannel('index');
res.locals.channel.isRSS = true;
rss(req, res, function (err) {
@ -519,7 +519,7 @@ describe('RSS', function () {
req = {params: {page: 4}, route: {path: '/rss/:page/'}};
req.originalUrl = req.route.path.replace(':page', req.params.page);
res.locals.channel = channelConfig.get('index');
res.locals.channel = channelUtils.getTestChannel('index');
res.locals.channel.isRSS = true;
rss(req, res, function (err) {

View file

@ -0,0 +1,14 @@
var defaultChannels = require('../../server/controllers/frontend/config.channels.json');
// This is a function to get a fake or test channel
// It's currently based on the default config in Ghost itself
module.exports.getTestChannel = function getTestChannel(channelName) {
var channel = defaultChannels[channelName];
channel.name = channelName;
return channel;
};
module.exports.getDefaultChannels = function getDefaultChannels() {
return defaultChannels;
};