プラグイン チュートリアル » History » Version 10
Haru Iida, 05/28/2009 04:53 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 | 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 | p=. !project_menu.png! |
||
| 228 | |||
| 229 | If you click the Polls tab, you should notice that the project menu is no longer displayed. |
||
| 230 | To make the project menu visible, you have to initialize the controller's instance variable @@project@. |
||
| 231 | |||
| 232 | Edit your PollsController to do so: |
||
| 233 | |||
| 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 | The project id is available in the @:project_id@ param because of the @:param => :project_id@ option in the menu item declaration above. |
||
| 242 | |||
| 243 | Now, you should see the project menu when viewing the polls: |
||
| 244 | |||
| 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" -%> |