Cannot use Setting when initializing a plugin

Added by Jean-Baptiste Barth over 11 years ago

When my plugin is initialized, I'd like to run some actions depending on a specific Setting. But as soon as I call a class method on Setting, app/models/setting.rb gets autoloaded. The Redmine::Plugin.all block at the beginning of the file is called to adjust available settings for plugins. And here's the problem: engines plugins loaded after that never get their settings initialized.

How would you solve that ? Do you think we should change the actual behavior ? If so I'll create an issue and work on a patch, but it should be heavily tested since it could have deep impacts on existing plugins.

Replies (6)

RE: Cannot use Setting when initializing a plugin - Added by Jean-Baptiste Barth over 11 years ago

Solved this by wrapping my actions in a config.to_prepare block, but I'd really like to understand your thoughts on this problem and how we could make plugin development easier.

RE: Cannot use Setting when initializing a plugin - Added by Eric Davis over 11 years ago

Can you post some code showing what your plugin is doing?

Eric Davis

RE: Cannot use Setting when initializing a plugin - Added by Jean-Baptiste Barth over 11 years ago

This plugin replaces Redmine's Groups in favor of a nested structure. So I want to hide groups item in admin_menu depending on a Setting (administrator could choose to use both structures...). And I don't want to try to hide this item in each request (seems inefficient and useless), I just want to do this when initializing and when checking/unchecking the appropriate checkbox.

Basically the following init.rb doesn't work (other plugins' settings never loaded) :

require 'redmine'

Redmine::Plugin.register :redmine_blah do
  settings :default => { 'hide_groups_menu' => "0" }
  delete_menu_item(:admin_menu, :groups) if Setting["plugin_redmine_blah"]["hide_groups_menu"]
end

And the following one works :

require 'redmine'

Redmine::Plugin.register :redmine_blah do
  settings :default => { 'hide_groups_menu' => "0" }
end

config.to_prepare do
  Redmine::MenuManager.map(:admin_menu).delete(:groups) if Setting["plugin_redmine_blah"]["hide_groups_menu"]
end

If you want to enlight the problem and your plugin initializations don't depend on a setting, you can just add the following line in app/models/setting.rb after line 78:

    puts "Loading settings for plugin #{plugin.id}" 

And you'll see your plugin settings won't all be loaded in the first case.

RE: Cannot use Setting when initializing a plugin - Added by Eric Davis over 11 years ago

You will need to show/hide the menu item in each request. The config.to_prepare is basically doing just that.

A better option would be to:

  1. Delete the core's group menu
  2. Re-add it but add a check onto it like: :if => Proc.new { Setting["plugin_redmine_blah"]["hide_groups_menu"] }

Then the menu item will always be there but it will be hidden if that Proc returns false.

Eric Davis

RE: Cannot use Setting when initializing a plugin - Added by Jean-Baptiste Barth over 11 years ago

Eric Davis wrote:

You will need to show/hide the menu item in each request. The config.to_prepare is basically doing just that.

It's true in development mode. I thought in production mode it was executing the block just for the first request. But it might not be the good debate, maybe these things have no impact on performance.

Then the menu item will always be there but it will be hidden if that Proc returns false.

Thanks for the tip, I'll try that.

Anyway, my own problem with this menu item is not very interesting. Above all I wanted to point out that the limited usage of Setting is not intuitive, and should be improved if we want to make plugin development easier.

RE: Cannot use Setting when initializing a plugin - Added by Eric Davis over 11 years ago

Jean-Baptiste Barth wrote:

It's true in development mode. I thought in production mode it was executing the block just for the first request. But it might not be the good debate, maybe these things have no impact on performance.

In production it's executed in the first request for each process. In a spawning server like passenger, that will be when a new child process is started.

Anyway, my own problem with this menu item is not very interesting. Above all I wanted to point out that the limited usage of Setting is not intuitive, and should be improved if we want to make plugin development easier.

Setting is supposed to be for user configuration that can be changed while the application is running. Enabling or disabling Groups would fall under that but deleting a menu item wouldn't.

Eric Davis

(1-6/6)