Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

There are a bunch of questions on Stack Overflow about whether AJAX should return JSON or HTML, and most seem to agree that it is ideal to return JSON for the sake of speed. However, that means that if I degrade gracefully, I will have some duplicate code because I am generating the same markup in both PHP and Javascript.

A hypothetical example: A website has a list of links to short stories. If the user has Javascript, then clicking on one of these links loads the story without a page refresh. This is done with an AJAX request that returned a JSON with the story information. Javascript generates the markup for the story. If the user does not have Javascript, then clicking on the same link reloads the page with the story now loaded. PHP generates the markup for the story.

Is there a solution to use JSON and degrade gracefully without duplicating the code?

share|improve this question
add comment

2 Answers 2

up vote 6 down vote accepted

Sure.

You are using json_encode right? So start with the same data structure. For simplicity here I will use an array.

$stories = array( '[id]' => [details] );

Now you have a quick break. If the request is an AJAX request, then simply echo json_encode($stories);. Otherwise standard requests will process the view with that same data structure.

I'm going to expand on this a bit. Assuming you aren't using some MVC paradigm and doing "straight" PHP work.

For generating the page you are going to want to encapsulate the logic for this table in a separate PHP file called with an include(). Let's call this file storyList.php and it's in the same web-accessible folder as everything else.

// File: storyList.php
// First connect to the database and pull the story list
// based on any parameters passed.
$story = new StoryList($_REQUEST);
$list = $story->fetch_list();

// Now do a quick conditional based on the headers.
// See http://php.net/manual/en/function.get-headers.php and
// define your own function for testing if a request is made
// with AJAX or not. Several libraries include their own.
if (is_xhr())
{
    echo json_encode($list);
}
else
{
    foreach ($list as $title => $story)
    {
        // Format as a table
    }
}
share|improve this answer
    
Thank you for answering, but I'm confused. Isn't this still duplicate code? If for example I change it from a table to an ordered list, won't I have to make this change in both my Javascript and my PHP? –  juicy lucy May 16 '11 at 21:21
    
@juicy: Yes, this is why I typically prefer to load html instead of JSON. –  Josh K May 17 '11 at 0:59
add comment

In a recent Google IO presentation this subject was discussed in some detail.

To solve this problem they used Mustache for templating. Using the Mustache.js implementation on the client side and the sharing same templates on the server side - in your case perhaps Mustache.php - the duplication can be removed.

share|improve this answer
    
This jQuery conference presentation says the same thing: use the same templates server-side and client-side. –  user16764 May 27 '11 at 16:51
    
I've blogged an example of this: duganchen.ca/single-page-web-app-architecture-done-right –  user16764 Jul 27 '11 at 15:29
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.