Grails: Set sitemesh layout depending on request parameter

For Fancyboxes/Lightboxes you may want to reuse your existing views with just another layout. In the Reference Documentation you’ll find some methods to trigger the layout in a static manner.
If you want to do this dependening on a request parameter (for example layout=embedded) you have two possibilities:

1. Use a expression in the meta tag

<head>
    <meta name="layout" content="${params.layout ?: 'main'}">
...

With this approach you have to use the meta tag in your views and use the expression in every view where you want the layout to be changeable.

2. Define a filter

import org.codehaus.groovy.grails.web.sitemesh.GroovyPageLayoutFinder

/**
 * Set layout depending on request parameter. This layout has the highest priority.
 */
class LayoutFilters {
    def filters = {
        all(controller:'*', action:'*') {
            before = {
				if (params.layout) {
					request[GroovyPageLayoutFinder.LAYOUT_ATTRIBUTE] = params.layout
				}
            }
        }
    }
}

With this filter you have the ability to change the layout for every view in your application. If you only want this mechanism for some controller/actions, change the filter expression (see Applying Filters).

Advertisements

Error in Grails documentation of URL Mappings exclude

In 6.4.6 Mapping Wildcards is written that you exclude URIs like this:

static excludes = ["/images/**", "/css/**"]

But this didn’t work for me. Looking at the source code (UrlMappingsFilter) I found out, that the exclude is no wildcard pattern matching and only a startsWith matching:

for (String excludePattern:excludePatterns){
    if (uri.equals(excludePattern)||
            (excludePattern.endsWith("*")&&
                    excludePattern.substring(0,excludePattern.length()-1).
                            regionMatches(0,uri,0,excludePattern.length()-1))){
        processFilterChain(request, response, filterChain);
        return;
    }
}

So the correct way is with one asterisk:

static excludes = ["/images/*", "/css/*"]