Releases: rainboyan/grails-plugin-dynamic-modules
v0.1.0
v0.0.3
Grails Dynamic Modules Plugin
Grails Dynamic Modules Plugin (GDMP) offer new ways of creating modular and maintainable Grails applications.
A Grails plugin can implement one or more plugin modules to develop and extend Grails applications.
What's Changed
Breaking Changes
- BREAKING: relocate
ModuleDescriptor,ModuleDescriptorFactorytograils.plugins, relocateAbstractModuleDescriptortograils.plugins.descriptors
Grails Version
- Grails 4.1.2
Usage
Add dependency to the build.gradle,
repositories {
mavenCentral()
}
dependencies {
// Grails 4
compile "org.rainboyan.plugins:grails-plugin-dynamic-modules:0.0.3"
// Grails 5
implementation "org.rainboyan.plugins:grails-plugin-dynamic-modules:0.0.3"
}
In your Grails Plugin project,
First, we create a Module descriptor: MenuModuleDescriptor,
@ModuleType('menu')
class MenuModuleDescriptor extends AbstractModuleDescriptor {
String i18n
String title
String link
String location
int order
MenuModuleDescriptor() {
}
@Override
void init(GrailsPlugin plugin, Map args) throws PluginException {
super.init(plugin, args)
this.i18n = args.i18n
this.title = args.title
this.link = args.link
this.location = args.location
}
}and then we update the MyNewGrailsPlugin to extend grails.plugins.DynamicPlugin,
class MyNewGrailsPlugin extends DynamicPlugin {
// 1. adding custom module types
def providedModules = [
MenuModuleDescriptor
]
// 2. define 'menu' module in doWithDynamicModules hook
void doWithDynamicModules() {
menu(key: 'about', i18n: 'menu.about', title: 'About US', link: '/about', location: 'topnav')
menu(key: 'product', i18n: 'menu.product', title: 'Products', link: '/product', location: 'topnav', enabled: "${Environment.isDevelopmentMode()}") {
description = "This menu enabled: ${Environment.isDevelopmentMode()}"
order = 2
}
menu(key: 'contact', i18n: 'menu.contact', title: 'Contact', link: '/contact', location: 'topnav', enabled: false)
menu(key: 'help', i18n: 'menu.help', title: 'Help', link: '/help', location: 'footer')
}
}now, you can get all the module descriptors in your Grails application throug the extended API of GrailsPluginManager,
// Get all the ModuleDescriptors
Collection<ModuleDescriptor<?>> allDescriptors = pluginManager.getModuleDescriptors()
// Get all the enabled MenuModuleDescriptor
List<MenuModuleDescriptor> menuDescriptors = pluginManager.getEnabledModuleDescriptorsByClass(MenuModuleDescriptor)
I've created a sample Grails project(Grails Dynamic Modules Demo) that you can run it and learn more.
Support Grails Version
- Grails 4.0, 4.1
- Grails 5.0, 5.1, 5.2, 5.3
Known issues
Grails has a bug that has been around since 2.0.0. I have submitted a patch for this bug, you can learn about it here, hope to fix it in the next release.
In your MyNewGrailsPlugin(which extends DynamicPlugin), when you using doWithSpring(),
there will be an error reporting that A component required a bean of type 'org.rainboyan.plugins.ModuleDescriptorFactory' that could not be found.,
this is because the Closure doWithSpring's delegation strategy was not set, Closure.OWNER_FIRST is the default strategy.
Closure doWithSpring() { {->
// Grails bugs here, because doWithSpring's delegation strategy not set
webMenuManager(DefaultWebMenuManager)
}
}
License
This plugin is available as open source under the terms of the APACHE LICENSE, VERSION 2.0