プラグイン チュートリアル » 履歴 » リビジョン 18
リビジョン 17 (Haru Iida, 2009/05/31 15:23) → リビジョン 18/19 (Haru Iida, 2009/05/31 15:26)
www.redmine.orgの"Plugin Turorial":http://www.redmine.org/wiki/redmine/Plugin_Tutorial を和訳してみます。 h1. プラグイン チュートリアル 注意: このチュートリアルはRedmineの開発リビジョン @r1786@ 以上を対象にしています。 {{toc}} h2. 新しいプラグインを作る。 プラグインの新規作成はRedmineのプラグインジェネレータを使用して行うことができます。 ジェネレータのコマンドは以下です。: <pre>ruby script/generate redmine_plugin <plugin_name></pre> コマンドプロンプトを開き "cd" であなたがredmineをインストールしたディレクトリに移動し、以下のコマンドを実行してみましょう。: % ruby script/generate redmine_plugin Polls @vendor/plugins/redmine_polls@ の下に以下のようなファイルとディレクトリが作られます: <pre> 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 </pre> @vendor/plugins/redmine_polls/init.rb@ を編集してあなたのプラグインの情報を書き込んでください。(name, author, description および version): <pre><code class="ruby"> require 'redmine' Redmine::Plugin.register :redmine_polls do name 'Polls plugin' author 'John Smith' description 'A plugin for managing polls' version '0.0.1' end </code></pre> そしてRedmineを起動し、ブラウザから次のアドレスを入力します。http://localhost:3000/admin/info. ログイン後、あなたのプラグインがプラグイン一覧に加わっていることが確認できます。 !plugins_list1.png! h2. モデルを作る それではこのプラグインのモデルとして Poll を作ってみましょう。: ruby script/generate redmine_plugin_model polls poll question:string yes:integer no:integer このコマンドで Poll モデルおよびPollモデルに対応したマイグレーションファイルが作成されます。 (訳注:マイグレーションファイルとは、RedmineのDBにこのモデル用のテーブルを作成するためのスクリプトファイルです) ここで注意が必要です。timestamped migrationは今のRedmineプラグインエンジンではサポートされていません。ファイル名についているタイムスタンプを"001", "002"のような名前に変更してください。 実際にデータベースへのマイグレーションを行うためには以下のコマンドを実行します。: rake db:migrate_plugins すべてのプラグインはそれぞれに自身のマイグレーションファイルを持っています。 それではconsoleスクリプトからPollのデータを追加してみましょう。ちゃんとテーブルが作られていることを確認できます。consoleを使用すると対話的にRedmineを動かして確認できます。また、遊びながらいろいろな情報を得ることができます。それでは2つのPollオブジェクトを作ります。 <pre> script/console >> Poll.create(:question => "Can you see this poll ?") >> Poll.create(:question => "And can you see this other poll ?") >> exit </pre> プラグインディレクトリの @vendor/plugins/redmine_polls/app/models/poll.rb@ を編集して #vote メソッドを追加しましょう。このメソッドはコントローラから実行されるものです。: <pre><code class="ruby"> class Poll < ActiveRecord::Base def vote(answer) increment(answer == 'yes' ? :yes : :no) end end </code></pre> h2. コントローラを作成する。 この段階ではまだこのプラグインは何もすることができません。このプラグインにコントローラを追加してみましょう。コントローラの作成にはプラグインコントローラジェネレータを使用できます。文法は以下です。: <pre>ruby script/generate redmine_plugin_controller <plugin_name> <controller_name> [<actions>]</pre> ではコマンドプロンプトから以下のように打ってみましょう。: <pre> % ruby script/generate redmine_plugin_controller Polls polls index vote exists app/controllers/ exists app/helpers/ create app/views/polls create test/functional/ create app/controllers/polls_controller.rb create test/functional/polls_controller_test.rb create app/helpers/polls_helper.rb create app/views/polls/index.html.erb create app/views/polls/vote.html.erb </pre> コントローラ @PollsController@ と2つのアクション (@#index@ and @#vote@) が作成されます。 @vendor/plugins/redmine_polls/app/controllers/polls_controller.rb@ を編集して 2つのアクションを実装します。 <pre><code class="ruby"> class PollsController < ApplicationController unloadable def index @polls = Poll.find(:all) end def vote poll = Poll.find(params[:id]) poll.vote(params[:answer]) if poll.save flash[:notice] = 'Vote saved.' redirect_to :action => 'index' end end end </code></pre> そして @vendor/plugins/redmine_polls/app/views/polls/index.html.erb@ を編集すると先ほど作成した2つのpollを表示できます。: <pre> <h2>Polls</h2> <% @polls.each do |poll| %> <p> <%= poll[:question] %>? <%= link_to 'Yes', {:action => 'vote', :id => poll[:id], :answer => 'yes'}, :method => :post %> (<%= poll[:yes] %>) / <%= link_to 'No', {:action => 'vote', :id => poll[:id], :answer => 'no'}, :method => :post %> (<%= poll[:no] %>) </p> <% end %> </pre> @vendor/plugins/redmine_polls/app/views/polls/vote.html.erb@ は対応するactionから使われることがないので削除してよいです。 さあ、Redmineを再起動してブラウザから http://localhost:3000/polls にアクセスしましょう。 2つのpollが確認でき、それらに投票することができるでしょう。: !pools1.png! もしRedmineをプロダクションモードで動かしていない場合、pollの結果はリクエスト毎にリセットされます。これは今回の例ではpollモデルをclass変数に格納しているためです。 Note that poll results are reset on each request if you don't run the application in production mode, since our poll "model" is stored in a class variable in this example. h2. メニューを拡張する。 コントローラは動くようになりましたが、このままではユーザはURLを知らない限り投票画面を見ることができません。RedmineのプラグインAPIを使用するとメニューを拡張できます。アプリケーションメニューに新しい項目を追加してみましょう。 h3. アプリケーションメニューを拡張する。 @vendor/plugins/redmine_polls/init.rb@ を編集してplugin registration blockの最後に以下の行を追加してください。: <pre><code class="ruby"> Redmine::Plugin.register :redmine_polls do [...] menu :application_menu, :polls, { :controller => 'polls', :action => 'index' }, :caption => 'Polls' end </code></pre> 文法は以下です。: menu(menu_name, item_name, url, options={}) 拡張できるメニューは4種類です。: * @:top_menu@ - 最上部の左側のメニュー。 * @:account_menu@ - 最上部の右側のメニュー。ログイン/ログアウトがある。 * @:application_menu@ - プロジェクトの外でのメインメニュー。 * @:project_menu@ - プロジェクト内でのメインメニュー。 以下のオプションが使えます。: * @:param@ - プロジェクトIDを渡すのに用いられる変数のキー。 (デフォルトは @:id@) * @:if@ - メニュー項目のレンダリング前に呼ばれるProc。メニュー項目はこのProcの戻りがtrueの場合にのみ表示される。 * @:caption@ - メニューのキャプション。以下が使えます。: * ローカライズ文字列用シンボル * 文字列 * projectを引数としたProc * @:before@, @:after@ - メニューを挿入する場所の指定 (例 @:after => :activity@ 訳注:「活動」ページの後ろに挿入される) * @:last@ - trueに設定するとメニューの最後に追加される。 (例 @:last => true@) * @:html_options@ - html オプションのHash。メニュー表示時の @link_to@ に渡される。訳注: @link_to@はRailsのAPI 今回の例ではメニュー項目をアプリケーションメニューに追加します。アプリケーションメニューはデフォルトでは空です。 Redmineを再起動して http://localhost:3000 にアクセスしてみましょう。: !application_menu.png! ようこそ画面のPollsタブをクリックして投票画面に行けるはずです。 h3. プロジェクトメニューを拡張する。 さあ、今度はpollsをプロジェクト用プラグインとした場合の例です。(今回のpollモデルはそう設計されてませんが)。Pollsタブをプロジェクトメニューに追加しましょう。 @init.rb@ を開いて先ほど追加した行を以下の2行に書き換えてください。: <pre><code class="ruby"> Redmine::Plugin.register :redmine_polls do [...] permission :polls, {:polls => [:index, :vote]}, :public => true menu :project_menu, :polls, { :controller => 'polls', :action => 'index' }, :caption => 'Polls', :after => :activity, :param => :project_id end </code></pre> 2行目がプロジェクトメニューにPollsタブを追加する定義です。活動タブのすぐ後ろに追加します。 最初の行は @PollsController@ の2つのアクションをpulicにするための設定です。詳細については後ほど説明します。 Redmineを再起動し、プロジェクトを表示します。: !project_menu.png! Pollsタブをクリックしてください。プロジェクトメニューが消えてしまうことに気付きましたか? プロジェクトメニューを表示しておくためにはコントローラのインスタンス変数 @@project@ を設定してあげる必要があります。 PollsController を以下のように編集します。: <pre><code class="ruby"> def index @project = Project.find(params[:project_id]) @polls = Poll.find(:all) # @project.polls end </code></pre> プロジェクトIDはparamの中の @:project_id@ に格納されています。なぜなら先ほどのメニューの定義で @:param => :project_id@ と設定したからです。 さあ、これでPollsタブをクリックしてもプロジェクトメニューが消えなくなりました。: !project_menu_pools.png! h2. パーミッションを定義する。 この状態ではすべての人が投票を行うことができます。ではパーミッションの定義をしてみましょう。 ここでは2種類のプロジェクトベースのパーミッションを定義します。ひとつはpollsの表示に関するもの、もう一つは投票に関するものです。これを行うと、パーミッションはpublicでは無くなります。(@:public => true@ オプションは削除します). @vendor/plugins/redmine_polls/init.rb@ を編集して先ほどのパーミッション定義を以下の2行に置き換えます。: <pre><code class="ruby"> permission :view_polls, :polls => :index permission :vote_polls, :polls => :vote </code></pre> Redmineを再起動して次のURLにアクセスしてみましょう。 http://localhost:3000/roles/report: !permissions1.png! これで既存のロールに対してパーミッションを設定できるようになりました。 もちろん、パーミッションに応じてユーザのアクセス制御を行うためにはPollsControllerにコードを追加する必要があります。 今回の場合は @:authorize@ フィルターを追加すること、およびこのフィルターが呼ばれる前に必ず @project に値がセットされるようにするだけです。 @#index@ アクションでは以下のようにします。: <pre><code class="ruby"> class PollsController < ApplicationController unloadable before_filter :find_project, :authorize, :only => :index [...] def index @polls = Poll.find(:all) # @project.polls end [...] private def find_project # @project variable must be set before calling the authorize filter @project = Project.find(params[:project_id]) end end </code></pre> @#vote@ アクションが動く前に現在のプロジェクトを取得します。これを行うと、投票は管理者もしくはこのプロジェクトの許可されたロールのユーザ以外行えなくなります。 h2. プロジェクトモジュールを作る。 今現在、pollの機能はすべてのプロジェクトに追加されています。しかし、pollsを限られたプロジェクトのみに使わせたい場合もあるでしょう。 ここでは 'Polls' プロジェクトモジュールを作成します. これはパーミッション定義を @#project_module@ 定義で囲むことによって実現します。 @init.rb@ を編集してパーミッションの定義を変更します。: <pre><code class="ruby"> project_module :polls do permission :view_polls, :polls => :index permission :vote_polls, :polls => :vote end </code></pre> Redmineを再起動し、適当なプロジェクトの設定メニューを開きます。そしてモジュールタブをクリックします。するとモジュールリストの最後にPolls moduleがあることが確認できます。 (デフォルトではチェックはついていません): !modules.png! これでプロジェクト毎にPollsの有効・無効を選択できるようになりました。 h2. プラグインの表示を拡張する。 h3. スタイルシートを追加する。 それではプラグインのviewにスタイルシートを追加してみましょう。 @voting.css@ というファイルを @vendor/plugins/redmine_polls/assets/stylesheets@ に作成してください。: <pre> a.vote { font-size: 120%; } a.vote.yes { color: green; } a.vote.no { color: red; } </pre> Redmineを再起動すると、assetsの下はRails Enginesによって自動的に @public/plugin_assets/redmine_polls/@ にコピーされます。これによってWebブラウザからこれらのファイルにアクセスできるようになります。なのでassetsの下のスタイルシートやJavascriptに変更を加えた場合には必ずRedmineの再起動が必要になります。 @vendor/plugins/redmine_polls/app/views/polls/index.html.erb@ に以下の行を加えてください。するとスタイルシートがRedmineのヘッダーからインクルードされます。: <pre> <% content_for :header_tags do %> <%= stylesheet_link_tag 'voting', :plugin => 'redmine_polls' %> <% end %> </pre> @:plugin => 'redmine_polls'@ オプションを @stylesheet_link_tag@ ヘルパーに渡します。 Javascript をプラグインのビューからインクルードするためには@javascript_include_tag@ ヘルパーを同様に使います。 h3. ページタイトルを設定する。 プラグインのviewにHTMLのタイトルを設定するには @html_title@ ヘルパーを使います。 例: <% html_title "Polls" -%>