diff --git a/src/node/eejs/index.js b/src/node/eejs/index.js index 90c69e595..2d02a45a6 100644 --- a/src/node/eejs/index.js +++ b/src/node/eejs/index.js @@ -23,6 +23,7 @@ var ejs = require("ejs"); var fs = require("fs"); var path = require("path"); var hooks = require("ep_etherpad-lite/static/js/pluginfw/hooks.js"); +var resolve = require("resolve"); exports.info = { buf_stack: [], @@ -91,13 +92,28 @@ exports.inherit = function (name, args) { exports.info.file_stack[exports.info.file_stack.length-1].inherit.push({name:name, args:args}); } -exports.require = function (name, args) { +exports.require = function (name, args, mod) { if (args == undefined) args = {}; - - if ((name.indexOf("./") == 0 || name.indexOf("../") == 0) && exports.info.file_stack.length) { - name = path.join(path.dirname(exports.info.file_stack[exports.info.file_stack.length-1].path), name); + + var basedir = __dirname; + var paths = []; + + if (exports.info.file_stack.length) { + basedir = path.dirname(exports.info.file_stack[exports.info.file_stack.length-1].path); } - var ejspath = require.resolve(name) + if (mod) { + basedir = path.dirname(mod.filename); + paths = mod.paths; + } + + var ejspath = resolve.sync( + name, + { + paths : paths, + basedir : basedir, + extensions : [ '.html', '.ejs' ], + } + ) args.e = exports; args.require = require; diff --git a/src/static/js/pluginfw/plugins.js b/src/static/js/pluginfw/plugins.js index b66af58ab..a3a8a8dfd 100644 --- a/src/static/js/pluginfw/plugins.js +++ b/src/static/js/pluginfw/plugins.js @@ -61,7 +61,7 @@ exports.loadFn = function (path, hookName) { return fn; }; -exports.extractHooks = function (parts, hook_set_name) { +exports.extractHooks = function (parts, hook_set_name, plugins) { var hooks = {}; _.each(parts,function (part) { _.chain(part[hook_set_name] || {}) @@ -69,14 +69,27 @@ exports.extractHooks = function (parts, hook_set_name) { .each(function (hook_name) { if (hooks[hook_name] === undefined) hooks[hook_name] = []; - var hook_fn_name = part[hook_set_name][hook_name]; - var hook_fn = exports.loadFn(hook_fn_name, hook_name); + + /* On the server side, you can't just + * require("pluginname/whatever") if the plugin is installed as + * a dependency of another plugin! Bah, pesky little details of + * npm... */ + if (!exports.isClient) { + hook_fn_name = path.normalize(path.join(path.dirname(exports.plugins[part.plugin].package.path), hook_fn_name)); + } + + try { + var hook_fn = exports.loadFn(hook_fn_name, hook_name); + if (!hook_fn) { + throw "Not a function"; + } + } catch (exc) { + console.error("Failed to load '" + hook_fn_name + "' for '" + part.full_name + "/" + hook_set_name + "/" + hook_name + "': " + exc.toString()) + } if (hook_fn) { hooks[hook_name].push({"hook_name": hook_name, "hook_fn": hook_fn, "hook_fn_name": hook_fn_name, "part": part}); - } else { - console.error("Unable to load hook function for " + part.full_name + " for hook " + hook_name + ": " + part.hooks[hook_name]); - } + } }); }); return hooks; @@ -139,7 +152,7 @@ exports.update = function (cb) { if (err) cb(err); exports.plugins = plugins; exports.parts = exports.sortParts(parts); - exports.hooks = exports.extractHooks(exports.parts, "hooks"); + exports.hooks = exports.extractHooks(exports.parts, "hooks"); exports.loaded = true; exports.callInit(cb); }