-
-
Notifications
You must be signed in to change notification settings - Fork 2.9k
Plugin API Draft
jhollinger edited this page Feb 2, 2012
·
23 revisions
This is extremely early work - one might even say speculation - on a proposed plugin API. Please add, delete, +1, or -1.
- The API should be unified (no distinction between server-side and UI plugins)
- custom js and css will remain, but should not be confused with plugins
- It should allow easy use of templates, as should some parts of core
- Plugins should (generally) be npm modules, but we must allow for "proprietary" plugins that aren't published
- npm plugins should possibly have a prefix - maybe "epl-"?
- Some existing features (e.g. timeslider, chat, import/export) should be pulled out into plugins, but would still be shipped with core
- This helps ensure a quality API and gives plugin authors some great examples
- This implies that plugins should be on the same "level" as core components; they will have deep access to the system
- This moves EPLite towards a "platform" mentality, rather than "an app with some integration points"
- Common, tedious things should be made trivial (e.g. serving custom static assets, rendering templates, adding buttons to the editor)
- "Convention over configuration" - a plugin should be functional (though probably not finished) with but a few lines of code. The author shouldn't even have to
require
anything up-front. - It should use a "global" hooks system
- i.e. use of hooks should not be isolated to plugins. core should use hooks to build (and obviously execute) as much behavior as possible
This example should present the absolute minimum amount of code needed to create a plugin that does some small thing.
This plugin is an npm module named "epl-huzzah". This is its index.js file.
var plugin = module.exports; plugin.name = "huzzah"; plugin.version = "1.0"; plugin.init = function(on) { // Add a routes to the app on.init.app(function(app) { app.get('/p/:pad/huzzah', function(req, res) { plugin.render(res, 'my_template'); }); }); }
- Monospace button
- Syntax highlighting
- A complete Admin UI
- Integrated OpenID/BrowserID auth
- Core features (chat, timeslider, import/export)
- Emailing pad change notifications to authors
- The express app
- SocketIORouter
- The async object from server.js (easier if they don't have to
require
/dependencyify it) - All the other plugins?
- the console, version, root path, server.js.exports.maxAge
- Minify.js - they should be able to append files to pad.js/timeslider.js, or create new minified chains
- Hooks for customizing various parts of the pad editor
- Adding buttons
- ...
- Database store access, for creating new types of objects
- Hooks into pad creation and changes, group creation, author creation, etc.
Litter this with code examples of how you'd like things to work.
npm_modules/ epl-example/ index.js lib/ example.js socketio_thing.js templates/ huzzah.ejs static/ js/ a.js b.js css/ c.css package.json
index.js
module.exports = require('./lib/example.js');
lib/example.js
var plugin = module.exports; // Required settings plugin.name = 'example'; plugin.version = '1.0'; // Optional settings with sensible defaults. These are the defaults. plugin.templates = 'templates'; // Name of plugin's template dir plugin.static = 'static'; // Name of plugin's static assets dir // Right before this hook, the plugin is assigned a new prototype, which contains the API plugin.init = function(on) { on.init.app(function(app) { plugin.serveJS(app); // Serves /static/js/ under "/plugins/example/js/" plugin.serveCSS(app); // CSS equivalent to above app.get('/some/path, function(req, res) { plugin.render(res, 'huzzah'); // Calls "res.render" using a plugin's template }); }); on.init.socketIO(function(socketIO) { var iothing = require('./socketio_thing'); socketIO.addComponent('example, iothing); }); on.init.minify(function(minify) { // Appends "b.js" to the virtual pad.js minified file minify.addJS('pad.js', plugin.jsPath('b.js')); // Creates a new minified chain called "foo.js" and adds two files from the plugin minify.addJS('foo.js', plugin.jsPath('foo1.js')); minify.addJS('foo.js', plugin.jsPath('foo2.js')); }); // Add a button to the pad editor. Any more specific ideas? on.pad.editor(function(editor) { editor.addButton(... }); on.pad.change(function(pad, changeset) { // email authors about changeset }); plugin.rootPath; // The full filesystem path to the plugin's root dir plugin.env.rootPath; // The full filesystem path to the EPL installation plugin.env.console.log("Logging!"); }
- Core will need to convert pad.html and timeslider.html to templates. Which engine should we use?
- EJS - Simple, HTML with embedded JS, should look familiar to most everyone +1 jhollinger
- Jade/HAML - Clean, pseudo-HTML with embedded JS, higher learning curve, somewhat "snooty" in this author's opinion -1 jhollinger
- JSDOM + Weld - Intriguing, but very high learning curve
- How to ensure that a plugin works with a specific version of etherpad lite?
- How to enable plugins? Live via an admin interface or in a config file?
- How can we detect plugins that are jamming up async due to dropped callbacks?
- We need to find a way to get a list of all etherpad lite plugins in the npm registry.
- We need some way so etherpad lite can find the the installed plugins.
- Some plugins will need configs
- Docs
- Translating
- HTTP API
- Plugin framework (API hooks)
- Plugins (available)
- Plugins (list)
- Plugins (wishlist)
- Etherpad URIs / URLs to specific resources IE export
- Etherpad Full data export
- Introduction to the source
- Release Procedure
- Etherpad Developer guidelines
- Project to-do list
- Changeset Library documentation
- Alternative Etherpad-Clients
- Contribution guidelines
- Installing Etherpad
- Deploying Etherpad as a service
- Deploying Etherpad on CloudFoundry
- Deploying Etherpad on Heroku
- Running Etherpad on Phusion Passenger
- Putting Etherpad behind a reverse Proxy (HTTPS/SSL)
- How to setup Etherpad on Ubuntu 12.04 using Ansible
- Migrating from old Etherpad to Etherpad
- Using Etherpad with MySQL
- Customizing the Etherpad web interface
- Enable import/export functionality with AbiWord
- Getting a list of all pads
- Providing encrypted web access to Etherpad using SSL certificates
- Optimizing Etherpad performance including faster page loads
- Getting to know the tools and scripts in the Etherpad /bin/ folder
- Embedding a pad using the jQuery plugin
- Using Embed Parameters
- Integrating Etherpad in a third party app (Drupal, MediaWiki, WordPress, Atlassian, PmWiki)
- HTTP API client libraries