Skip to content

Releases: rainboyan/grails-plugin-dynamic-modules

v0.1.0

22 Sep 18:02
Compare
Choose a tag to compare

What's Changed

46d9f4b Update README
0efef0c Auto-Configure DynamicModules
64f691f Make DefaultModuleDescriptorFactory implements ApplicationContextAware
1a28827 Set project version to 0.1.0-SNAPSHOT

Full Changelog: v0.0.5...v0.1.0

v0.0.3

09 Mar 17:35
Compare
Choose a tag to compare
v0.0.3 Pre-release
Pre-release

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 to grails.plugins, relocate AbstractModuleDescriptor to grails.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

Links