How To: Writing a Plugin

Jump to: navigation, search

Contents

Requirements

Writing a plugin for Omeka requires a working knowledge of PHP, some experience with the Linux operating system, and a basic familiarity with the Omeka system architecture (a highly modified and extended Zend Framework). Some experience with MySQL may also be needed.

Basic Plugin Writing

There are myriad ways to write an Omeka plugin, but here we'll touch on the most rudimentary. Let's say your client wants to add Creative Commons license information to the bottom of every item page. You could simply modify your Omeka theme to include this information in the /items/show.php template file. But why not write a plugin that does the same thing and lets you share it with other Omeka developers? This ability to share new functionality is the primary reason for writing plugins.

Your solution to your client's request will be to create a plugin that appends Creative Commons markup to every item show page. Here's how to do that:

The first thing you must do is make a new directory within the plugins directory (which is within the Omeka root directory). Make sure to name your plugin appropriately. An appropriate name is one that is not already in use in the Omeka Plugins Directory, one that adequately and succinctly describes your plugin, one that uses CamelCase, and one that will play well with established namespaces.

For our purposes, let's name our plugin "CreativeCommonsLicense ":

[~]$ cd /path/to/omeka/root/plugins/
[plugins]$ mkdir CreativeCommonsLicense

Once your plugin directory is made, the next step is to create the core plugin file within that directory. This file must be named "plugin.php". Remember that every Omeka plugin requires at a minimum a file named plugin.php to exist.

Let's create the plugin.php file now, within the CreativeCommonsLicense directory:

[plugins]$ cd CreativeCommonsLicense/
[CreativeCommonsLicense]$ touch plugin.php

(You can create your plugin.php file any way you want. Just be sure to place it within your plugin directory.)

Now you have a working Omeka plugin! Go to your Omeka installation and go to the following page: Settings -> Plugins. You should be notified that your plugin was successfully installed. Of course your plugin is worthless in its present state, so let's make it do something.

First you need to add the function that will allow your plugin to "hook into" the rest of Omeka; that is, to call functions in your plugin at specific times, and thereby set your plugin in motion. For now we only need one plugin hook: the append_to_item_show hook, which is called (or "fired") at the bottom of the administrative theme's item show page. (We'll show you how to call hooks in the public themes later.)

To add the hook, simply add the add_plugin_hook() function in your plugin.php file, like below:

<?php
add_plugin_hook("append_to_item_show", "creativeCommonsLicenseItemShow");
?>

As you see above, the add_plugin_hook() function takes two arguments:

  1. The name of the hook. (A list of all available hooks can be found here.)
  2. The name of your custom function that will run when the hook is called.

For your custom function we suggest that you prepend your plugin name to the function name. This way you avoid conflict with another function somewhere else in the system.

Here the name of your function is creativeCommonsLicenseItemShow, so let's add that function to the plugin.php file:

<?php
add_plugin_hook("append_to_item_show", "creativeCommonsLicenseItemShow");
 
function creativeCommonsLicenseItemShow($item)
{
}
?>

You'll notice that the creativeCommonsLicenseItemShow() accepts the argument $item, which is automatically available from the append_to_item_show hook. The variable $item is an item object and contains all possible information about the item.

Right now your plugin works, but it needs some content. Let's say that your client wants every item in Omeka to be licensed under Creative Commons's "Attribution-Noncommercial-Share Alike." Here's the XHTML markup (as generated by the Creative Commons website):

<a rel="license" 
   href="http://creativecommons.org/licenses/by-nc-sa/3.0/us/">
<img alt="Creative Commons License" 
     style="border-width:0" 
     src="http://i.creativecommons.org/l/by-nc-sa/3.0/us/88x31.png" />
</a>
<br />This work is licensed under a 
<a rel="license" 
   href="http://creativecommons.org/licenses/by-nc-sa/3.0/us/">Creative Commons 
Attribution-Noncommercial-Share Alike 3.0 United States License</a>.

Now let's put the markup in the creativeCommonsLicenseItemShow() function and finish this plugin:

<?php
add_plugin_hook('append_to_item_show', 'creativeCommonsLicenseItemShow');
 
function creativeCommonsLicenseItemShow($item)
{
?>
<p>
<a rel="license" 
   href="http://creativecommons.org/licenses/by-nc-sa/3.0/us/">
<img alt="Creative Commons License" 
     style="border-width:0" 
     src="http://i.creativecommons.org/l/by-nc-sa/3.0/us/88x31.png" />
</a>
<br />This work is licensed under a 
<a rel="license" 
   href="http://creativecommons.org/licenses/by-nc-sa/3.0/us/">Creative Commons 
Attribution-Noncommercial-Share Alike 3.0 United States License</a>.
</p>
<?php
}
?>

Congratulations! You now have a fully operational plugin. Try it out by going to the administrative interface and viewing an item. Look at the bottom of the page and you'll see the license.

Advanced Plugin Writing

But why stop here? Let's say your client wants to display the same license but also wants to embed the item's title and type. Here's the XHTML markup (as generated by the Creative Commons website):

<a rel="license" 
   href="http://creativecommons.org/licenses/by-nc-sa/3.0/us/">
<img alt="Creative Commons License" 
     style="border-width:0" 
     src="http://i.creativecommons.org/l/by-nc-sa/3.0/us/88x31.png" />
</a>
<br />
<span xmlns:dc="http://purl.org/dc/elements/1.1/" 
      href="http://purl.org/dc/dcmitype/???" 
      property="dc:title" 
      rel="dc:type">???</span> is licensed under a 
<a rel="license" 
   href="http://creativecommons.org/licenses/by-nc-sa/3.0/us/">Creative Commons 
Attribution-Noncommercial-Share Alike 3.0 United States License</a>.

You may notice that the type and title have placeholders for now, so let's put the markup in the creativeCommonsLicenseItemShow() function, dynamically include the item's type and title (using the passed $item object), and finish this plugin:

<?php
add_plugin_hook('append_to_item_show', 'creativeCommonsLicenseItemShow');
 
function creativeCommonsLicenseItemShow($item)
{
    // Set the item's title.
    $title = $item->title ? $item->title : 'This item';
 
    // Customize this mapping array to the item types in your archive.
    $typeMapping = array(
        // Dublin Core type      // Array of types in your archive that map to 
                                 // the specific Dublin Core type.
        'Collection'          => array(),
        'Dataset'             => array(),
        'Event'               => array('Event'),
        'Image'               => array(),
        'InteractiveResource' => array('Website', 'Interactive Resource'),
        'MovingImage'         => array('Moving Image'), 
        'PhysicalObject'      => array('Person'),
        'Service'             => array(),
        'Software'            => array(),
        'Sound'               => array('Oral History', 'Sound'),
        'StillImage'          => array('Still Image'),
        'Text'                => array('Document', 'Email', 'Lesson Plan', 
                                       'Hyperlink')
    );
 
    // Set the item's type.
    $type = false;
    foreach ($typeMapping as $dcType => $typeMap) {
        if (in_array($item->Type->name, $typeMap)) {
            $type = $dcType;
            break;
        }
    }
?>
<p>
<a rel="license" 
   href="http://creativecommons.org/licenses/by-nc-sa/3.0/us/">
<img alt="Creative Commons License" 
     style="border-width:0" 
     src="http://i.creativecommons.org/l/by-nc-sa/3.0/us/88x31.png" />
</a>
<br />
<span xmlns:dc="http://purl.org/dc/elements/1.1/" 
      <?php if ($type): ?>
      href="http://purl.org/dc/dcmitype/<?= $type ?>" 
      rel="dc:type" 
      <?php endif; ?>
      property="dc:title"><?= $title ?></span> is licensed under a 
<a rel="license" 
   href="http://creativecommons.org/licenses/by-nc-sa/3.0/us/">Creative Commons 
Attribution-Noncommercial-Share Alike 3.0 United States License</a>.
</p>
<?php
}
?>

Now when you go to an item show page you'll see the license customized for the particular item.

Plugin Functionality in Public Themes

So, now that you know how to write a plugin for the administrative theme, let's talk about how to include plugin functionality in the public themes. Because they are user generated, public themes usually don't come with the means to fire plugin hooks. But there are several ways to do this:

  • Directly call your custom function from your plugin (recommended).
  • Add the fire_plugin_hook() function to your public theme (not recommended).

The first option is to directly call the custom function from your plugin. In the case of our example plugin, simply open your public theme items/show.php file and write the following code before the footer:

<?php
if (function_exists('creativeCommonsLicenseItemShow')):
    creativeCommonsLicenseItemShow($item);
endif;
?>

Now the license will show up at the bottom of your public item show pages. The reason why we first ask if the function exists is because if the plugin is disabled or uninstalled, the function call will result in a fatal error.

The second way is to add the fire_plugin_hook() function to the appropriate place in the public theme. Only a few hooks can be used this way because most hooks are inaccessible from the public interface. Thankfully, in the case of our example plugin, we can use the append_to_item_show hook. Open your public theme items/show.php file and write the following code before the footer:

<?php fire_plugin_hook('append_to_item_show', $item); ?>

Now the license will show up at the bottom of your public item show pages. The biggest problem with this (and why we don't recommend this option) is that any other plugins that use the append_to_item_show hook will fire, even if they were meant only for the administrator theme.

Plugin Organization

Suppose you are creating a plugin called YourPlugin. You will want to organize your plugin code into the following directories:

  • YourPlugin/models - models used by your plugin
  • YourPlugin/controllers - controllers for your plugin models
  • YourPlugin/views/admin/your-plugin - admin views used by your plugin
  • YourPlugin/views/public/your-plugin - public views used by your plugin
  • YourPlugin/views/shared/your-plugin - shared views used by your plugin
  • YourPlugin/libraries - put external libraries used by your plugin

Note: The directory name of the views folder is not camel-cased, but all lower case, where words are seperated by dashes.

You will also want to create these basic files:

  • YourPlugin/plugin.php - the main plugin file. It should set the version number, configure event hooks to your various functions, and add routes to various controller actions.
  • YourPlugin/plugin.ini - includes the name, author, and brief description of your plugin. This information is displaying in the Admin page when you install the plugin.
  • YourPluging/readme.txt - includes a description of your plugin, along with instructions for how to install and use it.

When you organize your plugin, you should look at other plugins and try to adopt the most common conventions.

Personal tools

Toolbox