DomainLink tag for Grails

Jul/09
28
0

One of the first things I noticed when generating the views from my domain classes was the code to link to an object in list.gsp.

Wouldn’t it be nice to just ‘mention’ an object using a tag that would render itself including a link to it’s controller?

That resulted in the following tag:

    def domainLink = {attrs, body ->
        def object = attrs.object
        def controller = attrs.controller
        // Action defaults to 'show'
        def action = attrs.action ?: 'show'

        if (!controller) {
            // If no controller was given in the tag, determine it through the object's class
            def lookForClass = object.metaClass.theClass

            // Find out which domain class this is
            def domainClass = grailsApplication.domainClasses.find {
                domain -> domain.clazz == lookForClass
            }

            if (!domainClass) {
                throwTagError("The property [object] of tag [domainLink] isn't a Domain class, but a ${object.class}")
            }
            controller = domainClass.shortName
            // first char to lower case
            controller = controller[0].toLowerCase() + controller.substring(1)
        }

        def bodyContent = body()
        // Do we have a body?
        // In that case use the body, otherwise "toString" the object
        def display = bodyContent ?: object
        out << g.link (controller: controller, action: action, id: object.id, {display})
    }

Now we can use it in a GSP like this:

<my:domainLink object="${todoInstance}"/>

which renders a link to the show action of the Todo controller (probably) with the ID of this todoInstance. You can specify a specific action and even a controller if you want. If you don't include a body, it uses toString().

<my:domainLink object="${todoInstance}" action="delete">Delete me!</my:domainLink>

You might wonder why I didn't use the convention, that a gsp links to the controller it came from. My domain model contains some inherited classes (e.g. User extends Person), so a list of objects can contain both classes. Now, the links in this list point to the correct controller and I'm not editing a User through the PersonController.

Share and Enjoy:
  • Print
  • Twitter
  • StumbleUpon
  • Digg
  • del.icio.us
  • Facebook
  • Google Bookmarks
  • DZone
  • LinkedIn
Tagged as: , ,
Comments (0) Trackbacks (0)

No comments yet.

Leave a comment

No trackbacks yet.