Jérémie is a frontend developer and Marc does the backend.
Address/state handling and content rendering are the two main challenges.
Browser history. If you don’t watch out, the back button won’t be working.
Deeplinking should stay possible.
A hash like
handle everything behind the hash.
A hashbang like
http://yoursite.com/#!/some/id. The difference? Google
and others replace the URL with
http://yoursite.com/?_escaped_fragment_/some/id. You’ll have to
configure your website to support it. Deeplinks work this way and crawlers
can access the site via links in a search engine sitemap.
It works with almost all browsers. And it covers all three mentioned problems. You have multiple URLs, however. And you’ll need to maintain legacy URLs.
In django you could implement it with some middleware that detects the
_escaped_frament_ GET parameter.
Pushstate. The URL is a regular URL like
http://yoursite.com/some/id. The best example is the github website.
Pro: easier to implement on the backend, good URLs, everything crawlable and deeplinkable. It degrades gracefully.
Drawbacks: no wide support. Even IE9 doesn’t support it. 62% of the now-used-browser-clients support it. But… it does work, just slower, as you need to grab a whole new page. Another drawback: it is more work for the frontend developer.
They do it with pjax: Push state ajax. A pjax link fetches the whole new page source over ajax and extracts a specified div and the title and modifies the browser history. You improve the speed this way by not needing to re-render the entire page, only one part is updated.
There are some existing implementations, like django-jax, django-easy-pjax and django-ajax-blocks, but they all had problems. So they made their own solution:
Django: template inheritance and filters and middleware.
They have two base templates: one for the regular layout and one for the pjax responses. They build a template filter “pjax” that returns whether it is a pjax request or not and modifies the name of the template that’s extended. That way you get a mostly empty page for pjax and the full one for regular requests.
Backbone handles the pjax handling, requesting the new page and replacing divs and so. And it keeps track of the browser history.
Some pitfalls: caching and redirection.
You use the same URL for your regular and pjax response. So caching can trip
you up. Setting a
Vary header helps, but not in all browsers. So they’re
now using a special URL and modify it back to the original URL in
Redirections happen transparently for ajax requests. You don’t have a chance to intercept them. To work around it, they return json for pjax requests with the redirect info in there.
My name is Reinout van Rees and I work a lot with Python (programming language) and Django (website framework). I live in The Netherlands and I'm happily married to Annie van Rees-Kooiman.
Most of my website content is in my weblog. You can keep up to date by subscribing to the automatic feeds (for instance with Google reader):