ether / etherpad-lite Public
Plugin API Draft
Pages 68
General
Resources
- Docs
- Translating
- HTTP API
- Plugin framework (API hooks)
- Plugins (available)
- Plugins (list)
- Plugins (wishlist)
- Stefan's nightly builds (Windows + .deb)
- Etherpad URIs / URLs to specific resources IE export
- Etherpad Full data export
For Developers
- Introduction to the source
- Release Procedure
- Etherpad Developer guidelines
- Project to-do list
- Changeset Library documentation
- Alternative Etherpad-Clients
How to's
Set up
- 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
Advanced steps
- 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
Integrating Etherpad in your web app
- 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
for Developers
Clone this wiki locally
WARNING: This page is NO LONGER APPLICABLE, please check https://github.com/ether/etherpad-lite/wiki/Plugin-API-Hooks for more helpful information....
This is extremely early work - one might even say speculation - on a proposed plugin API. Please add, delete, +1, or -1.
A working of example of how some of this could be implemented lives at https://github.com/jhollinger/etherpad-lite/tree/plugin_api_ideas. Note node/server.js and the new node/features directory, where much of the core functionality has been implemented like plugins.
The Plugin API should be...
- 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
requireanything 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
Examples of functionality/plugins
- 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 colou?r picker - the packaged one could be extended or completely overwritten
Hooks, or server.js pieces which plugins should have direct access to
- 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.
A contrived example
Litter this with code examples of how you'd like things to work.
npm_modules/
epl-example/
index.js (main file)
lib/ (optional, for use by main file)
socketio_thing.js
templates/ (optional, default template location)
huzzah.ejs
static/ (optional, default static file location)
js/
a.js
b.js
css/
c.css
package.json
index.js
var plugin = module.exports;
// Required config
plugin.name = 'example';
plugin.version = '1.0';
// Optional config 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
// Optional pre-init hook. Run before any plugins' init hooks.
plugin.preInit = function() {
}
// Optional post-init hook. Run after all plugins' init hooks.
plugin.postInit = function() {
}
// The primary callback, passed the hooks object.
// Right before preInit, the module is assigned a new prototype, which contains the API.
plugin.init = function(on) {
// Hook for access to the Express app
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
});
});
// Hook for access to the socket.io handler
on.init.socketIO(function(socketIO) {
var iothing = require('./socketio_thing');
socketIO.addComponent('example, iothing);
});
// Hook for adding minified files
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(...
});
// Hook for saving a changset
on.pad.change(function(pad, changeset) {
// email authors about changeset
});
// These (and other) attributes are inherited from the plugin's prototype, which automatically assigned
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!");
}
Other thoughts, concerns
- 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 +1 Pita +1 fourplusone
- 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
- hogan.js - Looks even simpler then EJS
- 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 for etherpad lite to find the installed plugins.
- Some plugins will need configs
- Lots of references to static/js/plugins.js, but it's not obvious (to jhollinger) if they do anything
- Should there be async as well as sync Hooks?
- async hooks for thinks like authentication, middleware (and almost everything server side)
- sync hooks editor related stuff like input validation etc
- A branch on Pita/etherpad-lite where some code (i.e. parts of https://github.com/jhollinger/etherpad-lite/tree/plugin_api_ideas) could be pulled into/discussed +1 jhollinger
Hello. Is it possible that the editor would use the drug n drop function ? And so that it would be possible to change the size of the pictures with the mouse? We want to use the editor to create online lessons. The lesson consists of a video, picture and text.

