Out of the box, Redmine provides a number of generators to facilitate the creation of plugins and plugin resources.
Running rails generate
from the root of our Redmine installation will provide a list of available generators (truncated in the following snippet to list only those that are currently relevant):
Tip
Downloading the example code
This book continually references a sample plugin known as the Redmine Knowledgebase plugin.
The source code is available on GitHub at https://github.com/alexbevi/redmine_knowledgebase and is free to view, modify, and use.
For more information on these generators, the source is available at /path/to/redmine/lib/generators
. For additional information about Ruby on Rails generators, see http://guides.rubyonrails.org/generators.html.
In order to create our knowledgebase plugin, we'll first run the redmine_plugin
generator, which creates the bare minimum folder structure and files we'll need to get started. This is done as follows:
As Redmine's plugin system is inspired by the Rails Engines plugin, they can also be considered as miniature applications that provide functionality to the host (Redmine) application.
Additional information regarding the Redmine plugin internals is available at http://www.redmine.org/projects/redmine/wiki/Plugin_Internals.
The plugin skeleton that the Redmine plugin generator has produced includes placeholders for a number of features we'll want to include later, such as tests, initialization, documentation, MVC, database migrations, and localization.
Using custom gemsets in our plugin
As Redmine is a Ruby on Rails application, all external dependencies are managed using Bundler. This utility greatly simplifies dependency management, but by default only allows a single Gemfile
to be evaluated when a bundle is being installed.
Although not provided by the default plugin generator, if our plugin will require external gemsets, we can add a Gemfile
to our plugin root, which will be automatically merged by Redmine whenever Bundler commands are executed or dependencies are evaluated.
For example, we can create Gemfile
in our plugin root directory as follows:
When the Bundler installation command is run from the root of our Redmine installation, our plugin's custom gems will be included and installed:
Generating models and controllers
The generators introduced previously include variants to generate a plugin's models and controllers.
One of the primary features of our knowledgebase plugin is the ability to manage categories. In order to implement this feature, we'll first have to generate the necessary model, migration, and controller code.
Redmine's plugin model generator parameters are the plugin name, the name of the model, then a list of attributes, and their data types:
As we've provided some field details in our generator, the generated migration will be populated accordingly. The same process can be followed to generate the controller that coincides with our model.
Redmine's plugin controller generator follows the same pattern as the plugin model generator, but doesn't require field details:
Redmine's plugin views cannot be directly generated, but as they follow the standard Rails layout convention of extending ActionController
and ActionView
(http://guides.rubyonrails.org/layouts_and_rendering.html), we can quickly add view templates and partials to our plugin by placing the necessary files under /path/to/redmine/plugins/redmine_knowledgebase/app/views
.
Note
Some of the naming conventions used by the plugin generators at the time of writing this book don't match the Ruby on Rails naming conventions. Database migrations should be prefixed with a timestamp, not an incremental value, and category_controller
would become categories_controller
.
The preceding examples were left intact as they reflect what the actual Redmine plugin generators produce.