Have you used PJAX yet (PushState + AJAX = PJAX)? It’s a pretty slick way to make AJAX partial updates a lot better compared to the regular g:remoteLink tag. The primary benefits are you don’t break the back button functionality and it updates the URL!
The key to implementing PJAX is that you need to have a “chrome-less” view for PJAX requests. This means the view can’t have the main.gsp layout applied to it (or whatever your layout is called). There are a number of different ways you could do this. First, you could simply look for the HTTP header that PJAX adds to each request called X-Pjax and then apply a different layout in the controller (or no layout at all). The approach I decided to take was a little different though. I decided that I didn’t want to modify any controllers and instead do it at the framework level. I also didn’t want to modify any views that already have the meta.layout (<meta name=”layout” content=”main”/>). My solution was to extend GrailsLayoutDecoratorMapper with my own new class called PjaxDecoratorMapper. I was originally going to create a Grails PJAX plugin to take care of this, but you need to modify sitemesh.xml in order to register this new decorator and I don’t believe there currently is any programmatic way to do that (like you can with web.xml). Also, the way that I’m implementing PJAX is certainly not the only way in a Grails app so I’m not sure how much value a plugin would even really provide. If people like this approach and it provides value, I’m certainly open to creating a plugin though. Let me know! So, let’s dive in!
- grails create-app pjaxsample
- cd pjaxsample/web-app/js
- curl -O https://raw.github.com/defunkt/jquery-pjax/master/jquery.pjax.js
Edit grails-app/conf/ApplicationResources.groovy to look like the following:
Next, we need to create a layout that will only be used for our PJAX requests.
Create a new grails-app/views/layouts/pjax.gsp that looks like this:
As you can see, all this layout is doing is rendering the body wrapped in a div called main. You can obviously call this div whatever you want or have multiple layouts for different divs that you want to use PJAX with if needed. For my needs, I simply wanted to always update one common area with PJAX, so just using one div for this met my needs.
Now let’s create our new decorator and configure it with sitemesh!
Create a new src/groovy/grails/pjax/PjaxDecoratorMapper.groovy file that looks like this:
Then modify the decorator-mappers part of web-app/WEB-INF/sitemesh.xml so it looks like this:
In the screencast below, I will now demonstrate using this PJAX setup in a sample application! You can download all the source for this screencast on GitHub: https://github.com/gr8casts/pjaxsample.
I hope you enjoyed this post about using PJAX in Grails! Please let me know in the comments if you have any suggestions for ways to improve PJAX usage in Grails and if you found this valuable or not. Thanks for reading & watching!