プロジェクト

全般

プロフィール

Redmineプラグイン開発

プラグイン開発の流れ

まず、自由にいじれる独自のRedmine実行環境を用意します。
Linuxマシンの自分のユーザーのHOMEディレクトリ下にRedmineを展開し、WEBRickサーバーで実行し、DBにはSQLiteを使うのが開発用にはお手軽です。

Redmine開発環境の用意

Linuxコマンドライン環境で簡単な開発環境を用意します。

プラグインの雛形生成

プラグイン名を指定して、以下のコマンドを実行します。

plugins$ bundle exec rails generate redmine_plugin redmine_hello
                                                   ^^^^^^^^^^^^^ 生成するプラグイン名

プラグインの雛形で生成されるディレクトリ構造

redmine_hello/
├─ app
│   ├─ controllers
│   ├─ helpers
│   ├─ models
│   └─ views
├─ assets
│   ├─ images
│   ├─ javascripts
│   └─ stylesheets
├─ config
│   └─ locales
├─ db
│   └─ migrate
├─ lib
│   └─ tasks
└─ test
     ├─ fixtures
     ├─ functional
     ├─ integration
     └─ unit

プラグインの雛形で生成されるファイル

redmine_hello/
├─ README.rdoc
├─ config
│   ├─ locales
│   │   └─ en.yml
│   └─ routes.rb
├─ init.rb
└─ test
     └─ test_helper.rb

プラグイン作成のいろいろな方法

Redmineのプラグインには、いくつかの方法があります。現時点で認識しているプラグイン作成方法でも次のものがあります。

  1. MVCの各部品を作成するMVCプラグイン
  2. 既存の表示に追加するView hooksプラグイン
  3. 既存の表示(ビューテンプレート)を差し替えるプラグイン
  4. 既存の振る舞い(メソッド)を差し替えるパッチプラグイン
  5. マクロを提供するプラグイン

使い分けに関しては、データをデータベースに保存する場合はモデルの定義が必要なのでMVCプラグイン、既存の表示に付けたしをする程度であれば、適するフック箇所があればView hooksプラグイン、なければビューテンプレートを差し替えるプラグインかパッチプラグイン、Wikiの記載でちょっとした処理をするならマクロといったところでしょうか。

フック

Redmineには、プラグインで処理を差し込めるようにあらかじめフックが設けられています。
フックには、View、Controller、Model、HelperとそれぞれRailsの構成要素の種類に応じて用意されています。

フック一覧を調べる

Redmine本家サイトに掲載されています。
http://www.redmine.org/projects/redmine/wiki/Hooks_List

次の方法でも調べることができます(上述ページに記載の方法)。

redmine$ grep -r call_hook *

Viewフックのお試し

チケット一覧のViewに用意されている:view_issues_index_bottomにフックを差し込むサンプルを記述します。
フックの定義は上述の方法で調べました。

redmine$ grep -r call_hook *
  : 
app/views/issues/index.html.erb:<%= call_hook(:view_issues_index_bottom, { :issues => @issues, :project => @project, :query => @query }) %>

フックを実装するRubyのクラスを定義します。

  • redmine/plugins/redmine_mein/lib/redmine_mein/hooks.rb
    module RedmineMein
      class Hooks < Redmine::Hook::ViewListener
        # 実装
      end
    end
    

名前の衝突を避けるため、クラス名にプラグイン名を付けて長くなるのは避けたいので、moduleを使って名前空間を導入します。
ただし、moduleを使うとソースファイルを置く場所がモジュール名に対応するディレクトリの下にする必要があるようです。

モジュール名、クラス名は、Pascalケース(先頭が大文字で、続く単語の先頭が大文字のキャメルケース)で記述しますが、ディレクトリ名、ファイル名はスネークケースになるようです。

次に、このフックをプラグインで有効にするため、init.rbに依存を定義します。

require_dependency 'redmine_mein/hooks'

モジュールを導入しているのでモジュール名に対応するディレクトリとクラス名に対応するファイル名(拡張子.rbは不要)を記述します。

コントローラーとビュー

RailsのMVC構造におけるVCの部分を作成します。モデルは既存のものを利用します。
プラグインとしては、既にあるデータを活用して、新たなビューを作りたいときに該当します。

コントローラーの雛形作成

書式: ruby bin/rails generate redmine_plugin_controller <プラグイン名> <コントローラー名> <アクション>...
redmine$ ruby bin/rails generate redmine_plugin_controller redmine_mein mein index
create  plugins/redmine_mein/app/controllers/mein_controller.rb
      create  plugins/redmine_mein/app/helpers/mein_helper.rb
      create  plugins/redmine_mein/test/functional/mein_controller_test.rb
      create  plugins/redmine_mein/app/views/mein/index.html.erb

コントローラーには雛形生成時に指定したindexアクションに対応するindexメソッドが定義されます。
ビューには雛形生成時に指定したindexアクションに対応するindex.html.erbファイルが生成されます。

ルート設定

プラグインディレクトリ下のconfig/routes.rb にパスを定義します。

Rails.application.routes.draw do
  resources :mein
end

resources で指定したコントローラーは、URLのパスにコントローラー名でアクセスが可能となります。
この例では、http://<サーバー名>/mein でindexメソッドに処理が渡されます。

resources :mein の指定で、次のHTTPリクエストに対するコントローラーのメソッド呼び出しの対応が定義されます。

リクエストメソッド リクエストURI コントローラー メソッド
GET /mein mein index
POST /mein create
GET /mein/new new
GET /mein/:id/edit edit
GET /mein/:id show
PATCH, PUT /mein/:id update
DELETE /mein/:id destroy

ルート設定の確認は、次のコマンドで可能です。

redmine$ bundle exec rake routes
indexアクションだけをルート定義する
resources :mein, only: :index
プロジェクトの下でコントローラーにアクセスする

T.B.D.

マクロ

マクロは、Wikiに埋め込むと実行時に展開されるブロックです。

便利集

Railsコンソール

Rails環境をコンソールで扱います。

redmine$ bundle exec rails console
irb(main):002:0> "man".pluralize
=> "men" 
irb(main):003:0>

参考資料

RAILS GUIDES日本語訳

クリップボードから画像を追加 (サイズの上限: 1 GB)