📜 ⬆️ ⬇️

Creating plugins for Redmine

The process of creating plugins for Redmine is very poorly documented. The task of this article is to partly fill this gap, telling about the successful experience of creating a small but useful plug-in. Important note. Redmine is written in Ruby on Rails, you need to be ready for this if you are going to make your plugin :)

Initial task


Our company uses Redmine as the main task tracker. I will not consider his pros and cons, I’ll dwell only on the number of letters he sends for any change in tasks. In this “noise”, new tasks or important comments are sometimes lost.

Developers, of course, have provided a number of settings for this, but they are rather scarce. I want to be able to configure notifications for specific changes.


')
Notifications to change the status of the task to “Task closed” were especially straining. To me, as a developer, they are not important. If there are improvements on the task, then the task is assigned the status “New” again, some comment is written, and I receive a notification and proceed to its solution.

You can set up a filter in the mail for such letters (you say), but it was much more interesting to write your own plugin that will allow all the participants of the process (performers, authors, observers) to regulate these notifications.

So, the task: to create a plugin that adds the setting "Do not notify me when the task is closed" to the user account.

Solution Description


I will omit the creation of a template for the plugin; this is described in detail in the corresponding section on redmine.org .

Add a tick, by analogy with "Do not notify about changes that I made myself." To do this, simply copy the template \ app \ views \ users \ _mail_notifications.html.erb into your plugin and add the required html code.

This is not very correct, but the standard hook on the user form : view_users_form , displays the checkbox in the wrong place. Redmine with each new version supports more and more hooks , but they will always be insufficient and this case is no exception.

Further "we patch" 3 methods, this creation and editing of the user by the administrator and editing on the account page. There are no hooks for these methods either, so the “hooks out of the box” came to the rescue: alias_method and alias_method_chain . The logic of their work is clear from the title, link methods and link methods in a chain.

The account my_controller , the account method, is responsible for the account page. We patch it by creating a file in the subdirectory of the plugin \ lib \ patches \ my_controller_patch.rb

module Patches module MyControllerPatch def self.included(base) #    base.extend(ClassMethods) #     base.send(:include, InstanceMethods) base.class_eval do unloadable #     alias_method_chain :account, :ext end end module ClassMethods end module InstanceMethods #     ext def account_with_ext if request.post? #           User.current.pref[:no_self_notified_closed] = (params[:no_self_notified_closed] == '1') end #    account account_without_ext end end end end 

Creating and editing admin, likewise.

Next, you need to read the set value when forming the list of users for the notification mailing; the issue model, the recipients method and the watcher_recipients method are responsible for this, copy them to \ lib \ patches \ issue_patch.rb and change them for yourself.

 module Patches module IssuePatch def self.included(base) … base.class_eval do unloadable #     alias_method :recipients, :recipients_ext alias_method :watcher_recipients, :watcher_recipients_ext end end … module InstanceMethods #     def recipients_ext #       @status = IssueStatus.find_by_id(self.status_id) notified = project.notified_users #         ( allow_notify_closed) notified << author if author && author.active? && author.notify_about?(self) && allow_notify_closed?(author) if assigned_to if assigned_to.is_a?(Group) notified += assigned_to.users.select { |u| u.active? && u.notify_about?(self) && allow_notify_closed?(u) } else notified << assigned_to if assigned_to.active? && assigned_to.notify_about?(self) && allow_notify_closed?(assigned_to) end end notified.uniq! notified.reject! { |user| !visible?(user) } notified.collect(&:mail) end #  def watcher_recipients_ext notified = watcher_users.active notified.reject! { |user| user.mail_notification == 'none' || allow_notify_closed?(user) === false } if respond_to?(:visible?) notified.reject! { |user| !visible?(user) } end notified.collect(&:mail).compact end private #   ,          def allow_notify_closed?(user) (user.pref[:no_self_notified_closed] && @status.is_closed?) ? false : true end end end end 

And the most important thing is to connect our patches. At the root of the plugin file init.rb , append :

 # dispatcher       require 'dispatcher' Dispatcher.to_prepare do MyController.send(:include, Patches::MyControllerPatch) UsersController.send(:include, Patches::UsersControllerPatch) Issue.send(:include, Patches::IssuePatch) end 

Install the plugin in the / vendor / plugins / folder and restart redmine. Everything, now it is possible to manage notifications and not to receive unnecessary letters. Thus, you can change the behavior of any method in Redmine and write your own plug-ins that automate and facilitate the work.

Link to sources https://github.com/parshukovvv/redmine_notice

Source: https://habr.com/ru/post/142584/


All Articles