Skip to content
magdmartin edited this page Sep 4, 2014 · 1 revision

How to start writing an extension

(This document applies to v2.0 and later.)

Giuliano Tortoreto write a separate documentation detailling how to build extension for OpenRefine. A LaTeX and PDF version are available on his repository giTorto/OpenRefineExtensionDoc (to do: convert the documentation to Creole and add it to this wiki)

OpenRefine makes use of the Butterfly framework to provide an extension architecture. OpenRefine extensions are Butterfly modules. You don't really need to know about Butterfly itself, but you might encounter "butterfly" here and there in the code base.

Note that Butterfly was chosen over OSGi because

  • Butterfly modules can contain both Java code (server-side) as well as webapp code (client-side); and
  • Unlike OSGi plugins, Butterfly modules don't have to be jarred and copied into one specific directory--both of which tasks make development very painful.

Extensions that come with the code base are located under the extensions subdirectory, but when you develop your own extension, you can put its code anywhere as long as you point Butterfly to it. That is done by any one of the following methods

  • refer to your extension's directory in the butterfly.properites file through a butterfly.modules.path setting.
  • specify the butterfly.modules.path property on the command line when you run OpenRefine. This overrides the values in the property file, so you need to include the default values first e.g. -Dbutterfly.modules.path=modules,../../extensions,/path/to/your/extension

Please note that you should bundle any dependencies yourself, so you are insulated from Refine packaging changes over time.

Directory Layout

A OpenRefine extension (implemented as a Butterfly module) sits in a file directory that contains the following files and sub-directories:

  build.xml
  src/
      com/foo/bar/... *.java source files
  module/
      *.html, *.vt files
      scripts/... *.js files
      styles/... *.css and *.less files
      images/... image files
      MOD-INF/
          lib/*.jar files
          classes/... java class files
          module.properties
          controller.js

The file named module.properties (see example) contains the extension's metadata. Of importance is the name field, which gives the extension a name that's used in many other places to refer to it. This can be different from the extension's directory name.

  name = my-extension-name

Your extension's client-side resources (.html, .js, .css files) stored in the module/ subdirectory will be accessible from http://127.0.0.1:3333/extension/my-extension-name/.

Also of importance is the dependency

  requires = core

which makes sure that the core module of OpenRefine is loaded before the extension attempts to hook into it.

The file named controller.js is responsible for registering the extension's hooks into OpenRefine. Look at the sample-extension extension's controller.js file for an example. It should have a function called init() that does the hook registrations.

The build.xml file is an Apache Ant build file. You can make a copy of the sample extension's build.xml file to get started. The important point here is that the Java classes should be built into the module/MOD-INF/classes sub-directory.

Note that your extension's Java code would need to reference some libraries used in OpenRefine and Refine's Java classes themselves. The libraries are in trunk/main/webapp/WEB-INF/lib/ and Refine's classes are in trunk/main/webapp/modules/core/MOD-INF/classes/.

Clone this wiki locally