プロジェクト

全般

プロフィール

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

Haru Iida, 2009/05/28 17:01

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
p=. !project_menu_pools.png!
246
247
h2. Adding new permissions
248
249
For now, anyone can vote for polls. Let's make it more configurable by changing the permission declaration.
250
We're going to declare 2 project based permissions, one for viewing the polls and an other one for voting. These permissions are no longer public (@:public => true@ option is removed).
251
252
Edit @vendor/plugins/redmine_polls/init.rb@ to replace the previous permission declaration with these 2 lines:
253
254
<pre><code class="ruby">
255
256
  permission :view_polls, :polls => :index
257
  permission :vote_polls, :polls => :vote
258
</code></pre>
259
260
261
Restart the application and go to http://localhost:3000/roles/report:
262
263
p=. !permissions1.png!
264
265
You're now able to give these permissions to your existing roles.
266
267
Of course, some code needs to be added to the PollsController so that actions are actually protected according to the permissions of the current user.
268
For this, we just need to append the @:authorize@ filter and make sure that the @project instance variable is properly set before calling this filter.
269
270
Here is how it would look like for the @#index@ action:
271
272
<pre><code class="ruby">
273
class PollsController < ApplicationController
274
  unloadable
275
  
276
  before_filter :find_project, :authorize, :only => :index
277
278
  [...]
279
  
280
  def index
281
    @polls = Poll.find(:all) # @project.polls
282
  end
283
284
  [...]
285
  
286
  private
287
  
288
  def find_project
289
    # @project variable must be set before calling the authorize filter
290
    @project = Project.find(params[:project_id])
291
  end
292
end
293
</code></pre>
294
295
Retrieving the current project before the @#vote@ action could be done using a similar way.
296
After this, viewing and voting polls will be only available to admin users or users that have the appropriate role on the project.
297
298
h2. Creating a project module
299
300
For now, the poll functionality is added to all your projects. But you way want to enable polls for some projects only.
301
So, let's create a 'Polls' project module. This is done by wrapping the permissions declaration inside a call to @#project_module@.
302
303
Edit @init.rb@ and change the permissions declaration:
304
305
<pre><code class="ruby">
306
  project_module :polls do
307
    permission :view_polls, :polls => :index
308
    permission :vote_polls, :polls => :vote
309
  end
310
</code></pre>
311
312
Restart the application and go to one of your project settings.
313
Click on the Modules tab. You should see the Polls module at the end of the modules list (disabled by default):
314
315
p=. !modules.png!
316
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" -%>