Skip to content

Commit 97cb0b0

Browse files
committed
Merge pull request #256 from defunkt/pjax-version-reloading
Layout Reloading
2 parents ff6e817 + 9ce916f commit 97cb0b0

File tree

4 files changed

+65
-1
lines changed

4 files changed

+65
-1
lines changed

README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -243,6 +243,26 @@ An `X-PJAX` request header is set to differentiate a pjax request from normal XH
243243

244244
Check if your favorite server framework supports pjax here: https://gist.github.com/4283721
245245

246+
#### Layout Reloading
247+
248+
Layouts can be forced to do a hard reload assets or html changes.
249+
250+
First set the initial layout version in your header with a custom meta tag.
251+
252+
``` html
253+
<meta http-equiv="x-pjax-version" content="v123">
254+
```
255+
256+
Then from the server side, set the `X-PJAX-Version` header to the same.
257+
258+
``` ruby
259+
if request.headers['X-PJAX']
260+
response.headers['X-PJAX-Version'] = "v123"
261+
end
262+
```
263+
264+
Deploying a deploy, bumping the version constant to force clients to do a full reload the next request getting the new layout and assets.
265+
246266
### Legacy API
247267

248268
Pre 1.0 versions used an older style syntax that was analogous to the now deprecated `$.fn.live` api. The current api is based off `$.fn.on`.

jquery.pjax.js

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -223,8 +223,23 @@ function pjax(options) {
223223
}
224224

225225
options.success = function(data, status, xhr) {
226+
// If $.pjax.defaults.version is a function, invoke it first.
227+
// Otherwise it can be a static string.
228+
var currentVersion = (typeof $.pjax.defaults.version === 'function') ?
229+
$.pjax.defaults.version() :
230+
$.pjax.defaults.version
231+
232+
var latestVersion = xhr.getResponseHeader('X-PJAX-Version')
233+
226234
var container = extractContainer(data, xhr, options)
227235

236+
// If there is a layout version mismatch, hard load the new url
237+
if (currentVersion && latestVersion && currentVersion !== latestVersion) {
238+
locationReplace(container.url)
239+
return
240+
}
241+
242+
// If the new response is missing a body, hard load the page
228243
if (!container.contents) {
229244
locationReplace(container.url)
230245
return
@@ -676,6 +691,16 @@ function cachePop(direction, id, value) {
676691
delete cacheMapping[id]
677692
}
678693

694+
// Public: Find version identifier for the initial page load.
695+
//
696+
// Returns String version or undefined.
697+
function findVersion() {
698+
return $('meta').filter(function() {
699+
var name = $(this).attr('http-equiv')
700+
return name && name.toUpperCase() === 'X-PJAX-VERSION'
701+
}).attr('content')
702+
}
703+
679704
// Install pjax functions on $.pjax to enable pushState behavior.
680705
//
681706
// Does nothing if already enabled.
@@ -700,7 +725,8 @@ function enable() {
700725
type: 'GET',
701726
dataType: 'html',
702727
scrollTo: 0,
703-
maxCacheLength: 20
728+
maxCacheLength: 20,
729+
version: findVersion
704730
}
705731
$(window).bind('popstate.pjax', onPjaxPopstate)
706732
}

test/app.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ def title(str)
2222
after do
2323
if pjax?
2424
response.headers['X-PJAX-URL'] = request.url
25+
response.headers['X-PJAX-Version'] = 'v1'
2526
end
2627
end
2728

test/unit/pjax.js

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,23 @@ if ($.support.pjax) {
400400
}
401401
})
402402

403+
asyncTest("header version mismatch does a full load", function() {
404+
var frame = this.frame
405+
406+
frame.$.pjax.defaults.version = 'v2'
407+
408+
frame.$.pjax({
409+
url: "hello.html",
410+
container: "#main"
411+
})
412+
413+
this.iframe.onload = function() {
414+
equal(frame.$("#main p").html(), "Hello!")
415+
equal(frame.location.pathname, "/hello.html")
416+
start()
417+
}
418+
})
419+
403420

404421
asyncTest("triggers pjax:start event from container", function() {
405422
var frame = this.frame

0 commit comments

Comments
 (0)