How to implement pushState() and popState() with ajaxed content in JSON format?

2.4k views Asked by At

Short Version

What content does the content.php file referenced in this tutorial have?

http://moz.com/blog/create-crawlable-link-friendly-ajax-websites-using-pushstate

Long Version With Research

The tutorial above is the most succinct I have come across for implementing pushState() and popState() in a scenario where you are loading content via Ajax but want to retain bookmarking and browser backwards and forwards navigation functionality:

A demo page has been set up as a proof of concept:

http://html5.gingerhost.com/

Where the source code is as below.

There are several in-between steps needed to implement it however that I'm not totally familiar with:

  • Setting up a PHP file of content in JSON format
  • Understanding JSON formatting

A comment on this post html5 pushstate example and jquery's $.getJSON suggests using Firebug to see the HTTP request response in order to see the JSON formatting.

With Firebug loaded, and Console > All selected, when I click on the navigation links I see entries like:

GET  http://html5.gingerhost.com/content.php?cid=%2F&format=json    200 OK  869ms
GET  http://html5.gingerhost.com/content.php?cid=%2Fseattle&format=json  200 OK  859ms
GET  http://html5.gingerhost.com/content.php?cid=%2Fnew-york&format=json  200 OK  837ms
GET  http://html5.gingerhost.com/content.php?cid=%2Flondon&format=json  200 OK  863ms

The corresponding content from the 'Reponse' tab for each entry is in the JSON format:

{"title":"Title value here","h1":"H1 value here","article #articletext":"<p>Lots of html here.<\/p><p>That includes escaped characters.<\/p>","#image":"<img class=\"thumbnail\" alt=\"\" src=\"and_an_image.jpg\">"}

So after some research, JSON format seems to be:

{
"myArrayName": [
{ "Key1":"Value1" , "Key2":"Value2" },  // object one
{ "Key1":"Value3" , "Key2":"Value4" },  // object two 
{ "Key1":"Value5" , "Key2":"Value6" },  // object three
]
}

Adding a 'real world' example to that would make it:

{
"myCDCollection": [
{ "Title":"Trash" , "Artist":"Alice Cooper" },  // object one
{ "Title":"Dr. Feelgood" , "Artist":"Motley Crue" },  // object two
{ "Title":"Cherry Pie" , "Artist":"Warrant" },  // object three
]
}

So the keys in the proof of concept seem to be:

title
h1
article #articletext
#image

So my question is what content does the content.php file referenced in the tutorial need to have?

Is it just a matter of copying and pasting the JSON objects, separated by commas?

Do they need to be encapsulated in an array?

Does the array need a name?

Which is then encapsulated in curly braces?

Does the PHP file need a MIME media type specified, if so where and how?

Here is the script from the proof of concept:

<script>
// THIS IS WHERE THE MAGIC HAPPENS
$(function() {
$('nav a').click(function(e) {
$("#loading").show();
href = $(this).attr("href");

loadContent(href);

// HISTORY.PUSHSTATE
history.pushState('', 'New URL: '+href, href);
e.preventDefault();


});

// THIS EVENT MAKES SURE THAT THE BACK/FORWARD BUTTONS WORK AS WELL
window.onpopstate = function(event) {
$("#loading").show();
console.log("pathname: "+location.pathname);
loadContent(location.pathname);
};

});

function loadContent(url){
// USES JQUERY TO LOAD THE CONTENT
$.getJSON("content.php", {cid: url, format: 'json'}, function(json) {
// THIS LOOP PUTS ALL THE CONTENT INTO THE RIGHT PLACES
$.each(json, function(key, value){
$(key).html(value);
});
$("#loading").hide();
});

// THESE TWO LINES JUST MAKE SURE THAT THE NAV BAR REFLECTS THE CURRENT URL
$('li').removeClass('current');
$('a[href="'+url+'"]').parent().addClass('current');

}

</script>
1

There are 1 answers

3
sahbeewah On

It doesn't matter what content.php contains, it is just supposed to return some content that is then manipulated by javascript and loaded into the DOM. You can't really determine what his content.php contains, but given the limited scope of the page, here is one possibility:

<?php
    $page = $_GET['cid'];

    $pageData = array();
    switch ($page) {
        case '/':
            $pageData = array(
                'title' => 'Seattle - Part of a demo for #ProSEO',
                'h1' => 'Seattle',
                'article #articletext' => '<p>Seattle is the northernmost major city in the contiguous United States, and the largest city in the Pacific Northwest and the state of Washington. It is a major seaport situated on a narrow isthmus between Puget Sound (an arm of the Pacific Ocean) and Lake Washington, about 114 miles (183 km) south of the Canada - United States border, and it is named after Chief Sealth \"Seattle\", of the Duwamish and Suquamish native tribes. Seattle is the center of the Seattle-Tacoma-Bellevue metropolitan statistical area--the 15th largest metropolitan area in the United States, and the largest in the northwestern United States.<\/p><p>Seattle is the county seat of King County and is the major economic, cultural and educational center in the region. The 2010 census found that Seattle is home to 608,660 residents within a metropolitan area of some 3.4 million inhabitants. The Port of Seattle, which also operates Seattle-Tacoma International Airport, is a major gateway for trade with Asia and cruises to Alaska, and is the 8th largest port in the United States in terms of container capacity.<\/p>',
                '#image' => '<img class=\"thumbnail\" alt=\"\" src=\"seattle.jpg\">'
            );
            break;
        case '/new-york':
            $pageData = array(
                'title' => 'New York - Part of a demo for #ProSEO',
                'h1' => 'New York',
                'article #articletext' => '<p>New York is the most populous city in the United States and the center of the New York metropolitan area, which is one of the most populous metropolitan areas in the world. New York City exerts a significant impact upon global commerce, finance, media, culture, art, fashion, research, technology, education, and entertainment. As the home of the United Nations Headquarters, it is also an important center for international affairs. The city is often referred to as New York City or the City of New York, to distinguish it from the state of New York, of which it is a part.<\/p>',
                '#image' => '<img class=\"thumbnail\" alt=\"\" src=\"new-york.jpg\">'
            );
            break;
        case '/london':
            // similar code for london
            break;
        case '/seattle':
            // similar code for seattle
            break;
    }

    header('Content-Type: application/json');
    echo json_encode($pageData);
?>

In reality it most likely retrieves the page data from an external source like a database.

Is it just a matter of copying and pasting the JSON objects, separated by commas? Do they need to be encapsulated in an array?

Nothing needs to be encapsulated in an array - it doesn't matter how it gets there (you could generate the JSON yourself manuallly) as long as that's what the output is (a json-valid file). And you specify the MIMEtype of the response to application/json using the header method in PHP.