mirror of
https://github.com/TryGhost/Ghost.git
synced 2025-02-17 23:44:39 -05:00
Merge pull request #166 from ErisDS/settings-cache
Settings cache & clean up "ghostGlobals"
This commit is contained in:
commit
d0eace2d36
5 changed files with 86 additions and 56 deletions
48
app.js
48
app.js
|
@ -18,20 +18,19 @@
|
||||||
filters = require('./core/frontend/filters'),
|
filters = require('./core/frontend/filters'),
|
||||||
helpers = require('./core/frontend/helpers'),
|
helpers = require('./core/frontend/helpers'),
|
||||||
|
|
||||||
// ## Variables
|
// ## Custom Middleware
|
||||||
auth,
|
auth,
|
||||||
authAPI,
|
authAPI,
|
||||||
ghostLocals,
|
ghostLocals,
|
||||||
|
|
||||||
|
// ## Variables
|
||||||
loading = when.defer(),
|
loading = when.defer(),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create new Ghost object
|
* Create new Ghost object
|
||||||
* @type {Ghost}
|
* @type {Ghost}
|
||||||
*/
|
*/
|
||||||
ghost = new Ghost(),
|
ghost = new Ghost();
|
||||||
// This is assigned after the call to ghost.init() below
|
|
||||||
ghostGlobals;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
ghost.app().configure('development', function () {
|
ghost.app().configure('development', function () {
|
||||||
|
@ -44,8 +43,6 @@
|
||||||
ghost.app().use(express.cookieSession({ cookie: { maxAge: 60000000 }}));
|
ghost.app().use(express.cookieSession({ cookie: { maxAge: 60000000 }}));
|
||||||
ghost.app().use(ghost.initTheme(ghost.app()));
|
ghost.app().use(ghost.initTheme(ghost.app()));
|
||||||
ghost.app().use(flash());
|
ghost.app().use(flash());
|
||||||
// bind locals - options which appear in every view - perhaps this should be admin only
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -75,18 +72,19 @@
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Expose the standard locals that every external page should have available;
|
* Expose the standard locals that every external page should have available;
|
||||||
* path, navItems and ghostGlobals
|
* path, navItems and settingsCache
|
||||||
*/
|
*/
|
||||||
ghostLocals = function (req, res, next) {
|
ghostLocals = function (req, res, next) {
|
||||||
ghost.doFilter('ghostNavItems', {path: req.path, navItems: []}, function (navData) {
|
ghost.doFilter('ghostNavItems', {path: req.path, navItems: []}, function (navData) {
|
||||||
// Make sure we have a locals value.
|
// Make sure we have a locals value.
|
||||||
res.locals = res.locals || {};
|
res.locals = res.locals || {};
|
||||||
|
|
||||||
|
// Extend it with nav data and settings
|
||||||
|
|
||||||
// Extend it with nav data and ghostGlobals
|
|
||||||
_.extend(res.locals, navData, {
|
_.extend(res.locals, navData, {
|
||||||
ghostGlobals: ghost.globals()
|
messages: req.flash(),
|
||||||
|
settings: ghost.settings(),
|
||||||
|
availableThemes: ghost.paths().availableThemes,
|
||||||
|
availablePlugins: ghost.paths().availablePlugins
|
||||||
});
|
});
|
||||||
|
|
||||||
next();
|
next();
|
||||||
|
@ -97,21 +95,9 @@
|
||||||
ghost.loaded = loading.promise;
|
ghost.loaded = loading.promise;
|
||||||
|
|
||||||
when.all([ghost.init(), filters.loadCoreFilters(ghost), helpers.loadCoreHelpers(ghost)]).then(function () {
|
when.all([ghost.init(), filters.loadCoreFilters(ghost), helpers.loadCoreHelpers(ghost)]).then(function () {
|
||||||
// Assign the globals we have loaded
|
|
||||||
ghostGlobals = ghost.globals();
|
|
||||||
|
|
||||||
ghost.app().use(function (req, res, next) {
|
// post init config
|
||||||
res.locals.messages = req.flash();
|
ghost.app().use(ghostLocals);
|
||||||
res.locals.siteTitle = ghostGlobals.title;
|
|
||||||
res.locals.siteDescription = ghostGlobals.description;
|
|
||||||
res.locals.siteUrl = ghostGlobals.url;
|
|
||||||
res.locals.activeTheme = ghostGlobals.activeTheme;
|
|
||||||
res.locals.activePlugin = ghostGlobals.activePlugin;
|
|
||||||
res.locals.availableThemes = ghost.paths().availableThemes;
|
|
||||||
res.locals.availablePlugins = ghost.paths().availablePlugins;
|
|
||||||
|
|
||||||
next();
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* API routes..
|
* API routes..
|
||||||
|
@ -122,9 +108,9 @@
|
||||||
ghost.app().get('/api/v0.1/posts/:id', authAPI, api.requestHandler(api.posts.read));
|
ghost.app().get('/api/v0.1/posts/:id', authAPI, api.requestHandler(api.posts.read));
|
||||||
ghost.app().put('/api/v0.1/posts/:id', authAPI, api.requestHandler(api.posts.edit));
|
ghost.app().put('/api/v0.1/posts/:id', authAPI, api.requestHandler(api.posts.edit));
|
||||||
ghost.app().del('/api/v0.1/posts/:id', authAPI, api.requestHandler(api.posts.destroy));
|
ghost.app().del('/api/v0.1/posts/:id', authAPI, api.requestHandler(api.posts.destroy));
|
||||||
ghost.app().get('/api/v0.1/settings', authAPI, api.requestHandler(api.settings.browse));
|
ghost.app().get('/api/v0.1/settings', authAPI, api.cachedSettingsRequestHandler(api.settings.browse));
|
||||||
ghost.app().get('/api/v0.1/settings/:key', authAPI, api.requestHandler(api.settings.read));
|
ghost.app().get('/api/v0.1/settings/:key', authAPI, api.cachedSettingsRequestHandler(api.settings.read));
|
||||||
ghost.app().put('/api/v0.1/settings', authAPI, api.requestHandler(api.settings.edit));
|
ghost.app().put('/api/v0.1/settings', authAPI, api.cachedSettingsRequestHandler(api.settings.edit));
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Admin routes..
|
* Admin routes..
|
||||||
|
@ -151,8 +137,8 @@
|
||||||
* Frontend routes..
|
* Frontend routes..
|
||||||
* @todo dynamic routing, homepage generator, filters ETC ETC
|
* @todo dynamic routing, homepage generator, filters ETC ETC
|
||||||
*/
|
*/
|
||||||
ghost.app().get('/:slug', ghostLocals, frontend.single);
|
ghost.app().get('/:slug', frontend.single);
|
||||||
ghost.app().get('/', ghostLocals, frontend.homepage);
|
ghost.app().get('/', frontend.homepage);
|
||||||
|
|
||||||
ghost.app().listen(3333, function () {
|
ghost.app().listen(3333, function () {
|
||||||
console.log("Express server listening on port " + 3333);
|
console.log("Express server listening on port " + 3333);
|
||||||
|
|
|
@ -16,14 +16,14 @@
|
||||||
'homepage': function (req, res) {
|
'homepage': function (req, res) {
|
||||||
api.posts.browse().then(function (page) {
|
api.posts.browse().then(function (page) {
|
||||||
ghost.doFilter('prePostsRender', page.posts, function (posts) {
|
ghost.doFilter('prePostsRender', page.posts, function (posts) {
|
||||||
res.render('index', {posts: posts, ghostGlobals: res.locals.ghostGlobals, navItems: res.locals.navItems});
|
res.render('index', {posts: posts});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
'single': function (req, res) {
|
'single': function (req, res) {
|
||||||
api.posts.read({'slug': req.params.slug}).then(function (post) {
|
api.posts.read({'slug': req.params.slug}).then(function (post) {
|
||||||
ghost.doFilter('prePostsRender', post.toJSON(), function (post) {
|
ghost.doFilter('prePostsRender', post.toJSON(), function (post) {
|
||||||
res.render('single', {post: post, ghostGlobals: res.locals.ghostGlobals, navItems: res.locals.navItems});
|
res.render('single', {post: post});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -87,14 +87,12 @@
|
||||||
// load Plugins...
|
// load Plugins...
|
||||||
// var f = new FancyFirstChar(ghost).init();
|
// var f = new FancyFirstChar(ghost).init();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
_.extend(instance, {
|
_.extend(instance, {
|
||||||
app: function () { return app; },
|
app: function () { return app; },
|
||||||
config: function () { return config; },
|
config: function () { return config; },
|
||||||
|
|
||||||
// there's no management here to be sure this has loaded
|
// there's no management here to be sure this has loaded
|
||||||
globals: function () { return instance.globalConfig; },
|
settings: function () { return instance.settingsCache; },
|
||||||
dataProvider: models,
|
dataProvider: models,
|
||||||
statuses: function () { return statuses; },
|
statuses: function () { return statuses; },
|
||||||
polyglot: function () { return polyglot; },
|
polyglot: function () { return polyglot; },
|
||||||
|
@ -125,6 +123,19 @@
|
||||||
var self = this;
|
var self = this;
|
||||||
|
|
||||||
return when.join(instance.dataProvider.init(), instance.getPaths()).then(function () {
|
return when.join(instance.dataProvider.init(), instance.getPaths()).then(function () {
|
||||||
|
return self.updateSettingsCache();
|
||||||
|
}, errors.logAndThrowError);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Ghost.prototype.updateSettingsCache = function (settings) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
|
settings = settings || {};
|
||||||
|
|
||||||
|
if (!_.isEmpty(settings)) {
|
||||||
|
self.settingsCache = settings;
|
||||||
|
} else {
|
||||||
// TODO: this should use api.browse
|
// TODO: this should use api.browse
|
||||||
return models.Settings.findAll().then(function (result) {
|
return models.Settings.findAll().then(function (result) {
|
||||||
var settings = {};
|
var settings = {};
|
||||||
|
@ -134,9 +145,9 @@
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
self.globalConfig = settings;
|
self.settingsCache = settings;
|
||||||
}, errors.logAndThrowError);
|
|
||||||
}, errors.logAndThrowError);
|
}, errors.logAndThrowError);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
|
|
||||||
var Ghost = require('../ghost'),
|
var Ghost = require('../ghost'),
|
||||||
_ = require('underscore'),
|
_ = require('underscore'),
|
||||||
|
when = require('when'),
|
||||||
|
errors = require('./errorHandling'),
|
||||||
|
|
||||||
ghost = new Ghost(),
|
ghost = new Ghost(),
|
||||||
dataProvider = ghost.dataProvider,
|
dataProvider = ghost.dataProvider,
|
||||||
|
@ -18,6 +20,7 @@
|
||||||
users,
|
users,
|
||||||
settings,
|
settings,
|
||||||
requestHandler,
|
requestHandler,
|
||||||
|
cachedSettingsRequestHandler,
|
||||||
settingsObject,
|
settingsObject,
|
||||||
settingsCollection;
|
settingsCollection;
|
||||||
|
|
||||||
|
@ -25,37 +28,37 @@
|
||||||
posts = {
|
posts = {
|
||||||
// takes filter / pagination parameters
|
// takes filter / pagination parameters
|
||||||
// returns a page of posts in a json response
|
// returns a page of posts in a json response
|
||||||
browse: function (options) {
|
browse: function browse(options) {
|
||||||
return dataProvider.Post.findPage(options);
|
return dataProvider.Post.findPage(options);
|
||||||
},
|
},
|
||||||
// takes an identifier (id or slug?)
|
// takes an identifier (id or slug?)
|
||||||
// returns a single post in a json response
|
// returns a single post in a json response
|
||||||
read: function (args) {
|
read: function read(args) {
|
||||||
return dataProvider.Post.findOne(args);
|
return dataProvider.Post.findOne(args);
|
||||||
},
|
},
|
||||||
// takes a json object with all the properties which should be updated
|
// takes a json object with all the properties which should be updated
|
||||||
// returns the resulting post in a json response
|
// returns the resulting post in a json response
|
||||||
edit: function (postData) {
|
edit: function edit(postData) {
|
||||||
return dataProvider.Post.edit(postData);
|
return dataProvider.Post.edit(postData);
|
||||||
},
|
},
|
||||||
// takes a json object representing a post,
|
// takes a json object representing a post,
|
||||||
// returns the resulting post in a json response
|
// returns the resulting post in a json response
|
||||||
add: function (postData) {
|
add: function add(postData) {
|
||||||
return dataProvider.Post.add(postData);
|
return dataProvider.Post.add(postData);
|
||||||
},
|
},
|
||||||
// takes an identifier (id or slug?)
|
// takes an identifier (id or slug?)
|
||||||
// returns a json response with the id of the deleted post
|
// returns a json response with the id of the deleted post
|
||||||
destroy: function (args) {
|
destroy: function destroy(args) {
|
||||||
return dataProvider.Post.destroy(args.id);
|
return dataProvider.Post.destroy(args.id);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// # Users
|
// # Users
|
||||||
users = {
|
users = {
|
||||||
add: function (postData) {
|
add: function add(postData) {
|
||||||
return dataProvider.User.add(postData);
|
return dataProvider.User.add(postData);
|
||||||
},
|
},
|
||||||
check: function (postData) {
|
check: function check(postData) {
|
||||||
return dataProvider.User.check(postData);
|
return dataProvider.User.check(postData);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -78,21 +81,17 @@
|
||||||
};
|
};
|
||||||
|
|
||||||
settings = {
|
settings = {
|
||||||
browse: function (options) {
|
browse: function browse(options) {
|
||||||
return dataProvider.Settings.browse(options).then(settingsObject);
|
return dataProvider.Settings.browse(options).then(settingsObject);
|
||||||
},
|
},
|
||||||
read: function (options) {
|
read: function read(options) {
|
||||||
return dataProvider.Settings.read(options.key).then(function (setting) {
|
return dataProvider.Settings.read(options.key).then(function (setting) {
|
||||||
return _.pick(setting.toJSON(), 'key', 'value');
|
return _.pick(setting.toJSON(), 'key', 'value');
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
edit: function (settings) {
|
edit: function edit(settings) {
|
||||||
settings = settingsCollection(settings);
|
settings = settingsCollection(settings);
|
||||||
return dataProvider.Settings.edit(settings).then(settingsObject);
|
return dataProvider.Settings.edit(settings).then(settingsObject);
|
||||||
},
|
|
||||||
add: function (settings) {
|
|
||||||
settings = settingsCollection(settings);
|
|
||||||
return dataProvider.Settings.add(settings).then(settingsObject);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -114,8 +113,42 @@
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
cachedSettingsRequestHandler = function (apiMethod) {
|
||||||
|
if (!ghost.settings()) {
|
||||||
|
return requestHandler(apiMethod);
|
||||||
|
}
|
||||||
|
|
||||||
|
return function (req, res) {
|
||||||
|
var options = _.extend(req.body, req.query, req.params),
|
||||||
|
promise;
|
||||||
|
|
||||||
|
switch (apiMethod.name) {
|
||||||
|
case 'browse':
|
||||||
|
promise = when(ghost.settings());
|
||||||
|
break;
|
||||||
|
case 'read':
|
||||||
|
promise = when(ghost.settings()[options.key]);
|
||||||
|
break;
|
||||||
|
case 'edit':
|
||||||
|
promise = apiMethod(options).then(function (result) {
|
||||||
|
ghost.updateSettingsCache(result);
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
errors.logAndThrowError(new Error('Unknown method name for settings API: ' + apiMethod.name));
|
||||||
|
}
|
||||||
|
return promise.then(function (result) {
|
||||||
|
res.json(result || {});
|
||||||
|
}, function (error) {
|
||||||
|
res.json(400, {error: error});
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
module.exports.posts = posts;
|
module.exports.posts = posts;
|
||||||
module.exports.users = users;
|
module.exports.users = users;
|
||||||
module.exports.settings = settings;
|
module.exports.settings = settings;
|
||||||
module.exports.requestHandler = requestHandler;
|
module.exports.requestHandler = requestHandler;
|
||||||
|
module.exports.cachedSettingsRequestHandler = cachedSettingsRequestHandler;
|
||||||
}());
|
}());
|
|
@ -27,19 +27,19 @@
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
dataProviderInitSpy = sinon.spy(fakeDataProvider, "init"),
|
dataProviderInitSpy = sinon.spy(fakeDataProvider, "init"),
|
||||||
oldDataProvder = ghost.dataProvider;
|
oldDataProvider = ghost.dataProvider;
|
||||||
|
|
||||||
ghost.dataProvider = fakeDataProvider;
|
ghost.dataProvider = fakeDataProvider;
|
||||||
|
|
||||||
should.not.exist(ghost.globals());
|
should.not.exist(ghost.settings());
|
||||||
|
|
||||||
ghost.init().then(function () {
|
ghost.init().then(function () {
|
||||||
|
|
||||||
should.exist(ghost.globals());
|
should.exist(ghost.settings());
|
||||||
|
|
||||||
dataProviderInitSpy.called.should.equal(true);
|
dataProviderInitSpy.called.should.equal(true);
|
||||||
|
|
||||||
ghost.dataProvider = oldDataProvder;
|
ghost.dataProvider = oldDataProvider;
|
||||||
|
|
||||||
done();
|
done();
|
||||||
}).then(null, done);
|
}).then(null, done);
|
||||||
|
|
Loading…
Add table
Reference in a new issue