プロジェクト

全般

プロフィール

プラグイン チュートリアル » 履歴 » バージョン 16

Haru Iida, 2009/05/31 15:12

1 1 Haru Iida
www.redmine.orgの"Plugin Turorial":http://www.redmine.org/wiki/redmine/Plugin_Tutorial を和訳してみます。
2
3
h1. プラグイン チュートリアル
4
5 6 Haru Iida
注意: このチュートリアルはRedmineの開発リビジョン @r1786@ 以上を対象にしています。
6 1 Haru Iida
7
{{toc}}
8
9
h2. 新しいプラグインを作る。
10
11
プラグインの新規作成はRedmineのプラグインジェネレータを使用して行うことができます。
12
ジェネレータのコマンドは以下です。:
13
14
<pre>ruby script/generate redmine_plugin <plugin_name></pre>
15
16
コマンドプロンプトを開き "cd" であなたがredmineをインストールしたディレクトリに移動し、以下のコマンドを実行してみましょう。:
17
18
  % ruby script/generate redmine_plugin Polls
19
20 2 Haru Iida
@vendor/plugins/redmine_polls@ の下に以下のようなファイルとディレクトリが作られます:
21 1 Haru Iida
22
<pre>
23
      create  vendor/plugins/redmine_polls/app/controllers
24
      create  vendor/plugins/redmine_polls/app/helpers
25
      create  vendor/plugins/redmine_polls/app/models
26
      create  vendor/plugins/redmine_polls/app/views
27
      create  vendor/plugins/redmine_polls/db/migrate
28
      create  vendor/plugins/redmine_polls/lib/tasks
29
      create  vendor/plugins/redmine_polls/assets/images
30
      create  vendor/plugins/redmine_polls/assets/javascripts
31
      create  vendor/plugins/redmine_polls/assets/stylesheets
32
      create  vendor/plugins/redmine_polls/lang
33
      create  vendor/plugins/redmine_polls/README
34
      create  vendor/plugins/redmine_polls/init.rb
35
      create  vendor/plugins/redmine_polls/lang/en.yml
36
</pre>
37
38 2 Haru Iida
@vendor/plugins/redmine_polls/init.rb@ を編集してあなたのプラグインの情報を書き込んでください。(name, author, description および version):
39 1 Haru Iida
40
<pre><code class="ruby">
41
require 'redmine'
42
43
Redmine::Plugin.register :redmine_polls do
44
  name 'Polls plugin'
45
  author 'John Smith'
46
  description 'A plugin for managing polls'
47
  version '0.0.1'
48
end
49
</code></pre>
50
51 2 Haru Iida
そしてRedmineを起動し、ブラウザから次のアドレスを入力します。http://localhost:3000/admin/info.
52
ログイン後、あなたのプラグインがプラグイン一覧に加わっていることが確認できます。
53 1 Haru Iida
54 4 Haru Iida
!plugins_list1.png!
55 1 Haru Iida
56 5 Haru Iida
h2. モデルを作る
57 1 Haru Iida
58 5 Haru Iida
それではこのプラグインのモデルとして Poll を作ってみましょう。:
59 1 Haru Iida
60
  ruby script/generate redmine_plugin_model polls poll question:string yes:integer no:integer
61
62 5 Haru Iida
このコマンドで Poll モデルおよびPollモデルに対応したマイグレーションファイルが作成されます。
63
(訳注:マイグレーションファイルとは、RedmineのDBにこのモデル用のテーブルを作成するためのスクリプトファイルです)
64 1 Haru Iida
65 5 Haru Iida
ここで注意が必要です。timestamped migrationは今のRedmineプラグインエンジンではサポートされていません。ファイル名についているタイムスタンプを"001", "002"のような名前に変更してください。
66 1 Haru Iida
67 5 Haru Iida
実際にデータベースへのマイグレーションを行うためには以下のコマンドを実行します。:
68 1 Haru Iida
69
  rake db:migrate_plugins
70
71 5 Haru Iida
すべてのプラグインはそれぞれに自身のマイグレーションファイルを持っています。
72 1 Haru Iida
73 6 Haru Iida
それではconsoleスクリプトからPollのデータを追加してみましょう。ちゃんとテーブルが作られていることを確認できます。consoleを使用すると対話的にRedmineを動かして確認できます。また、遊びながらいろいろな情報を得ることができます。それでは2つのPollオブジェクトを作ります。
74 1 Haru Iida
75
<pre>
76
script/console
77
>> Poll.create(:question => "Can you see this poll ?")
78
>> Poll.create(:question => "And can you see this other poll ?")
79
>> exit
80
</pre>
81
82 6 Haru Iida
プラグインディレクトリの @vendor/plugins/redmine_polls/app/models/poll.rb@ を編集して #vote メソッドを追加しましょう。このメソッドはコントローラから実行されるものです。:
83 1 Haru Iida
84
<pre><code class="ruby">
85
class Poll < ActiveRecord::Base
86
  def vote(answer)
87
    increment(answer == 'yes' ? :yes : :no)
88
  end
89
end
90
</code></pre>
91
92 7 Haru Iida
h2. コントローラを作成する。
93 1 Haru Iida
94 7 Haru Iida
この段階ではまだこのプラグインは何もすることができません。このプラグインにコントローラを追加してみましょう。コントローラの作成にはプラグインコントローラジェネレータを使用できます。文法は以下です。:
95 1 Haru Iida
96
<pre>ruby script/generate redmine_plugin_controller <plugin_name> <controller_name> [<actions>]</pre>
97
98 7 Haru Iida
ではコマンドプロンプトから以下のように打ってみましょう。:
99 1 Haru Iida
100
<pre>
101
% ruby script/generate redmine_plugin_controller Polls polls index vote
102
      exists  app/controllers/
103
      exists  app/helpers/
104
      create  app/views/polls
105
      create  test/functional/
106
      create  app/controllers/polls_controller.rb
107
      create  test/functional/polls_controller_test.rb
108
      create  app/helpers/polls_helper.rb
109
      create  app/views/polls/index.html.erb
110
      create  app/views/polls/vote.html.erb
111
</pre>
112
113 7 Haru Iida
コントローラ @PollsController@ と2つのアクション (@#index@ and @#vote@) が作成されます。
114 1 Haru Iida
115 7 Haru Iida
@vendor/plugins/redmine_polls/app/controllers/polls_controller.rb@ を編集して 2つのアクションを実装します。
116 1 Haru Iida
117
<pre><code class="ruby">
118
class PollsController < ApplicationController
119
  unloadable
120
121
  def index
122
    @polls = Poll.find(:all)
123
  end
124
125
  def vote
126
    poll = Poll.find(params[:id])
127
    poll.vote(params[:answer])
128
    if poll.save
129
      flash[:notice] = 'Vote saved.'
130
      redirect_to :action => 'index'
131
    end
132
  end
133
end
134
</code></pre>
135
136 8 Haru Iida
そして @vendor/plugins/redmine_polls/app/views/polls/index.html.erb@ を編集すると先ほど作成した2つのpollを表示できます。:
137 1 Haru Iida
138
139
<pre>
140
<h2>Polls</h2>
141
142
<% @polls.each do |poll| %>
143
  <p>
144
  <%= poll[:question] %>?
145
  <%= link_to 'Yes', {:action => 'vote', :id => poll[:id], :answer => 'yes'}, :method => :post %> (<%= poll[:yes] %>) /
146
  <%= link_to 'No', {:action => 'vote', :id => poll[:id], :answer => 'no'}, :method => :post %> (<%= poll[:no] %>)
147
  </p>
148
<% end %>
149
</pre>
150
151 8 Haru Iida
@vendor/plugins/redmine_polls/app/views/polls/vote.html.erb@ は対応するactionから使われることがないので削除してよいです。
152 1 Haru Iida
153 8 Haru Iida
さあ、Redmineを再起動してブラウザから http://localhost:3000/polls にアクセスしましょう。
154
2つのpollが確認でき、それらに投票することができるでしょう。:
155 1 Haru Iida
156 8 Haru Iida
!pools1.png!
157 1 Haru Iida
158
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.
159
160 9 Haru Iida
h2. メニューを拡張する。
161 1 Haru Iida
162 9 Haru Iida
コントローラは動くようになりましたが、このままではユーザはURLを知らない限り投票画面を見ることができません。RedmineのプラグインAPIを使用するとメニューを拡張できます。アプリケーションメニューに新しい項目を追加してみましょう。
163 1 Haru Iida
164 9 Haru Iida
h3. アプリケーションメニューを拡張する。
165 1 Haru Iida
166 9 Haru Iida
@vendor/plugins/redmine_polls/init.rb@ を編集してplugin registration blockの最後に以下の行を追加してください。:
167 1 Haru Iida
168
<pre><code class="ruby">
169
Redmine::Plugin.register :redmine_polls do
170
  [...]
171
  
172
  menu :application_menu, :polls, { :controller => 'polls', :action => 'index' }, :caption => 'Polls'
173
end
174
</code></pre>
175
176 9 Haru Iida
文法は以下です。:
177 1 Haru Iida
178
  menu(menu_name, item_name, url, options={})
179
180 9 Haru Iida
拡張できるメニューは4種類です。:
181 1 Haru Iida
182 9 Haru Iida
* @:top_menu@ - 最上部の左側のメニュー。
183
* @:account_menu@ - 最上部の右側のメニュー。ログイン/ログアウトがある。
184
* @:application_menu@ - プロジェクトの外でのメインメニュー。
185
* @:project_menu@ - プロジェクト内でのメインメニュー。
186 1 Haru Iida
187 9 Haru Iida
以下のオプションが使えます。:
188 1 Haru Iida
189 9 Haru Iida
* @:param@ - プロジェクトIDを渡すのに用いられる変数のキー。 (デフォルトは @:id@)
190
* @:if@ - メニュー項目のレンダリング前に呼ばれるProc。メニュー項目はこのProcの戻りがtrueの場合にのみ表示される。
191
* @:caption@ - メニューのキャプション。以下が使えます。:
192 1 Haru Iida
193 9 Haru Iida
  * ローカライズ文字列用シンボル
194
  * 文字列
195
  * projectを引数としたProc
196 1 Haru Iida
197 9 Haru Iida
* @:before@, @:after@ - メニューを挿入する場所の指定 (例 @:after => :activity@ 訳注:「活動」ページの後ろに挿入される)
198
* @:last@ - trueに設定するとメニューの最後に追加される。 (例 @:last => true@)
199
* @:html_options@ - html オプションのHash。メニュー表示時の @link_to@ に渡される。訳注: @link_to@はRailsのAPI
200 1 Haru Iida
201 9 Haru Iida
今回の例ではメニュー項目をアプリケーションメニューに追加します。アプリケーションメニューはデフォルトでは空です。
202
Redmineを再起動して http://localhost:3000 にアクセスしてみましょう。:
203 1 Haru Iida
204 9 Haru Iida
!application_menu.png!
205 1 Haru Iida
206 9 Haru Iida
ようこそ画面のPollsタブをクリックして投票画面に行けるはずです。
207 1 Haru Iida
208 10 Haru Iida
h3. プロジェクトメニューを拡張する。
209 1 Haru Iida
210 10 Haru Iida
さあ、今度はpollsをプロジェクト用プラグインとした場合の例です。(今回のpollモデルはそう設計されてませんが)。Pollsタブをプロジェクトメニューに追加しましょう。
211
@init.rb@ を開いて先ほど追加した行を以下の2行に書き換えてください。:
212 1 Haru Iida
213
<pre><code class="ruby">
214
Redmine::Plugin.register :redmine_polls do
215
  [...]
216
217
  permission :polls, {:polls => [:index, :vote]}, :public => true
218
  menu :project_menu, :polls, { :controller => 'polls', :action => 'index' }, :caption => 'Polls', :after => :activity, :param => :project_id
219
end
220
</code></pre>
221
222 10 Haru Iida
2行目がプロジェクトメニューにPollsタブを追加する定義です。活動タブのすぐ後ろに追加します。
223
最初の行は @PollsController@ の2つのアクションをpulicにするための設定です。詳細については後ほど説明します。
224 1 Haru Iida
225 10 Haru Iida
Redmineを再起動し、プロジェクトを表示します。:
226 1 Haru Iida
227 11 Haru Iida
!project_menu.png!
228 1 Haru Iida
229 12 Haru Iida
Pollsタブをクリックしてください。プロジェクトメニューが消えてしまうことに気付きましたか?
230
プロジェクトメニューを表示しておくためにはコントローラのインスタンス変数 @@project@ を設定してあげる必要があります。
231 1 Haru Iida
232 12 Haru Iida
PollsController を以下のように編集します。:
233 1 Haru Iida
234
<pre><code class="ruby">
235
def index
236
  @project = Project.find(params[:project_id])
237
  @polls = Poll.find(:all) # @project.polls
238
end
239
</code></pre>
240
241 12 Haru Iida
プロジェクトIDはparamの中の @:project_id@ に格納されています。なぜなら先ほどのメニューの定義で @:param => :project_id@ と設定したからです。
242 1 Haru Iida
243 12 Haru Iida
さあ、これでPollsタブをクリックしてもプロジェクトメニューが消えなくなりました。:
244 1 Haru Iida
245 13 Haru Iida
!project_menu_pools.png!
246 1 Haru Iida
247 13 Haru Iida
h2. パーミッションを定義する。
248 1 Haru Iida
249 14 Haru Iida
この状態ではすべての人が投票を行うことができます。ではパーミッションの定義をしてみましょう。
250
ここでは2種類のプロジェクトベースのパーミッションを定義します。ひとつはpollsの表示に関するもの、もう一つは投票に関するものです。これを行うと、パーミッションはpublicでは無くなります。(@:public => true@ オプションは削除します).
251 1 Haru Iida
252 14 Haru Iida
@vendor/plugins/redmine_polls/init.rb@ を編集して先ほどのパーミッション定義を以下の2行に置き換えます。:
253 1 Haru Iida
254
<pre><code class="ruby">
255
256
  permission :view_polls, :polls => :index
257
  permission :vote_polls, :polls => :vote
258
</code></pre>
259
260
261 14 Haru Iida
Redmineを再起動して次のURLにアクセスしてみましょう。 http://localhost:3000/roles/report:
262 1 Haru Iida
263 15 Haru Iida
!permissions1.png!
264 1 Haru Iida
265 14 Haru Iida
これで既存のロールに対してパーミッションを設定できるようになりました。
266 1 Haru Iida
267 14 Haru Iida
もちろん、パーミッションに応じてユーザのアクセス制御を行うためにはPollsControllerにコードを追加する必要があります。
268 1 Haru Iida
269 14 Haru Iida
今回の場合は @:authorize@ フィルターを追加すること、およびこのフィルターが呼ばれる前に必ず @project に値がセットされるようにするだけです。
270
271
@#index@ アクションでは以下のようにします。:
272 1 Haru Iida
273
<pre><code class="ruby">
274
class PollsController < ApplicationController
275
  unloadable
276
  
277
  before_filter :find_project, :authorize, :only => :index
278
279
  [...]
280
  
281
  def index
282
    @polls = Poll.find(:all) # @project.polls
283
  end
284
285
  [...]
286
  
287
  private
288
  
289
  def find_project
290
    # @project variable must be set before calling the authorize filter
291
    @project = Project.find(params[:project_id])
292
  end
293
end
294
</code></pre>
295
296 16 Haru Iida
@#vote@ アクションが動く前に現在のプロジェクトを取得します。これを行うと、投票は管理者もしくはこのプロジェクトの許可されたロールのユーザ以外行えなくなります。
297 1 Haru Iida
298
299 16 Haru Iida
h2. プロジェクトモジュールを作る。
300 1 Haru Iida
301 16 Haru Iida
今現在、pollの機能はすべてのプロジェクトに追加されています。しかし、pollsを限られたプロジェクトのみに使わせたい場合もあるでしょう。
302
ここでは 'Polls' プロジェクトモジュールを作成します. これはパーミッション定義を @#project_module@ 定義で囲むことによって実現します。
303 1 Haru Iida
304 16 Haru Iida
@init.rb@ を編集してパーミッションの定義を変更します。:
305
306 1 Haru Iida
<pre><code class="ruby">
307
  project_module :polls do
308
    permission :view_polls, :polls => :index
309
    permission :vote_polls, :polls => :vote
310
  end
311
</code></pre>
312
313 16 Haru Iida
Redmineを再起動し、適当なプロジェクトの設定メニューを開きます。そしてモジュールタブをクリックします。するとモジュールリストの最後にPolls moduleがあることが確認できます。 (デフォルトではチェックはついていません):
314 1 Haru Iida
315 16 Haru Iida
!modules.png!
316 1 Haru Iida
317
You can now enable/disable polls at project level.
318
319
h2. Improving the plugin views
320
321
h3. Adding stylesheets
322
323
Let's start by adding a stylesheet to our plugin views.
324
Create a file named @voting.css@ in the @vendor/plugins/redmine_polls/assets/stylesheets@ directory:
325
326
<pre>
327
a.vote { font-size: 120%; }
328
a.vote.yes { color: green; }
329
a.vote.no  { color: red; }
330
</pre>
331
332
When starting the application, plugin assets are automatically copied to @public/plugin_assets/redmine_polls/@ by Rails Engines to make them available through your web server. So any change to your plugin stylesheets or javascripts needs an application restart.
333
334
Then, append the following lines at the end of @vendor/plugins/redmine_polls/app/views/polls/index.html.erb@ so that your stylesheet get included in the page header by Redmine:
335
336
<pre>
337
<% content_for :header_tags do %>
338
    <%= stylesheet_link_tag 'voting', :plugin => 'redmine_polls' %>
339
<% end %>
340
</pre>
341
342
Note that the @:plugin => 'redmine_polls'@ option is required when calling the @stylesheet_link_tag@ helper.
343
344
Javascripts can be included in plugin views using the @javascript_include_tag@ helper in the same way.
345
346
h3. Setting page title
347
348
You can set the HTML title from inside your views by using the @html_title@ helper.
349
Example:
350
351
  <% html_title "Polls" -%>