I have a requirement where new items should be added to the menu of an app when different plugins are installed. The key idea is to extend the frontend functionality with plugins, adding new items on the menu will allow to access actions from controllers defined on those plugins installed.
I couldn't find any documentation or guide that talks about that, and not sure if it's any recommendation on that area. Also I need to validate if this could be done with plugins and if there is any better alternative than plugins.
Also, I want to avoid at all costs is creating my own plugin infrastructure inside Grails.
The default generated grails-app/views/index.gsp
for a newly created Grails app actually does that.
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Installed Plugins <span class="caret"></span></a>
<ul class="dropdown-menu">
<g:each var="plugin" in="${applicationContext.getBean('pluginManager').allPlugins}">
<li class="dropdown-item"><a href="#">${plugin.name} - ${plugin.version}</a></li>
</g:each>
</ul>
</li>
I hope that helps.
EDIT: Adding Info Based On Comment Below
See the project at https://github.com/jeffbrown/pablopazosmenus.
Run the app...
./gradlew app:bootRun
On the main home page you will see a "Books" menu and a "Music" menu.
The app depends on 2 plugins, each of those plugins is providing dynamic menu info. The plugins are being pulled into the app at https://github.com/jeffbrown/pablopazosmenus/blob/345bcf17a12639df6b7c9e980c39f01102f1eb2c/app/build.gradle#L62-L63.
runtime project(':pluginone')
runtime project(':plugintwo')
pluginone
is providing the "Music" menu. plugintwo
is proving the "Books" menu. If you comment out either of those plugin dependencies and re-run the app, you will see the corresponding menu disappear in the app. This indicates that the app is dynamically building up the menu based on beans provided by the plugins. The simple tag library at https://github.com/jeffbrown/pablopazosmenus/blob/master/app/grails-app/taglib/pablopazosmenus/MenuTagLib.groovy is part of that.
package pablopazosmenus
import org.springframework.beans.factory.annotation.Autowired
class MenuTagLib {
static namespace = 'pablo'
@Autowired
List<MenuHelper> menuHelpers
def renderMenu = { attrs ->
out << render(template: '/dynamicMenu', model: [menuHelpers: menuHelpers])
}
}
The plugins are each providing 1 of the MenuHelper
beans that are being injected there but a plugin could provide any number of those. Each of the plugins is adding the beans in their doWithSpring
methods.
The code at https://github.com/jeffbrown/pablopazosmenus/blob/345bcf17a12639df6b7c9e980c39f01102f1eb2c/app/grails-app/views/index.gsp#L36 is invoking that tag lib.
<pablo:renderMenu/>
There are a lot of different ways to put all this together and how I would do it would depend on understanding the real requirements.
I hope that helps.