Implement Redmine Project Menu Item Customize Setting with Plugin
主要是想試試看Redmine這類有時代背景的產品
是否因為Rails與本身設計的彈性
讓開發者易於修改、以及使用者客製化的維度等等
找了不少關鍵字,沒看到我想要的,於是就記錄一下~
是否因為Rails與本身設計的彈性
讓開發者易於修改、以及使用者客製化的維度等等
找了不少關鍵字,沒看到我想要的,於是就記錄一下~
- 實作目標:讓各個專案管理者自行決定某個專案標籤是否顯示,而非關閉此功能
- 實作範圍:Plugin。不含既有非模組化的Menu item,如:概觀(Overview)、活動(Activity)
- Redmine原始碼參考 Mirror site
- 精要結果:修改hearts模組的init.rb即可
修改後的程式碼如下menu :project_menu, :hearts, { :controller => :hearts, :action => :index }, :param => :project_id, :caption => :hearts_link_label, # 如果hearts模組在project是enable的,才產生此menu item :if => proc { |project| project.module_enabled? :hearts } # 在Project新增此模組的設定檔,也有權限限制,只有專案管理員可設定。 project_module :hearts do permission :hearts, { hearts: [:index] }, require: :member end
只需修改這樣,就可以達到上述客製化的設定,相當精美而且直覺 - 細部說明:
由於所有Redmine模組的init.rb都是透過Redmine::Plugin實作
與此次案例有關的程式碼為menu
裡頭也引用到Redmine::MenuManager.map,會將Menu Item的資訊存入
很明顯的,在這個步驟並沒有觸發:if
判斷的Proc程式碼區段
那麼是在哪裡被啟用呢?
在 layouts/base.html.rb,如果目前是在Project頁面
那麼就會呼叫 MenuManager的render_main_menu方法
在往裡頭追縱會看到menu_manager.rb MenuItem::allow? 方法裏頭這段程式碼if condition && !condition.call(project) # Condition that doesn't pass return false end
這個call,就是proc被啟動的時間點,同時還傳了當下的project物件
所以我們就可以拿到這個物件相關的資訊,用以判斷模組在該project是否啟用
這段程式碼就在這裡生效了:if => proc { |project| project.module_enabled? :hearts }
當proc最後回傳true的時候就顯示,反之則跳過 - Demo
- 到該專案點選設定
- 取消Hearts並儲存,此時『讚』標籤已消失
- 議題的讚功能都還在,正常運作
- 不會影響到其他專案,證明是依專案設定而非全域設定
- 到該專案點選設定
未來如果要更彈性設定模組哪些功能要開、哪些要關,可以參考現有Plugin專案設定作法
由於很多服務都是關掉就整個功能沒了,為了這個再開個標籤只有一個設定也有點多餘
我們是嘗試僅關閉部分顯示邏輯,也看到Rails與Redmine的彈性
由於很多服務都是關掉就整個功能沒了,為了這個再開個標籤只有一個設定也有點多餘
我們是嘗試僅關閉部分顯示邏輯,也看到Rails與Redmine的彈性
留言
張貼留言