mirror of
https://github.com/NodeBB/NodeBB.git
synced 2025-11-01 11:35:55 +01:00
updates to allow dynamic addition of static directories provided by plugins
This commit is contained in:
2
app.js
2
app.js
@@ -75,7 +75,7 @@ if (fs.existsSync(__dirname + '/config.json') && (!nconf.get('setup') && !nconf.
|
||||
templates = require('./public/src/templates.js'),
|
||||
webserver = require('./src/webserver.js'),
|
||||
websockets = require('./src/websockets.js'),
|
||||
plugins = require('./src/plugins'),
|
||||
plugins = require('./src/plugins'), // Don't remove this - plugins initializes itself
|
||||
admin = {
|
||||
'categories': require('./src/admin/categories.js')
|
||||
};
|
||||
|
||||
@@ -3,9 +3,15 @@ var fs = require('fs'),
|
||||
RDB = require('./redis.js'),
|
||||
async = require('async'),
|
||||
winston = require('winston'),
|
||||
eventEmitter = require('events').EventEmitter,
|
||||
plugins = {
|
||||
libraries: {},
|
||||
loadedHooks: {},
|
||||
staticDirs: {},
|
||||
|
||||
// Events
|
||||
readyEvent: new eventEmitter,
|
||||
|
||||
init: function() {
|
||||
if (this.initialized) return;
|
||||
if (global.env === 'development') winston.info('[plugins] Initializing plugins system');
|
||||
@@ -50,8 +56,13 @@ var fs = require('fs'),
|
||||
}
|
||||
|
||||
if (global.env === 'development') winston.info('[plugins] Plugins OK');
|
||||
|
||||
_self.readyEvent.emit('ready');
|
||||
});
|
||||
},
|
||||
ready: function(callback) {
|
||||
this.readyEvent.once('ready', callback);
|
||||
},
|
||||
initialized: false,
|
||||
loadPlugin: function(pluginPath, callback) {
|
||||
var _self = this;
|
||||
@@ -59,19 +70,48 @@ var fs = require('fs'),
|
||||
fs.readFile(path.join(pluginPath, 'plugin.json'), function(err, data) {
|
||||
if (err) return callback(err);
|
||||
|
||||
var pluginData = JSON.parse(data);
|
||||
_self.libraries[pluginData.id] = require(path.join(pluginPath, pluginData.library));
|
||||
if (pluginData.hooks) {
|
||||
for(var x=0,numHooks=pluginData.hooks.length;x<numHooks;x++) {
|
||||
_self.registerHook(pluginData.id, pluginData.hooks[x]);
|
||||
}
|
||||
}
|
||||
if (global.env === 'development') winston.info('[plugins] Loaded plugin: ' + pluginData.id);
|
||||
var pluginData = JSON.parse(data),
|
||||
libraryPath, staticDir;
|
||||
|
||||
async.parallel([
|
||||
function(next) {
|
||||
if (pluginData.library) {
|
||||
libraryPath = path.join(pluginPath, pluginData.library);
|
||||
|
||||
fs.exists(libraryPath, function(exists) {
|
||||
if (exists) {
|
||||
_self.libraries[pluginData.id] = require(libraryPath);
|
||||
|
||||
if (pluginData.hooks && Array.isArray(pluginData.hooks) && pluginData.hooks.length > 0) {
|
||||
async.each(pluginData.hooks, function(hook, next) {
|
||||
_self.registerHook(pluginData.id, hook, next);
|
||||
}, next);
|
||||
}
|
||||
}
|
||||
});
|
||||
} else next();
|
||||
},
|
||||
function(next) {
|
||||
if (pluginData.staticDir) {
|
||||
staticDir = path.join(pluginPath, pluginData.staticDir);
|
||||
|
||||
fs.exists(staticDir, function(exists) {
|
||||
if (exists) {
|
||||
_self.staticDirs[pluginData.id] = staticDir;
|
||||
next();
|
||||
} else next();
|
||||
});
|
||||
} else next();
|
||||
}
|
||||
], function(err) {
|
||||
if (!err) {
|
||||
if (global.env === 'development') winston.info('[plugins] Loaded plugin: ' + pluginData.id);
|
||||
callback();
|
||||
} else callback(new Error('Could not load plugin system'))
|
||||
});
|
||||
});
|
||||
},
|
||||
registerHook: function(id, data) {
|
||||
registerHook: function(id, data, callback) {
|
||||
/*
|
||||
`data` is an object consisting of (* is required):
|
||||
`data.hook`*, the name of the NodeBB hook
|
||||
@@ -89,6 +129,7 @@ var fs = require('fs'),
|
||||
_self.loadedHooks[data.hook].push([id, data.method, !!data.callbacked, data.priority]);
|
||||
|
||||
if (global.env === 'development') winston.info('[plugins] Hook registered: ' + data.hook + ' will call ' + id);
|
||||
callback();
|
||||
} else return;
|
||||
},
|
||||
fireHook: function(hook, args, callback) {
|
||||
|
||||
@@ -21,7 +21,8 @@ var express = require('express'),
|
||||
testBed = require('./routes/testbed.js'),
|
||||
auth = require('./routes/authentication.js'),
|
||||
meta = require('./meta.js'),
|
||||
feed = require('./feed');
|
||||
feed = require('./feed'),
|
||||
plugins = require('./plugins');
|
||||
|
||||
(function(app) {
|
||||
var templates = null;
|
||||
@@ -81,6 +82,29 @@ var express = require('express'),
|
||||
next();
|
||||
});
|
||||
|
||||
// Static Directories for NodeBB Plugins
|
||||
app.configure(function() {
|
||||
var tailMiddlewares = [];
|
||||
|
||||
plugins.ready(function() {
|
||||
// Remove some middlewares until the router is gone
|
||||
// This is not recommended behaviour: http://stackoverflow.com/a/13691542/122353
|
||||
// Also: https://www.exratione.com/2013/03/nodejs-abusing-express-3-to-enable-late-addition-of-middleware/
|
||||
tailMiddlewares.push(app.stack.pop());
|
||||
tailMiddlewares.push(app.stack.pop());
|
||||
tailMiddlewares.push(app.stack.pop());
|
||||
for(d in plugins.staticDirs) {
|
||||
app.use(nconf.get('relative_path') + '/plugins/' + d, express.static(plugins.staticDirs[d]));
|
||||
}
|
||||
|
||||
// Push the removed middlewares back onto the application stack
|
||||
tailMiddlewares.reverse();
|
||||
app.stack.push(tailMiddlewares.shift());
|
||||
app.stack.push(tailMiddlewares.shift());
|
||||
app.stack.push(tailMiddlewares.shift());
|
||||
});
|
||||
});
|
||||
|
||||
module.exports.init = function() {
|
||||
templates = global.templates;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user