redmine自定义插件开发

Posted on Posted in 经验分享

1. 创建一个插件,借助于redmine自己提供的插件扩展功能
语法:ruby script/generate redmine_plugin <plugin_name>
所以我们输入以下一个实例作演示(投票插件Polls)
redmine > ruby script/generate redmine_plugin Polls

控制台信息如下:

 create vendor/plugins/redmine_polls/app/controllers
 create vendor/plugins/redmine_polls/app/helpers
 create vendor/plugins/redmine_polls/app/models
 create vendor/plugins/redmine_polls/app/views
 create vendor/plugins/redmine_polls/db/migrate
 create vendor/plugins/redmine_polls/lib/tasks
 create vendor/plugins/redmine_polls/assets/images
 create vendor/plugins/redmine_polls/assets/javascripts
 create vendor/plugins/redmine_polls/assets/stylesheets
 create vendor/plugins/redmine_polls/lang
 create vendor/plugins/redmine_polls/README
 create vendor/plugins/redmine_polls/init.rb
 create vendor/plugins/redmine_polls/lang/en.yml

2.编辑插件信息:

redmine> vi vendor/plugins/redmine_polls/init.rb

init.rb文件信息如下:

1 require 'redmine'
2 
3 Redmine::Plugin.register :redmine_polls do
4 name 'plugin name'
5 author 'your name'
6 description 'A plugin for managing polls'
7 version '0.0.1'
8 end 3.重启应用服务,在浏览器输入 http://localhost:3000/admin/plugins.

登录之后你将在插件列表看见你刚创建的一个新插件,视图如下

4.创建一个模组

redmine> ruby script/generate redmine_plugin_model Polls poll question:string 
yes:integer no:integer

注意:你需要将生成的带时间戳的迁移文件重命名为数字号码前缀的文件名。因为redmine目前的插件引擎不支持时间戳文件。例如你可将时间戳命名的文件改为”001_xxx.rb”,”002_xxx.rb”等等。

同时给Poll类增加一个业务功能
vi vendor/plugins/redmine_polls/app/models/poll.rb
class Poll < ActiveRecord::Base
def vote(answer)
increment(answer==’yes’ ? :yes : :no)
end
end

5.数据迁移

redmine> rake db:migrate_plugins RAILS_ENV='production' 顺便向数据库中插入几行数据,以供演示用
mysql>insert into polls(question) values("Can you see this poll?"); mysql>insert into polls(question) values("Can you see this other poll?");
6.为插件添加控制器

语法:

ruby script/generate redmine_plugin_controller <plugin_name> <controller_name> 
[<actions>]

因此我们这么作:

redmine> ruby script/generate redmine_plugin_controller Polls polls index vote
控制台信息:
 exists app/controllers/
 exists app/helpers/
 create app/views/polls
 create test/functional/
 create app/controllers/polls_controller.rb
 create test/functional/polls_controller_test.rb
 create app/helpers/polls_helper.rb
 create app/views/polls/index.html.erb
 create app/views/polls/vote.html.erb

编辑vendor/plugins/redmine_polls/app/controllers/polls_controller.rb文件

 1 class PollsController < ApplicationController
 2 unloadable
 3 
 4 def index
 5 @polls = Poll.find(:all)
 6 end
 7 
 8 def vote
 9 poll = Poll.find(params[:id]) 10 poll.vote(params[:answer])
11 if poll.save
12 flash[:notice] = 'Vote saved.'
13 redirect_to :action => 'index'
14 end
15 end
16 end

 

接下来编辑vendor/plugins/redmine_polls/app/views/polls/index.html.erb

<h2>Polls</h2>
<% @polls.each do |poll| %>
 <p>
 <%= poll[:question] %>?
 <%= link_to 'Yes', {:action => 'vote', :id => poll[:id], :answer => 'yes'}
, :method => :post %> (<%= poll[:yes] %>) /
 <%= link_to 'No', {:action => 'vote', :id => poll[:id], :answer => 'no'}
, :method => :post %> (<%= poll[:no] %>)
 </p>
<% end %>

现在你可以将 vendor/plugins/redmine_polls/app/views/polls/vote.html.erb 删除了,因为本演示不用跳转的该页面

重启你的服务,在浏览器输入http://localhost:3000/polls.你将看到

7.把插件扩展为一个菜单,因为不这样作的话,你需要记住刚访问的url,这显然很麻烦。

首先我们做一个应用程序类型的菜单
编辑
vendor/plugins/redmine_polls/init.rb ,在文件尾部加入以下内容

1 Redmine::Plugin.register :redmine_polls do
2 [...]
3 
4 menu :application_menu, :polls, { :controller => 'polls', :action => 
'index' }, :caption => 'Polls'
5 end

语法

menu(menu_name, item_name, url, options={})

一共有四种菜单类型

  • :top_menu – the top left menu
  • :account_menu – the top right menu with sign in/sign out links
  • :application_menu – the main menu displayed when the user is not inside a project
  • :project_menu – the main menu displayed when the user is inside a project

Available options are:

  • :param- the parameter key that is used for the project id (default is :id)
  • :if – a Proc that is called before rendering the item, the item is displayed only if it returns true
  • :caption – the menu caption that can be:
    • a localized string Symbol
    • a String
    • a Proc that can take the project as argument
  • :before, :after – specify where the menu item should be inserted (eg. :after => :activity)
  • :last- if set to true, the item will stay at the end of the menu (eg. :last => true)
  • :html_options – a hash of html options that are passed to link_to when rendering the menu item

重启服务器,在浏览器输入:http://localhost:3000:

创建规属于项目的菜单

编辑 init.rb文件

1 Redmine::Plugin.register :redmine_polls do
2 [...]
3 
4 permission :polls, {:polls => [:index, :vote]}, :public => true
5 menu :project_menu, :polls, { :controller => 'polls', :action => 'index' }
, :caption => 'Polls', :after => :activity, :param => :project_id
6 end 重启服务器,任意进入一个项目,你将看到项目多了一个菜单选项 

但如果你点击Polls,却发现项目菜单不见了。

下面我们做得就是让项目菜单显示,这样你就不得不创建一个实例变量@project

编辑PollsController

def index
 find_project
 @polls = Poll.find(:all) # @project.polls
end
private
def find_project
 @project = Project.find(params[:project_id]) if params[:project_id]
end

参数:project_id正是init.rb文件中 :param => :project_id

至此一个项目菜单作好了

如果想进一步改善项目菜单你可以继续往下看

8.给项目菜单添加权限

编辑vendor/plugins/redmine_polls/init.rb

将原来的

permission :polls, {:polls => [:index, :vote]}, :public => true用下面两行代替
1 
2 permission :view_polls, :polls => :index
3 permission :vote_polls, :polls => :vote

重启应用服务,输入http://localhost:3000/roles/report:

你可以给不同角色分配权限
别忘了修改PollsController

1 class PollsController < ApplicationController
 2 unloadable
 3 
 4 before_filter :find_project, :authorize, :only => :index
 5 
 6 [...]
 7 
 8 def index
 9 @polls = Poll.find(:all) # @project.polls 10 end
11 
12 [...]
13 
14 private
15 
16 def find_project
17 # @project variable must be set before calling the authorize filter
18 @project = Project.find(params[:project_id])
19 end 20 end