# Locomotive Plugins [![Build Status](https://secure.travis-ci.org/colibri-software/locomotive_plugins.png)](https://travis-ci.org/colibri-software/locomotive_plugins) This gem is used to develop plugins for [Locomotive CMS](http://locomotivecms.com/). Plugins can be enabled or disabled on each site individually. ## Installation To create a Locomotive Plugin, create a ruby gem and then install this gem: gem install locomotive_plugins Alternatively if you're using Bundler, add the following line to your Gemfile: gem 'locomotive_plugins' and run `bundle install`. To install the plugin in LocomotiveCMS, simply [create a LocomotiveCMS app](http://doc.locomotivecms.com/guides/get-started/install-engine), ensuring you have all of the [Requirements](http://doc.locomotivecms.com/guides/get-started/requirements) installed, and add your plugin gem to the app's Gemfile in the `locomotive_plugins` group: group(:locomotive_plugins) do gem 'my_plugin' gem 'another_plugin' end ## Usage To create a plugin, create a class which includes the `Locomotive::Plugin` module: class BasicAuth include Locomotive::Plugin end The plugin class will automatically be registered under an ID which is its underscored name, in this case, `basic_auth`. To register it under a different ID, simply override the class level method `default_plugin_id`: class BasicAuth include Locomotive::Plugin def self.default_plugin_id 'auth' end end See the sections below for usage examples of the various features. Also, see the [documentation](http://rubydoc.info/github/colibri-software/locomotive_plugins/). ### Initialization There are two methods which can be overridden to customize the initialization process. The class method `plugin_loaded` is called after the rails app first loads the plugin. The `initialize` method may also be overridden in order run custom code when the plugin object is constructed. Note that the `initialize` method must not take any arguments. class MyPlugin include Locomotive::Plugin def self.plugin_loaded # Initial initialization code (only called once) end def initialize # Plugin object initialization code. This is called before each request # for which this plugin is needed end end ### Callbacks A plugin may use ActiveModel callbacks. Currently, two callbacks are supported: `page_render` and `rack_app_request`, both allowing `before`, `around`, and `after` callbacks. The `page_render` callbacks are called for all enabled plugins when a public-facing liquid page in LocomotiveCMS is rendered. The `rack_app_request` callbacks are called for a specific plugin when a request is about to be handed to its rack app (see the section below on including a Rack app in the plugin). The `page_render` callbacks have access to the controller which is being invoked, and both callback types have access to the config variable which is set within the Locomotive UI. class BasicAuth include Locomotive::Plugin before_page_render :authenticate def authenticate if self.config[:use_basic_auth] self.controller.authenticate_or_request_with_http_basic do |username, password| username = USER_ID && password == PASSWORD end end end end ### Liquid Plugins have the ability to add liquid drops, tags, and filters to LocomotiveCMS. These liquid objects will only be accessible to sites which have enabled the plugin. All liquid objects have access to `@context.registers[:plugin_object]` which supplies the plugin object. This gives access to the config hash and other plugin methods. #### Drops A plugin can add a liquid drop which can be accessed from page templates in LocomotiveCMS. To do so, override the `to_liquid` method. Plugin code: class BasicAuth include Locomotive::Plugin def to_liquid BasicAuthDrop.new(self.get_authenticated_user_id) end end class BasicAuthDrop < ::Liquid::Drop def initialize(userid) @userid = userid end def userid @userid end end Liquid code:
Your User ID is: {{ plugins.basic_auth.userid }}
This liquid code assumes that the plugin has been registered under the default ID as described above. #### Filters A plugin can add liquid filters: module Filters def add_http(input) if input.start_with?('http://') input else "http://#{input}" end end end class MyPlugin include Locomotive::Plugin def self.liquid_filters Filters end end Locomotive will automatically prefix the filter with the plugin ID in the liquid code: Click here! #### Tags A plugin may also supply custom liquid tags. The custom tag class may override the `render_disabled` method to specify what should be rendered if the plugin is not enabled. By default, this will be the empty string. For example: # Note that Liquid::Block is a subclass of Liquid::Tag class Paragraph < Liquid::Block def render(context) "#{render_all(@nodelist, context)}
" end def render_disabled(context) render_all(@nodelist, context) end end class Newline < Liquid::Tag def render(context) "Some Text
Some TextMy Hint