I figured out a semi-cool setup to provide alternate views if the client is found to be, for instance, a Mobile Safari browser on an iPhone. I wanted to share my findings since I’ve seen related questions asked here or there, and I have a question at the end about a potential improvement.
First, I made a filter:
detectMobile (controller:'*', action:'*') { before = { if (request.getHeader('user-agent') =~ /(?i)iphone/) { request['isMobile'] = true } else { request['isMobile'] = false } return true // keep processing other filters and the action } after = { } afterView = { } }
Next, I added the following to a controller:
def afterInterceptor = { model, modelAndView -> if (request['isMobile']) { modelAndView.viewName = modelAndView.viewName + "_m" } }
For that controller, if a request comes in from a mobile device, a view ending in “_m” is loaded, instead of the default view. The view “list.gsp” would have a counterpart mobile view “list_m.gsp”, and that’s what would be served to iPhone clients. That’s it, so far.
One bit that would be handy would be to add this closure to every controller, rather than have to copy and paste it to controllers that support mobile views. I’ve been meaning to see how the rest plugin dynamically adds methods to every controller in case that is similar to what I’m trying to do, but if anyone knows offhand what I need to do (or read) to automatically get the closure in every controller, please let me know.