プロジェクト

全般

プロフィール

プラグイン チュートリアル » 履歴 » リビジョン 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" -%>