DiggingIntoWordPress

by Chris Coyier & Jeff Starr

Ajax Requested Page Return Only Content

Posted by on

I posted a little tip on CSS-Tricks the other day about how you can load only parts of other pages on a site via Ajax, and how to do that without needing additional HTML wrapping elements to keep it clean. A common criticism of this is that the Ajax request still loads the entire page, using all that bandwidth, it’s just that it only places onto the page the part you specify via CSS selector.

Sometimes it’s hard to have discussions like this without looking at specific use case, but I see where they are coming from. Loading content you aren’t going to use is a waste of bandwidth. It does make progressive Ajax enhancements a lot easier though. And in fact, that’s how the ALL AJAX theme here on this site works.

This had me thinking though… if WordPress pages could be smart enough to know if they are being requested normally or via Ajax, they could return only the appropriate content. Turns out PHP can detect this. So here is the basic idea:

<?php 

/* Page template, or single.php, or any other typical 
    theme file in charge of displaying a whole page */

the_post();

/* Ajax check  */
if (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') { ?>

  /* This is Ajax: Return ONLY content */
  <h1><?php the_title(); ?></h1>
  <?php the_content(); ?>

<?php } else { ?>

  /* Normal request: Return everything (header, sidebar, content, etc) */

  <?php get_header(); ?>

  <section id="main-content">
  	<article class="post" id="post-<?php the_ID(); ?>">
  		<h1><?php the_title(); ?></h1>
  		<?php the_content(); ?>
  	</article>
  </section>

  <?php get_sidebar(); ?>
  <?php get_footer(); ?>

<?php } ?>

I haven’t tested this but it seems like a reasonable solution to me. Anyone have any experience trying something like this?

16 Responses

  1. I don’t think that’s an elegant solution, I’m pretty certain there’s a better one.

    You can check out what the plugin “Infinite Scroll” is doing:
    http://wordpress.org/extend/plugins/infinite-scroll/

    I haven’t looked into it yet, but I installed this plugin on my custom theme and it just worked like a charm! Right out of the box.

  2. Yes, it seems like a reasonable solution. I prefer creating separate pages for AJAX requests and even put them in separate folders. I like to keep them organized. I’ve tested your code and indeed worked. However, the value of $_SERVER[‘HTTP_X_REQUESTED_WITH’] is ‘XMLHttpRequest’ not ‘xmlhttprequest’. Just wanted to point out this, since it doesn’t work if you put lowercase characters. At least, that’s what my PHP (5.3.0) returns ;-)

    • I think it varies, that’s what the strtolower() function is there for. =)

    • It goes through the strtolower() function first, so ‘xmlhttprequest’ should work!

    • You should really only test for the existence of $_SERVER[‘HTTP_X_REQUESTED_WITH’] and not care about its value.

  3. I do something similar, except I pass a variable (e.g., “is_ajax”) via a jQuery ajax request. Then throughout the template I just check that $_GET variable and return the parts I need for an ajax request.

    It’s kind of messy, but creating multiple templates can be, too.

  4. A while back I had the same need and addressed it with a plugin, http://bit.ly/hfvcbG

    Should WP do it natively, sure, but for now the plugin works like a charm.

  5. Not sure why you would do this when JSON is available. Better yet someone has already built an awesome JSON API for WordPress. I believe doing is this way is not only easier but much much faster.

    http://wordpress.org/extend/plugins/json-api/

    • Oh yes, I’ve used JSON too instead of showing HTML code or just text as a response.

    • The problem with using JSON is that you have to format it using JavaScript, and this means you have presentation management in two places, so instead you let the php manage the presentation, as it’s already there for the non-Ajax version.

      • No no no. you can easily use same JSON file both in JavaScript and on PHP level. this is really great solution. I build websites to have them both working with JS (ajax, some animations and so on) and and with no JS and I keep all data in one format.

  6. I do this all the time. I add a function to the functions.php file in my theme like what you have above that returns a boolean value. I then use something like:

    <?php if (!is_ajax()) get_header(); ?>

    This turns out to be an elegant solution when you need fallbacks if JavaScript isn’t available.

  7. i’ve used something similar, glad to see i’m not the only one. :)

  8. This technique can cause problems with file-based cache plugins. Using a separate URL for fetching json, xml, or an html snippet will lead to less problems. And if implemented carefully, the rpc data will also be cached.

    • That’s a really good point. I hadn’t thought about that. Thanks for the tip.

Comments are closed. Contact us with any critical information. Thank you!

Code is poetry