TILE Plugin Development

Developing TILE Plugins

This guide teaches the basics of developing a TILE plugin by walking through developing an example plugin HelloWorld.

Building Blocks

The TILE Global Array Object

Everything that is listed in the TILE API can be accessed through a global object instantiated in tile.js. This object is registered as TILE and has several key features:

TILE.engine – the object that allows access to all of the methods for inserting plugins, editing data, and outputting data. These methods are listed in the TILE API.

TILE.scale – the current scale for images.

TILE.url – the current image being displayed or should be displayed

TILE.experimental – a flag that can be set to true or false. If set to true, certain features still under development but released with the current version become active.

The TILE Interface Lifecycle

To understand developing TILE plugins, it is helpful to understand the larger picture of how TILE works. TILE operates in a programmatic work-flow. TILE is initiated as TILE.engine either in a script file or in the index.html file. Plugins are then loaded using TILE.engine.insertPlugin while interface Modes are inserted using TILE.engine.insertMode. Once TILE is activated, it calls the start() method of each plugin. Plugins can then be attached to Modes using TILE.engine.insertModePlugin(). Users load their data in the form of TEI, regular XML, or JSON, which is converted into TILE-formatted JSON. This data is read by the TILE.engine then images and text are parsed out and fed into a copied version of the main JSON object. From here, the user annotates images and text in the collection they uploaded, which triggers key events that edit the core JSON in TILE.engine. When done, the user Saves the data using the Save dialog, which makes TILE.engine create a copy of the JSON that is fed to a PHP script that outputs as either the JSON or XML.

In this cycle, the plugins life can be represented in simple code:

  1. Plugin loaded into TILE
  2. TILE loads necessary dependencies for plugin
  3. TILE is activated, calling start() method of each plugin
  4. start() method sets up plugin HTML and attaches itself to a Mode using TILE.engine.insertModePlugin
  5. User annotates and edits data – plugin updates TILE if any of its data is created, deleted, or updated.
  6. TILE outputs its own copy of JSON

As a diagram:

The code within the index.html file that comes zipped with each TILE release, featuring the above functions:


// At the end of the body element, inside a script tag //

// Initialize the core functions and objects:
// (Metadata dialog, TILE_ENGINE, Save dialog, Toolbar)
engine=new TILE_ENGINE({});

// add Mode
engine.insertMode('Image Annotation');

engine.insertMode('Auto Line Recognizer');

engine.insertMode('Dashboard');
// add plugins
// Image tagger
engine.insertModePlugin('Image Annotation','ImageTagger');
// Auto recognizer
engine.insertModePlugin('Auto Line Recognizer','AutoLineRecognizer');
// transcript lines
engine.insertModePlugin('Image Annotation','Transcript');
// text selection
engine.insertModePlugin('Image Annotation','TextSelection');
// labels
engine.insertModePlugin('Image Annotation','Labels');
// dashboard
engine.insertModePlugin('Dashboard','Dashboard');
// CoreData plugin
engine.insertPlugin('CoreData');
// autoload
engine.insertPlugin('AutoLoad');

// activate with the Image Annotation tool as
// initial tool active
engine.activate('Image Annotation');

 

TILE Events

Once TILE.engine has been activated, it is running all plugins simultaneously. An object called PluginController makes sure that each Mode that is set controls which plugin(s) are on the screen and taking up browser memory at any given time.

newJSON

Whenever TILE.engine loads a new set of data, it triggers a broadcast event for all listening plugins to either process the data or to ignore the event.

newPage

Since TILE is focused on editing images, it may be important for a plugin to register if there is a new page being displayed. Pages represent states of the data, with all of the related objects and items attached to that page data.

newActive – passes a TILE object

Triggered whenever a plugin initiates the TILE.engine.setActiveObj({Object}) method. Passed object is the new active object.

dataAdded – passes a TILE object

Triggered whenever an object is created and added to the TILE core. Passed object is the TILE object that is created.

dataUpdated – passes a TILE object

Triggered whenever data already inserted into the TILE core JSON is updated. Passed object is the TILE object that was updated.

dataDeleted – passes a TILE object

Triggered whenever TILE JSON data is deleted. Passed object is the object that was deleted.

dataLinked – passes an array of TILE objects

Triggered whenever two objects within TILE are linked together. The passed object is an array of the two TILE objects that are now linked together.

Saving and Loading a Plugin

All TILE plugins need to be saved in Javascript files with the name tileplugin.js. The folder name must be the name of the plugin, case-sensitive, but without any dashes or spaces. For example, Image Tagger as a plugin has a folder named “ImageTagger” that contains a Javascript file that runs the plugin called tileplugin.js.

TILE looks for plugin folders in the plugins/ directory of the root TILE installation. When using the method TILE.engine.insertPlugin({Plugin Name}), the Plugin Name parameter refers to two things. The first is the name that appears in the name variable of the plugin wrapper. The second is the name of the folder in the plugins/ directory that contains the tileplugin.js file that initiates the plugin wrapper into TILE. This is explained in more detail in the next section, TILE HelloWorld Plugin.

TILE HelloWorld Plugin

This leads to how to write a plugin. A TILE plugin is simply a Javascript object that contains an essential core of properties and methods, and any number of additional properties and methods a developer wishes to have included. The core property is just one: name, which is the String that identifies the plugin. The only core method that is required for any plugin is start, which is called after the TILE engine completes its activation() method.

Generating a TILE plugin wrapper

As mentioned in the above sections, a TILE plugin needs to be saved in the plugins/ directory of the TILE root installation directory. Navigating to /plugins/, there are a number of plugin folders present. Assuming no folder is present called HelloWorld, the HelloWorld folder is created and put inside plugins/, thus making /plugins/HelloWorld. Then, a file called tileplugin.js is created and put in /plugins/HelloWorld/.

Opening tileplugin.js in any text editor/IDE, the wrapper can be created by initiating a Javascript Object. The name of this object will be HelloWorld, and it’s created the same way any Javascript variable would be started:


var HelloWorld={
//Note that the name matches what we feed into TILE.engine
name:"HelloWorld",
// Start method that is called by TILE.engine on activation
start:function(){
// Override

}

};

So far, all that has been created is one variable name, which is the value fed into TILE.engine.insertPlugin. One final piece has to be created, however.


// Pass the plugin wrapper to TILE
TILE.engine.registerPlugin(HelloWorld);

In order for TILE to receive the plugin wrapper, it must be passed to TILE.engine through TILE.engine.registerPlugin. Now, the plugin is ready to be inserted into the index.html file. Opening index.html and scrolling down, this script is inserted/modified:


// Create TILE.engine
var engine=new TILE_ENGINE({});

// add Plugin
engine.insertPlugin("HelloWorld"); // parameter matches folder in plugins/ and name variable

// activate engine and all appended plugins
engine.activate();

 

(Optional) Inserting HelloWorld into its own Mode

Every plugin in TILE can be inserted into a specific Mode using TILE.engine.insertModePlugin(). A Mode is a container for plugins. Whenever a Mode is created, a new button up on the Global TILE navigation bar (In the upper header area, nearest the right side) is created with the Mode’s name. When this button is pressed, a modeIsActive event is triggered, and the Mode hides all other HTML not related to the plugins it contains, and shows only the HTML for its own plugins.

Returning to index.html, HelloWorld is inserted into its own Mode “Tutorial”:

// Create TILE.engine
var engine=new TILE_ENGINE({});

// Create a Mode object
// Give name for Mode as parameter
engine.insertMode("Tutorial");

// add Plugin to the Mode
// first parameter is the Mode name
// second parameter matches folder in plugins/ and name variable
engine.insertModePlugin("Tutorial", "HelloWorld");

// activate engine and all appended plugins
engine.activate();

 

 

 

This creates a new button called “Tutorial” that, when pressed, will activate the HelloWorld plugin in addition to any other plugins added to the “Tutorial” mode using TILE.engine.insertModePlugin.

TILE Mode objects trigger an event whenever they become active. This event is called modeActive and it passes one variable: the name of the Mode as a string. This can be useful if a plugin has to perform an action or sequence of actions whenever its Mode is activated.

 

Creating the Start Method

Here is HelloWorld with just a start method and name:
var HelloWorld={
name:”HelloWorld”,
// Beginning start function
start:function(mode){
var self=this;

self.objects=[];

// HTML to be displayed in interface

var html=’

HELLO WORLD!

’;

// insert HTML into the interface
TILE.engine.insertModeHTML(html,’rightarea’,mode.name);

// Insert listener for button
$(“#helloworldObj”).click(function(e){

e.preventDefault();

// Does nothing for now

});

}

 

 

 

 

};

In this case, the start method is a simple function that creates a String of html, then inserts that into the TILE interface using the insertModeHTML method found in the TILE API.

Creating and Inserting an Object into the TILE JSON

In order to edit the data in TILE.engine, there needs to be some interactivity between the plugin and the TILE core. This can be accomplished through use of the TILE API.

To start, the click event for the #helloworldObj should be changed:

$(“#helloworldObj”).click(function(e){
    e.preventDefault();
    // Create object

	var id='helloworld'+(self.objects.length+1);
	var obj={id:id,text:’Hello’};
	self.objects.push(obj);

	// put into TILE wrapper
	var tileObj={
		id:id,
		type:'helloworld',
		jsonName:'helloworld',
		obj:obj
	};

	// Insert into TILE
	TILE.engine.insertData(tileObj);

});

First, the function creates an ordinary object – this can be anything so as long as the result is a JSON-readable object. Next, the object has to be wrapped into a TILE object. A TILE object is made up of id (The unique ID of the object), type (A unique name for what type of object has been output), jsonName (The name of the array to be saved in the TILE JSON – use the global variable TILE.url to save the array in the current page data), and obj (The object that was created). In this case, the HelloWorld object will be saved in an array outside of the pages array of the TILE JSON called ‘helloworld’.

More data manipulation methods can be found in the TILE API page.

Creating Event Listeners

If TILE inserts, deletes, or updates data that does not belong to the HelloWorld plugin, it will alert HelloWorld plugin through the use of event triggers. These are event triggers as outlined in the W3C specifications and jQuery (http://api.jquery.com/category/events/event-object/). This example will show how to assign a listener within the HelloWorld plugin to dataAdded.

In order for HelloWorld to detect if a page has been changed, it binds a listener to the body:first selector:

// attach listener
$("body:first").bind("dataAdded",function(e,obj){
	// obj refers to the object that has been added into TILE
	// obj is a JSON object in TILE-format (properties: id,type,jsonName,obj)

	// attach obj data to main screen of plugin
	$("#helloworld_body").text("Data attached: "+JSON.stringify(obj));

});

This concludes the basics of plugin development. For more information, there is source code for all of the major plugins (Transcript lines, Image Tagger, Auto Line Recognizer, Text Selections, Dashboard) within the root directory under plugins/.

Post a Comment

You must be logged in to post a comment.