Skip to content

Commit

Permalink
Merge pull request #931 from jgable/pluginApiChanges
Browse files Browse the repository at this point in the history
  • Loading branch information
ErisDS committed Oct 29, 2013
2 parents 6634c46 + 6a0a453 commit 17bc803
Show file tree
Hide file tree
Showing 7 changed files with 710 additions and 539 deletions.
75 changes: 53 additions & 22 deletions core/ghost.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ var config = require('../config'),
instance,
defaults;

when.pipeline = require('when/pipeline');

// ## Default values
/**
* A hash of default values to use instead of 'magic' numbers/strings.
Expand Down Expand Up @@ -182,8 +184,6 @@ Ghost.prototype.init = function () {
return when.join(
// Check for or initialise a dbHash.
initDbHashAndFirstRun(),
// Initialize plugins
self.initPlugins(),
// Initialize the permissions actions and objects
permissions.init()
);
Expand Down Expand Up @@ -282,6 +282,19 @@ Ghost.prototype.registerThemeHelper = function (name, fn) {
hbs.registerHelper(name, fn);
};

// Register an async handlebars helper for themes
Ghost.prototype.registerAsyncThemeHelper = function (name, fn) {
hbs.registerAsyncHelper(name, function (options, cb) {
// Wrap the function passed in with a when.resolve so it can
// return either a promise or a value
when.resolve(fn(options)).then(function (result) {
cb(result);
}).otherwise(function (err) {
errors.logAndThrowError(err, "registerAsyncThemeHelper: " + name);
});
});
};

// Register a new filter callback function
Ghost.prototype.registerFilter = function (name, priority, fn) {
// Curry the priority optional parameter to a default of 5
Expand Down Expand Up @@ -312,43 +325,61 @@ Ghost.prototype.unregisterFilter = function (name, priority, fn) {
};

// Execute filter functions in priority order
Ghost.prototype.doFilter = function (name, args, callback) {
var callbacks = this.filterCallbacks[name];
Ghost.prototype.doFilter = function (name, args) {
var callbacks = this.filterCallbacks[name],
priorityCallbacks = [];

// Bug out early if no callbacks by that name
if (!callbacks) {
return callback(args);
return when.resolve(args);
}

// For each priorityLevel
_.times(defaults.maxPriority + 1, function (priority) {
// Bug out if no handlers on this priority
if (!_.isArray(callbacks[priority])) {
return;
}

// Call each handler for this priority level
_.each(callbacks[priority], function (filterHandler) {
try {
args = filterHandler(args);
} catch (e) {
// If a filter causes an error, we log it so that it can be debugged, but do not throw the error
errors.logError(e);
// Add a function that runs its priority level callbacks in a pipeline
priorityCallbacks.push(function (currentArgs) {
// Bug out if no handlers on this priority
if (!_.isArray(callbacks[priority])) {
return when.resolve(currentArgs);
}

// Call each handler for this priority level, allowing for promises or values
return when.pipeline(callbacks[priority], currentArgs);
});
});

callback(args);
return when.pipeline(priorityCallbacks, args);
};

// Initialise plugins. Will load from config.activePlugins by default
Ghost.prototype.initPlugins = function (pluginsToLoad) {
pluginsToLoad = pluginsToLoad || models.Settings.activePlugins;
var self = this;

return plugins.init(this, pluginsToLoad).then(function (loadedPlugins) {
if (!_.isArray(pluginsToLoad)) {

try {
// We have to parse the value because it's a string
pluginsToLoad = JSON.parse(this.settings('activePlugins')) || [];
} catch (e) {
errors.logError(
'Failed to parse activePlugins setting value: ' + e.message,
'Your plugins will not be loaded.',
'Check your settings table for typos in the activePlugins value. It should look like: ["plugin-1", "plugin2"] (double quotes required).'
);
return when.resolve();
}
}

return plugins.init(self, pluginsToLoad).then(function (loadedPlugins) {
// Extend the loadedPlugins onto the available plugins
_.extend(self.availablePlugins, loadedPlugins);
}, errors.logAndThrowError);
}).otherwise(function (err) {
errors.logError(
err.message || err,
'The plugin will not be loaded',
'Check with the plugin creator, or read the plugin documentation for more details on plugin requirements'
);
});
};

module.exports = Ghost;
module.exports = Ghost;
38 changes: 23 additions & 15 deletions core/server.js
Original file line number Diff line number Diff line change
Expand Up @@ -445,22 +445,30 @@ when(ghost.init()).then(function () {
loading.resolve();
}

// ## Start Ghost App
if (getSocket()) {
// Make sure the socket is gone before trying to create another
fs.unlink(getSocket(), function (err) {
// Expose the express server on the ghost instance.
ghost.server = server;

// Initialize plugins then start the server
ghost.initPlugins().then(function () {

// ## Start Ghost App
if (getSocket()) {
// Make sure the socket is gone before trying to create another
fs.unlink(getSocket(), function (err) {
server.listen(
getSocket(),
startGhost
);
fs.chmod(getSocket(), '0744');
});

} else {
server.listen(
getSocket(),
ghost.config().server.port,
ghost.config().server.host,
startGhost
);
fs.chmod(getSocket(), '0744');
});
}

} else {
server.listen(
ghost.config().server.port,
ghost.config().server.host,
startGhost
);
}
}, errors.logAndThrowError);
});
}).otherwise(errors.logAndThrowError);
8 changes: 3 additions & 5 deletions core/server/controllers/frontend.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,6 @@ frontendControllers = {
}

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

var maxPage = page.pages;

// A bit of a hack for situations with no content.
Expand All @@ -56,7 +55,7 @@ frontendControllers = {
}

// Render the page of posts
ghost.doFilter('prePostsRender', page.posts, function (posts) {
ghost.doFilter('prePostsRender', page.posts).then(function (posts) {
res.render('index', {posts: posts, pagination: {page: page.page, prev: page.prev, next: page.next, limit: page.limit, total: page.total, pages: page.pages}});
});
}).otherwise(function (err) {
Expand All @@ -66,7 +65,7 @@ frontendControllers = {
'single': function (req, res, next) {
api.posts.read({'slug': req.params.slug}).then(function (post) {
if (post) {
ghost.doFilter('prePostsRender', post, function (post) {
ghost.doFilter('prePostsRender', post).then(function (post) {
res.render('post', {post: post});
});
} else {
Expand Down Expand Up @@ -117,7 +116,7 @@ frontendControllers = {
return res.redirect('/rss/' + maxPage + '/');
}

ghost.doFilter('prePostsRender', page.posts, function (posts) {
ghost.doFilter('prePostsRender', page.posts).then(function (posts) {
posts.forEach(function (post) {
var item = {
title: _.escape(post.title),
Expand Down Expand Up @@ -148,7 +147,6 @@ frontendControllers = {
return next(new Error(err));
});
}

};

module.exports = frontendControllers;
Loading

0 comments on commit 17bc803

Please sign in to comment.