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
,ModuleDescriptorFactory
tograils.plugins
, relocateAbstractModuleDescriptor
tograils.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