summaryrefslogtreecommitdiffstats
path: root/lib/pluginslist.js
blob: 35ba8c3bb3256409398881eec0adb979999c17de (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
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);
};

// return count of plugins
PluginsList.prototype.count = function() {
	return this.plugins.length;
};

// 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) {
			return prev.then(function() {
				return that.load(p);
			});
		}, Q());
	}
	if (_.isObject(plugin) && !(plugin instanceof Plugin)) plugin = plugin.name;
	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 Q();
    } 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);
    });

    // Extract blocks
	_.each(plugin.getBlocks(), function(block, blockName) {
        that.book.template.addBlock(blockName, block);
    });

	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;