Plugin Tutorial » History » Version 3

Jean-Philippe Lang, 2008-08-10 17:36

1 3 Jean-Philippe Lang
{{>toc}}
2 3 Jean-Philippe Lang
3 1 Jean-Philippe Lang
h1. Plugin Tutorial
4 1 Jean-Philippe Lang
5 1 Jean-Philippe Lang
h2. Creating a new Plugin
6 1 Jean-Philippe Lang
7 1 Jean-Philippe Lang
Open up a command prompt and "cd" to your redmine directory, then execute the following command:
8 1 Jean-Philippe Lang
9 3 Jean-Philippe Lang
  % ruby script/generate redmine_plugin Pools
10 1 Jean-Philippe Lang
11 1 Jean-Philippe Lang
The plugin structure is created in @vendor/plugins/redmine_pools@:
12 1 Jean-Philippe Lang
13 1 Jean-Philippe Lang
<pre>
14 1 Jean-Philippe Lang
      create  vendor/plugins/redmine_pools/app/controllers
15 1 Jean-Philippe Lang
      create  vendor/plugins/redmine_pools/app/helpers
16 1 Jean-Philippe Lang
      create  vendor/plugins/redmine_pools/app/models
17 1 Jean-Philippe Lang
      create  vendor/plugins/redmine_pools/app/views
18 1 Jean-Philippe Lang
      create  vendor/plugins/redmine_pools/db/migrate
19 1 Jean-Philippe Lang
      create  vendor/plugins/redmine_pools/lib/tasks
20 1 Jean-Philippe Lang
      create  vendor/plugins/redmine_pools/assets/images
21 1 Jean-Philippe Lang
      create  vendor/plugins/redmine_pools/assets/javascripts
22 1 Jean-Philippe Lang
      create  vendor/plugins/redmine_pools/assets/stylesheets
23 1 Jean-Philippe Lang
      create  vendor/plugins/redmine_pools/lang
24 1 Jean-Philippe Lang
      create  vendor/plugins/redmine_pools/README
25 1 Jean-Philippe Lang
      create  vendor/plugins/redmine_pools/init.rb
26 1 Jean-Philippe Lang
      create  vendor/plugins/redmine_pools/lang/en.yml
27 1 Jean-Philippe Lang
</pre>
28 1 Jean-Philippe Lang
29 2 Jean-Philippe Lang
Edit @vendor/plugins/redmine_pools/init.rb@ too adjust plugin information (name, author, description and version):
30 1 Jean-Philippe Lang
31 1 Jean-Philippe Lang
<pre><code class="ruby">
32 1 Jean-Philippe Lang
require 'redmine'
33 1 Jean-Philippe Lang
34 1 Jean-Philippe Lang
Redmine::Plugin.register :redmine_pools do
35 1 Jean-Philippe Lang
  name 'Pools plugin'
36 1 Jean-Philippe Lang
  author 'John Smith'
37 1 Jean-Philippe Lang
  description 'A plugin for managing pools'
38 1 Jean-Philippe Lang
  version '0.0.1'
39 1 Jean-Philippe Lang
end
40 1 Jean-Philippe Lang
</code></pre>
41 1 Jean-Philippe Lang
42 2 Jean-Philippe Lang
Then restart the application and point your browser to http://localhost:3000/admin/info.
43 1 Jean-Philippe Lang
After logging in, you should see your new plugin in the plugins list:
44 2 Jean-Philippe Lang
45 2 Jean-Philippe Lang
!plugins_list1.png!
46 2 Jean-Philippe Lang
47 1 Jean-Philippe Lang
h2. Generating a controller
48 1 Jean-Philippe Lang
49 3 Jean-Philippe Lang
For now, the plugin doesn't do anything. So let's create a controller for our plugin.
50 3 Jean-Philippe Lang
Go back to the command prompt and run:
51 3 Jean-Philippe Lang
52 3 Jean-Philippe Lang
<pre>
53 3 Jean-Philippe Lang
% ruby script/generate redmine_plugin_controller Pools pools index vote
54 3 Jean-Philippe Lang
      exists  app/controllers/
55 3 Jean-Philippe Lang
      exists  app/helpers/
56 3 Jean-Philippe Lang
      create  app/views/pools
57 3 Jean-Philippe Lang
      create  test/functional/
58 3 Jean-Philippe Lang
      create  app/controllers/pools_controller.rb
59 3 Jean-Philippe Lang
      create  test/functional/pools_controller_test.rb
60 3 Jean-Philippe Lang
      create  app/helpers/pools_helper.rb
61 3 Jean-Philippe Lang
      create  app/views/pools/index.html.erb
62 3 Jean-Philippe Lang
      create  app/views/pools/vote.html.erb
63 3 Jean-Philippe Lang
</pre>
64 3 Jean-Philippe Lang
65 3 Jean-Philippe Lang
A controller @PoolsController@ with 2 actions (@#index@ and @#vote@) is created.
66 3 Jean-Philippe Lang
67 3 Jean-Philippe Lang
Edit @app/controllers/pools_controller.rb@ in @redmine_pools@ directory to implement these 2 actions:
68 3 Jean-Philippe Lang
69 3 Jean-Philippe Lang
<pre><code class="ruby">
70 3 Jean-Philippe Lang
class PoolsController < ApplicationController
71 3 Jean-Philippe Lang
  unloadable
72 3 Jean-Philippe Lang
  
73 3 Jean-Philippe Lang
  @@pools = [ {:id => 1, :title => 'First pool', :question => 'This is the first pool question', :yes => 0, :no => 0},
74 3 Jean-Philippe Lang
              {:id => 2, :title => 'Second pool', :question => 'This is the second pool question', :yes => 0, :no => 0} ]
75 3 Jean-Philippe Lang
76 3 Jean-Philippe Lang
  def index
77 3 Jean-Philippe Lang
    @pools = @@pools
78 3 Jean-Philippe Lang
  end
79 3 Jean-Philippe Lang
80 3 Jean-Philippe Lang
  def vote
81 3 Jean-Philippe Lang
    pool = @@pools.find {|p| p[:id].to_s == params[:id]}
82 3 Jean-Philippe Lang
    # saves the vote
83 3 Jean-Philippe Lang
    pool[params[:answer].to_sym] += 1
84 3 Jean-Philippe Lang
    flash[:notice] = 'Vote saved.'
85 3 Jean-Philippe Lang
    redirect_to :action => 'index'
86 3 Jean-Philippe Lang
  end
87 3 Jean-Philippe Lang
end
88 3 Jean-Philippe Lang
</code></pre>
89 3 Jean-Philippe Lang
90 3 Jean-Philippe Lang
Then edit @app/views/pools/index.html.erb@ that will display existing pools:
91 3 Jean-Philippe Lang
92 3 Jean-Philippe Lang
93 3 Jean-Philippe Lang
<pre>
94 3 Jean-Philippe Lang
<h2>Pools</h2>
95 3 Jean-Philippe Lang
96 3 Jean-Philippe Lang
<% @pools.each do |pool| %>
97 3 Jean-Philippe Lang
  <p>
98 3 Jean-Philippe Lang
  <%= pool[:question] %>?
99 3 Jean-Philippe Lang
  <%= link_to 'Yes', {:action => 'vote', :id => pool[:id], :answer => 'yes'}, :method => :post %> (<%= pool[:yes] %>) /
100 3 Jean-Philippe Lang
  <%= link_to 'No', {:action => 'vote', :id => pool[:id], :answer => 'no'}, :method => :post %> (<%= pool[:no] %>)
101 3 Jean-Philippe Lang
  </p>
102 3 Jean-Philippe Lang
<% end %>
103 3 Jean-Philippe Lang
</pre>
104 3 Jean-Philippe Lang
105 3 Jean-Philippe Lang
You can remove @vote.html.erb@ since no rendering is done by the corresponding action.
106 3 Jean-Philippe Lang
107 3 Jean-Philippe Lang
Now, restart the application and point your browser to http://localhost:3000/pools.
108 3 Jean-Philippe Lang
You should see the 2 pools and you should be able to vote for them.