Plugin Development

Opal Plugins extend the functionality of Items in Opal. Opal comes with several built-in plugins, like Images, which allow you to upload images to an Item. In this guide, we'll show you how to create an Opal plugin, called Event, which will allow you to schedule events for items. Check out the entire source code for this plugin here.

Getting Started

Plugin Structure

Opal Plugins are currently stored and accessed as Rails Plugins. This means when a Opal user installs your theme, they'll stored in the vendor/plugins directory of Opal. This also means that your model, views, controllers, translations, routes, and other rails goodies will be contained inside the plugin directory.

It's probably easiest if you create and develop your Opal plugin inside your own Opal application. This will make it easy to test, install, and deploy.

Naming Convention

When creating a new Opal plugin, please prefix the plugin directory with opal_. Since we'll be creating an plugin for Events, let's name our directory opal_events.

Plugin Installation

When a user installs your plugin from the Opal Interface, Opal will automatically copy it into the vendor/plugin directory, load your plugin's model(which is stored in app/models within your plugin), and call your model's class method: install(eg: PluginEvent.install). Similarly, when a user uninstalls the plugin, the uninstall class method is called. You can have this method do whatever you want, but you'll probably want to create the Plugin record first.

Each plugin in Opal has one instance/record of the Opal System Model: Plugin. Once this record is created, Users will then see your plugin in the Plugins pages of the Opal Administration Section. This record allows the user to rearrange/sort plugins, disable/enable the plugin, edit settings, and other cool stuff. Here's an example of how to create a Plugin record during the install method:

plugin = Plugin.create(:name => "Event", :is_enabled => "1", :is_builtin => "0")

Next, we'll create your plugin's table for storing data that belongs to a particular item. This is the part where you define what attributes your plugin will have. We'll create this table using ActiveRecord's Migration library:

      ActiveRecord::Migration.create_table :plugin_events do |t|
       t.column :item_id, :integer, :nil => false
       t.column :user_id, :integer, :nil => false
       t.column :title, :string
       t.column :description, :text
       t.column :date, :datetime # date of event
       t.column :price, :string
       t.column :created_at, :datetime 
       t.column :updated_at, :datetime 
       t.column :is_approved, :boolean, :default => false  

Create your Controllers & Views

Next, start creating your controllers and views the app directory of your plugin. This is where the real customization happens, you can make your controllers interact with your new plugin however you'd like, and you can customize your views to fit your visual needs.

Packaging & Publishing

Once you're done creating your plugin, archive it into a zip file. This will allow users to install plugins from Opal's interface. Then, if you'd like to release your plugin to the public, host it over at Customize for free!

Multi-Language Support

Since Opal has multi-language support, you can also add internationalization translations to your plugin. Opal uses Rails' I18n library, you can do this by creating a locale directory in your plugin directory. Here's what the path to a typical locale directory looks like:


A translation file for each language you want to support will be stored in this directory. For example, if I was making an English translation for my plugin, I would create the file: en.yml with the following contents:

          description: Events happening for an Item.
          title: Display Upcoming Events
          description: Display Upcoming Events on Homepage.                  
        one: Event
        other: Events
        title: Title

To get the name of your plugin in views and controllers, always use model_name.human, which will generate the name of your plugin by the model's name, or look up a translated name(if one exists). Here's an example:

puts "Hey I just made an plugin called " + PluginExample.model_name.human # returns "Hey I just made a plugin called Event"