プラグイン チュートリアル » History » Version 18
Haru Iida, 05/31/2009 03:26 PM
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 | 18 | Haru Iida | もしRedmineをプロダクションモードで動かしていない場合、pollの結果はリクエスト毎にリセットされます。これは今回の例ではpollモデルをclass変数に格納しているためです。 |
159 | 1 | Haru Iida | |
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 | 17 | Haru Iida | これでプロジェクト毎にPollsの有効・無効を選択できるようになりました。 |
318 | 1 | Haru Iida | |
319 | 17 | Haru Iida | h2. プラグインの表示を拡張する。 |
320 | 1 | Haru Iida | |
321 | 17 | Haru Iida | h3. スタイルシートを追加する。 |
322 | 1 | Haru Iida | |
323 | 17 | Haru Iida | それではプラグインのviewにスタイルシートを追加してみましょう。 |
324 | @voting.css@ というファイルを @vendor/plugins/redmine_polls/assets/stylesheets@ に作成してください。: |
||
325 | 1 | Haru Iida | |
326 | <pre> |
||
327 | a.vote { font-size: 120%; } |
||
328 | a.vote.yes { color: green; } |
||
329 | a.vote.no { color: red; } |
||
330 | </pre> |
||
331 | |||
332 | 17 | Haru Iida | Redmineを再起動すると、assetsの下はRails Enginesによって自動的に @public/plugin_assets/redmine_polls/@ にコピーされます。これによってWebブラウザからこれらのファイルにアクセスできるようになります。なのでassetsの下のスタイルシートやJavascriptに変更を加えた場合には必ずRedmineの再起動が必要になります。 |
333 | 1 | Haru Iida | |
334 | 17 | Haru Iida | @vendor/plugins/redmine_polls/app/views/polls/index.html.erb@ に以下の行を加えてください。するとスタイルシートがRedmineのヘッダーからインクルードされます。: |
335 | 1 | Haru Iida | |
336 | <pre> |
||
337 | <% content_for :header_tags do %> |
||
338 | <%= stylesheet_link_tag 'voting', :plugin => 'redmine_polls' %> |
||
339 | <% end %> |
||
340 | </pre> |
||
341 | |||
342 | 17 | Haru Iida | @:plugin => 'redmine_polls'@ オプションを @stylesheet_link_tag@ ヘルパーに渡します。 |
343 | 1 | Haru Iida | |
344 | 17 | Haru Iida | Javascript をプラグインのビューからインクルードするためには@javascript_include_tag@ ヘルパーを同様に使います。 |
345 | 1 | Haru Iida | |
346 | 17 | Haru Iida | h3. ページタイトルを設定する。 |
347 | 1 | Haru Iida | |
348 | 17 | Haru Iida | プラグインのviewにHTMLのタイトルを設定するには @html_title@ ヘルパーを使います。 |
349 | 例: |
||
350 | 1 | Haru Iida | |
351 | <% html_title "Polls" -%> |