Move plugin helper methods to a specific class

This commit is contained in:
Samy Pessé
2015-01-27 15:22:42 +01:00
parent 870ca4da0c
commit 131c19dee6
4 changed files with 140 additions and 139 deletions
+12 -24
View File
@@ -16,10 +16,13 @@ var logger = require("./utils/logger");
var Configuration = require("./configuration");
var TemplateEngine = require("./template");
var Plugin = require("./plugin");
var PluginsList = require("./pluginslist");
var generators = require("./generators");
var Book = function(root, context, parent) {
var that = this;
this.context = _.defaults(context || {}, {
// Extend book configuration
config: {},
@@ -70,7 +73,7 @@ var Book = function(root, context, parent) {
this.files = [];
// List of plugins
this.plugins = {};
this.plugins = new PluginsList(this);
// Structure files
this.summaryFile = null;
@@ -85,6 +88,9 @@ var Book = function(root, context, parent) {
this.field('title', { boost: 10 });
this.field('body');
});
// Bind methods
_.bindAll(this);
};
Book.LOG_LEVELS = {
@@ -327,30 +333,12 @@ Book.prototype.parsePlugins = function() {
var failed = [];
// Load plugins
var pluginsList = _.map(that.options.plugins, function(plugin) {
var plugin = new Plugin(that, plugin.name);
that.log.info("load plugin", plugin.name, "....");
return that.plugins.load(that.options.plugins)
.then(function() {
if (_.size(that.plugins.failed) > 0) return Q.reject(new Error("Error loading plugins: "+that.plugins.failed.join(",")+". Run 'gitbook install' to install plugins from NPM."));
if (!plugin.isValid()) {
that.log.info.fail();
failed.push(plugin.name);
} else {
that.log.info.ok();
}
return plugin;
});
if (_.size(failed) > 0) return Q.reject(new Error("Error loading plugins: "+failed.join(",")+". Run 'gitbook install' to install plugins from NPM."));
that.log.info.ok(that.plugins.length+" plugins loaded");
that.log.debug.ln("normalize plugins list");
return Plugin.normalize(pluginsList)
.then(function(_plugins) {
that.plugins = _plugins;
// Add filters
that.template.addFilters(that.plugins.filters);
that.log.info.ok(that.plugins.length+" plugins loaded");
that.log.debug.ln("normalize plugins list");
});
};
-109
View File
@@ -196,113 +196,4 @@ Plugin.prototype.copyAssets = function(out, options) {
}, _.constant(false));
};
// Extract data from a list of plugin
Plugin.normalize = function(plugins, options) {
options = _.defaults(options || {}, {
assetsBase: "book"
});
// The raw resources extracted from each plugin
var pluginResources;
// Map of resources
var resources = {};
// Map of all filters
var filters = {};
// Get resources of plugins
return Q.all(_.map(plugins, function(plugin) {
return plugin.getResources(options.assetsBase);
}))
// Extract resources out
// css, js, etc ...
.then(function(_resources) {
pluginResources = _resources;
})
.then(function() {
// Group by resource types
resources = _.chain(Plugin.RESOURCES)
.map(function(resourceType) {
// Get resources from all the plugins for this current type
return [
// Key
resourceType,
// Value
_.chain(pluginResources)
.pluck(resourceType)
.compact()
.flatten()
.value()
];
})
.object()
.value();
})
// Extract html snippets
.then(function() {
// Map of html resources by name added by each plugin
resources.html = pluginResources.reduce(function(accu, resource) {
var html = (resource && resource.html) || {};
_.each(html, function(code, key) {
// Turn into function if not one already
if (!_.isFunction(code)) code = _.constant(code);
// Append
accu[key] = (accu[key] || []).concat([code]);
});
return accu;
}, {});
})
// Extract filters
.then(function() {
_.each(plugins, function(plugin) {
_.each(plugin.getFilters(), function(filterFunc, filterName) {
if (filters[filterName]) {
plugin.book.log.warn.ln("Conflict in filters, '"+filterName+"' is already set");
} else {
filters[filterName] = filterFunc;
}
});
});
})
// Return big multi-plugins object
.then(function() {
return {
'list': plugins,
'resources': resources,
'filters': filters,
'hook': function(name, data) {
return _.reduce(plugins, function(prev, plugin) {
return prev.then(function(ret) {
return plugin.callHook(name, ret);
});
}, Q(data));
},
'template': function(name) {
var withTpl = _.find(plugins, function(plugin) {
return (
plugin.infos.templates &&
plugin.infos.templates[name]
);
});
if (!withTpl) return null;
return withTpl.resolveFile(withTpl.infos.templates[name]);
},
'html': function(tag, context, options) {
return _.map(resources.html[tag] || [], function(code) {
return code.call(context, options);
}).join("\n");
}
};
});
};
module.exports = Plugin;
+117
View File
@@ -0,0 +1,117 @@
var _ = require("lodash");
var Q = require("q");
var Plugin = require("./plugin");
var PluginsList = function(book, plugins) {
this.book = book;
this.log = this.book.log;
// List of Plugin objects
this.plugins = [];
// List of names of failed plugins
this.failed = [];
// List of plugins resources
this.resources = {};
_.each(Plugin.RESOURCES, function(resourceType) {
this.resources[resourceType] = [];
}, this);
// Map of html snippets
this.htmlSnippets = {};
// Bind methods
_.bindAll(this);
if (plugins) this.load(plugins);
};
// Add and load a plugin
PluginsList.prototype.load = function(plugin, options) {
var that = this;
options = _.defaults(options || {}, {
assetsBase: "book"
});
if (_.isArray(plugin)) {
return _.reduce(plugin, function(prev, p) {
prev.then(function() {
return that.load(p);
});
}, Q());
}
if (_.isString(plugin)) {
plugin = new Plugin(this.book, plugin);
}
that.log.info("load plugin", plugin.name, "....");
if (!plugin.isValid()) {
that.log.info.fail();
that.failed.push(plugin.name);
return;
} else {
that.log.info.ok();
// Push in the list
that.plugins.push(plugin);
}
// Extract filters
_.each(plugin.getFilters(), function(filterFunc, filterName) {
that.book.template.addFilter(filterName, filterFunc);
});
return Q()
.then(function() {
return plugin.getResources(options.assetsBase);
})
.then(function(plResources) {
// Extract js and css
_.each(Plugin.RESOURCES, function(resourceType) {
that.resources[resourceType].concat(plResources[resourceType] || []);
});
// Map of html resources by name added by each plugin
_.each(plResources.html || {}, function(value, tag) {
// Turn into function if not one already
if (!_.isFunction(value)) value = _.constant(value);
that.htmlSnippets[tag] = that.htmlSnippets[tag] || [];
that.htmlSnippets[tag].push(value);
});
});
};
// Call a hook
PluginsList.prototype.hook = function(name, data) {
return _.reduce(this.plugins, function(prev, plugin) {
return prev.then(function(ret) {
return plugin.callHook(name, ret);
});
}, Q(data));
};
// Return a template from a plugin
PluginsList.prototype.template = function(name) {
var withTpl = _.find(this.plugins, function(plugin) {
return (
plugin.infos.templates &&
plugin.infos.templates[name]
);
});
if (!withTpl) return null;
return withTpl.resolveFile(withTpl.infos.templates[name]);
};
// Return an html snippet
PluginsList.prototype.html = function(tag, context, options) {
return _.map(this.htmlSnippets[tag] || [], function(code) {
return code.call(context, options);
}).join("\n");
};
module.exports = PluginsList;
+11 -6
View File
@@ -45,6 +45,7 @@ var BookLoader = nunjucks.Loader.extend({
var TemplateEngine = function(book) {
this.book = book;
this.log = this.book.log;
// Nunjucks env
this.env = new nunjucks.Environment(
@@ -66,12 +67,16 @@ var TemplateEngine = function(book) {
);
};
// Add filters
TemplateEngine.prototype.addFilters = function(filters) {
_.each(filters, function(func, key) {
this.book.log.debug.ln("add filter '"+key+"'");
this.env.addFilter(key, func);
}, this);
// Add filter
TemplateEngine.prototype.addFilter = function(key, filter) {
if (this.env.getFilter(filterName)) {
this.log.warn.ln("conflict in filters, '"+filterName+"' is already set");
return false;
}
this.log.debug.ln("add filter '"+key+"'");
this.env.addFilter(key, func, true);
return true;
};
// Render a string from the book