Redmine Plugin Development - Part1: Generation, Enumerations, Hooks

Posted by Sergey Enin 09 April 2011 at 02:40

Currently redmine represents good and powerfull project management system.

It`s free, powerfull and provide a lot customization and extensable features. Third-party features is rational to implement through plugins, than change the core code, - it is avoid problems when others in your team also would like to customize redmine or when you would like update your instance in future.

Especially great that redmine shows how ruby metaprogramming phylosophy transforms into great solution.

I created for myself little manual, where I described all most interested or obscure questions I faced during work with redmine, separated into 2 parts:

1) Generation, Enumerations, Hooks.

2) Customization.

Below is Part 1.

Please, consider, that I will not cover points that good is on Plugin Page.

 

Generation

To create plugin you need to

ruby script/generate redmine_plugin

so,

rails generate redmine_plugin Polls

  create  vendor/plugins/redmine_polls/app/controllers
  create  vendor/plugins/redmine_polls/app/helpers
  create  vendor/plugins/redmine_polls/app/models
  create  vendor/plugins/redmine_polls/app/views
  create  vendor/plugins/redmine_polls/db/migrate
  create  vendor/plugins/redmine_polls/lib/tasks
  create  vendor/plugins/redmine_polls/assets/images
  create  vendor/plugins/redmine_polls/assets/javascripts
  create  vendor/plugins/redmine_polls/assets/stylesheets
  create  vendor/plugins/redmine_polls/lang
  create  vendor/plugins/redmine_polls/README
  create  vendor/plugins/redmine_polls/init.rb
  create  vendor/plugins/redmine_polls/lang/en.yml


It is creates by default plugin with name: redmine_polls, if you dont want to see prefix redmine_ you can: 1) rename plugin folder; 2) in plugin folder/init.rb raname to new plugin name also; and it`s done

Regarding auto created lang directory -

The location of *.yml translation files, depends on redmine version:

Version                                     Path

< 0.9

.../redmine_polls/lang

>= 0.9

.../redmine_polls/config/locales

Generation of controllers, models and migrations casuals, but you need to rename migrations from timestamp to numbers format.

If you want to migrate specific plugin to version X(for example uninstall specific plugin) you can just:

rake db:migrate:plugin NAME=redmine_products VERSION=0

 

Enumerations

Enumeration is example of rails STI(single table inheretance).

The casual way of adding your own Enumeration` STI child is:

1) in init.rb of your plugin:

require 'dispatcher'

#Hack to add STI ProductSource to subclasses of Enumeration
Dispatcher.to_prepare do
require_dependency 'enumeration'
require_dependency 'product_source'
end

2) in app/models/product_source.rb:

require_dependency 'enumeration'
class ProductSource < Enumeration

OptionName = :product_source_categories
def option_name
OptionName
end
end

3) so, in console:

ruby-1.8.7-p302 > ProductSource.first

=> ProductSource id: 15, name: "Commercial", position: 1, is_default: true, type: "ProductSource", active: true, project_id: nil, parent_id: nil

ruby-1.8.7-p302 > Enumeration.find(15)

=> ProductSource id: 15, name: "Commercial", position: 1, is_default: true, type: "ProductSource", active: true, project_id: nil, parent_id: nil

This way works in production and work in development mode only for first loading of init.rb, this connected with Dispatcher.to_prepare, cause by definition:


Dispatcher.to_prepare(identifier = nil, &block)

Add a preparation callback. Preparation callbacks are run before every request in development mode, and before the first request in production mode. An optional identifier may be supplied for the callback. If provided, to_prepare may be called again with the same identifier to replace the existing callback. Passing an identifier is a suggested practice if the code adding a preparation block may be reloaded.
Source: on GitHub

 

So, when you will try to reload page in development mode, you will have error, like:

Sun Apr 10 17:04:52 +0300 2011: Read error: #TypeError: superclass mismatch for
class ProductSource
redmine/vendor/plugins/products/app/models/product_source.rb
:2

In one of the next articles I will review this more detaily and will try to propose some solutions.

 

Hooks

Hooks is way of insert your own logic into redmine core code, that was provided by redmine developers through inserting special hooks code.

There are 3 types of hooks in redmine:

1) View hooks;

2) Controller hooks;

3) Model hooks;

 

Read next part of guide: Redmine Plugin Development - Part2: Journal, Customization of Redmine Menu and Core

Links:

Posted in , ,  | Tags , , , , , , ,

blog comments powered by Disqus