Thursday, June 9, 2011

How to use Groovy categories in gsp's

You use Groovy categories in a canonical way in gsp's. i.e. by surrounding all your gsp code inside a call to

<% use(YourCategoryClass) { %>

<% } %>

But it gets troublesome quite soon, especially if the main gsp renders other partial templates.

Luckily there is a way to hook into the view rendering workflow. The trick is to provide your own implementation of View that invoke the call to use categories around the view.render method. To do that you also need to override the default jspViewResolver spring bean with your own implementation of ViewResolver which uses your own implementation of View. Lastly if you need dynamically decide what categories classes to use then you can pass it in the model attribute inside your controller.

The result will look something like this.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 
class MyGrailsViewResolver extends GrailsViewResolver {

    @Override
    protected View loadView(String viewName, Locale locale) {
        new MyView(super.loadView(viewName, locale))
    }

    static class MyView implements View {
        def View view

        MyView(View view) {
            this.view = view
        }

        String getContentType() {
            view.getContentType()
        }

        void render(Map<String, ?> model, HttpServletRequest request, HttpServletResponse response) {
            if (model.categories) {
                use(model.remove('categories')) {
                    view.render model, request, response
                }
            } else {
                view.render model, request, response
            }
        }
    }
}

No comments: