Straightfw
Straightfw

Reputation: 2211

Dynamically creating a menu of available scaffoldings in Grails

I have a bunch of model classes in my Grails app, all of which are for the purpose of dynamic scaffolding of their respective database tables. For the index of the app, I'd like to have a menu of all these scaffoldings so that if a new model is added, the menu is updated.

Is there any automatic, Grails way of doing this or am I stuck with creating a naive index view with a bunch of g:link's statically typed out for each class to take the user to their respective CRUD views?

Upvotes: 1

Views: 149

Answers (2)

Mike W
Mike W

Reputation: 3932

As an extension to Joshua's answer, the following should get you a list of scaffolded controllers, in grails 3 at least.

<g:each var="c" in="${grailsApplication.controllerClasses.findAll{ it.isReadableProperty('scaffold') } }">
    <li><g:link controller="${c.logicalPropertyName}">${c.fullName}</g:link></li>
</g:each>

EDIT

As requested in the comments, to get the table name you'll need access to the sessionFactory which you'll need to inject into a controller, something like the following will get you a map of domain name to domain table name.

Controller

class YourController {

    def sessionFactory

    def index() {
        def scaffoldedTables = grailsApplication.controllerClasses.findAll{ it.isReadableProperty( 'scaffold' ) }.collectEntries {
            [(it.name): sessionFactory.getClassMetadata(it.getPropertyValue( 'scaffold', Object.class )).tableName]
        }

        [scaffoldedTables: scaffoldedTables]
    }
}

gsp

<g:each var="c" in="${scaffoldedTables}">
    <li><g:link controller="${c.key}">${c.value}</g:link></li>
</g:each>

Upvotes: 2

Joshua Moore
Joshua Moore

Reputation: 24776

You could just simply build a list of them like this:

<ul>
    <g:each var="c" in="${grailsApplication.controllerClasses.sort { it.fullName } }">
    <li><g:link controller="${c.logicalPropertyName}">${c.fullName}</g:link></li>
    </g:each>
</ul>

This code was taken from an old Grails 1.3x project from the default index.gsp. Not sure if it still works in recent versions of Grails, but it should at least give you an idea of what you can do that would be dynamic.

UPDATE As Jeff Scott Brown has pointed out this will include ALL controllers, scaffolded or not, and those provided by plugins as well. In theory you could further filter the resulting classes from grailsApplication.controllerClasses, inspecting them for their package (assuming your domain is in a known package or packages) and/or if they are scaffolded (static scaffold = true).

Upvotes: 2

Related Questions