Search code examples
grailsgsp

grails current page highlight


In grails I have a menu. I'm trying to highlight the menu item for the active page:

link1
link2 (show as bold if the controller action partially matches this gsp name)
link3

I have working code but it seems like there would be a better way.

Taglib works fine:

def active = { attrs, body ->
    for (page in attrs.check) {
        if (params.action.startsWith(page)) {
            out << "current"
            break
        }
    }
}

This option works fine, but seems wordy:

<li><a href="${createLink(action: 'contactInfo')}" title="Contact Info" class="<xyz:active check='${['contactInfo']}'/>">Contact Info</a></li>
<li><a href="${createLink(action: 'aboutYouFamily')}" title="About You" class="<xyz:active check='${['aboutYouFamily', 'aboutYouBackground', 'aboutYouCharacteristics', 'aboutYouLifestyle', 'aboutYouApplicant2']}'/>">About You</a></li>

This blows up:

<g:link action='myProfile' class="${<xyz:active check='${['myControllerAction']}'/>}">My Profile</g:link>

I don't believe you can pass a taglib as a parameter to g:link

I also have the requirement that multiple gsps/actions would cause a link to be active because of how they are named:

aboutYouLocation
aboutYouBackground
aboutYouEducation

all make this link the active one:

About You

I can do a partial match, but I've also got some actions/gsps that begin with aboutYour (extra R) resulting in my use of the array being passed into my taglib.


Solution

  • There's a standard way of doing that with the Platform Core plugin. It will provide you a Navigation API:

    grails-app/conf/AppNavigation.groovy

    navigation = {
        // Declare the "app" scope, used by default in tags
        app {
          contact(action: 'contactInfo')
          about(action: 'aboutYouFamily')
        }
    }
    

    *grails-app/view/_menu.gsp* (template that you can use in your layout or GSP's)

    <nav:menu scope="app" id="navigation" />
    

    You can also customize the html generated for your menu, check the custom item rendering.