Getting Loopy – Ajax Powered Loops with jQuery and WordPress
videos

Getting Loopy – Ajax Powered Loops with jQuery and WordPress

Tutorial Details
  • Program: WordPress
  • Version: 3.0+
  • Difficulty: Intermediate
  • Estimated Completion Time: 25-30 minutes

In this tutorial, we give you a starting point for creating AJAX interaction in your blog. We follow a step by step process, showing you how to load posts based on the viewers page scroll. The tutorial covers enqueueing scripts, setting up an AJAX handler, how to get a file outside of WordPress to use WordPress functions and access the database, and logic for loading posts on user page scroll.


What this tutorial will cover:

  1. Organizing folders.
  2. Adding jQuery to your site.
  3. Including a new script (js) file.
  4. Adding a loop handler php file (loop.php or loopHandler.php).
  5. Copying loop from main index file to our loop handler.
  6. Cleaning up the loop.
  7. Including wp-load.php (it’s what makes this whole thing work well)
  8. Storing GET data as variables in our handler.
  9. Using wp-query.
  10. Using jQuery, create our AJAX call function.
  11. Success!
  12. Displaying data on page scroll.
  13. Adding a loader gif.

Assumptions:

  • You are familiar with jQuery JavaScript library
  • You have some basic understanding of AJAX
  • You are comfortable with editing WordPress PHP files

Why a Child Theme?

Since the lessons in this tutorial can be applied to any theme, I do not want to go in depth about creating child themes (as that is an article in itself). However, we do not want to lose all the hard work we will be doing here, we will need to create a child theme. If you are not familiar with child themes, you can look up how to create them by searching the WordPress codex.

For this tutorial, we will be using the the default “twentyeleven,” theme, which comes bundled with WordPress, as the parent for our child theme. All files we will be editing and creating will reference this theme, but the concepts discussed here can be applied to any WordPress loop, regardless of theme. OK, let’s compile our assets and begin editing. As we move through the code, sections will be repeated and new additions will be highlighted in bold.


The Screencast

Follow along, as we walk you step-by-step through the code, or follow the written steps below.


Step 1 Organizing folders

When you have finished adding your child theme folder, you should only see a stylesheet, linking to the parent theme, inside. Inside your folder add the following:

  • A folder named “js”
  • A folder named “images”
  • An empty php file named loopHandler.php
  • An empty php file named functions.php
  • Inside the “js” folder, add an empty js file named ajaxLoop.js
  • Copy the Index file of the parent theme and paste it into the child theme root folder

Functions.php will not override the parent theme’s functions file, but rather extend it. This file will allow us to properly add scripts to our page.


Step 2 Adding jQuery to your site

By default, jQuery is not automatically added to the “twentyeleven” theme. We can add it to our theme by adding a function to our functions.php file we created and then calling add_action() to register it. Add the following code to your functions.php file:

<?php
function register_jquery() {
    wp_deregister_script( 'jquery' );
    wp_register_script( 'jquery', 'http://ajax.googleapis.com/ajax/libs/jquery/1.6/jquery.min.js');
    wp_enqueue_script( 'jquery' );
}     
add_action('wp_enqueue_scripts', 'register_jquery');
?>

With wp_deregister_script(), we make sure to unregister any previous jquery script (if any), then we proceed to using wp_register_script() to add jQuery. We name the registered script in the first argument, “jquery” and we set the source to Google cdn in the second argument. We then call wp_enqueue_script() with the name we set in the previous function (“jquery”). The add_action() function will finally register the function we created using the hook “wp_enqueue_scripts”. According to the codex, using “wp_enqueue_scripts” as the hook is safer than using hooks such as “init”, which may break things after upgrading.

UPDATE: “WordPress 3.2 core ships with jQuery 1.6.1 out of the box so you could remove lines 3 & 4 from that and just have wp_enqueue_script( ‘jquery’ ); and WordPress 3.3 ships with jQuery 1.7.1. If you’re just doing that in case the user has a cached copy of jQuery from Google’s CDN then that’s cool but if you’re doing that you should have a fallback just in case the CDN happens to go down. I know the chances of that are very small but it’s best to be safe” – Thanks to Bronson Quick in the comments for this note! The revised code would look like this:

<?php
function register_jquery() {
    wp_enqueue_script( 'jquery' );
}     
add_action('wp_enqueue_scripts', 'register_jquery');
?>

Japh adds: “WordPress ships with jQuery and unless you’re deregistering it and reregistering it for the CDN benefits, there’s no need to do anything more than enqueuing jQuery.

The method described above is covered in the WordPress Codex under Load a default WordPress script from a non-default location, and there’s actually a note there recommending against it.

In fact, usually you’re including jQuery for use with another script, so you could simply indicate jQuery as a dependancy for your script in it’s enqueue and voila! This is covered on that Codex page too, under Load a script from your theme which depends upon a WordPress Script”.

You can read all about the proper use of using the enqueue script in our post on it here.


Step 3 Including a New Script (js) File.

To add our custom script, we will be following the same steps as we did for adding jQuery. The main difference will be that we are going to add a locally stored file rather than one that is hosted by Google. Because this script will be dependent on jQuery being loaded, we will add another argument to our register_script() call. The following is the full code in your functions.php file:

<?php
function register_jquery() {
    wp_deregister_script( 'jquery' );
    wp_register_script( 'jquery', 'http://ajax.googleapis.com/ajax/libs/jquery/1.6/jquery.min.js');
    wp_enqueue_script( 'jquery' );
}
add_action('wp_enqueue_scripts', 'register_jquery');

function register_ajaxLoop_script() {
    wp_register_script(
      'ajaxLoop',
       get_stylesheet_directory_uri() . '/js/ajaxLoop.js',
       array('jquery')
    );
    wp_enqueue_script('ajaxLoop');
}
add_action('wp_enqueue_scripts', 'register_ajaxLoop_script');
?>

The third argument, array(‘jquery’) handles any dependencies that your script may have. You can pass additional items in the array for each additional dependency. Please note that if you did not make a child theme, you should use “get_template_directory_uri()” instead of “get_stylesheet_directpry_uri()”.


Step 4 Copying Loop from Main Index File to our Loop Handler

Now that we have our scripts queued, we can begin writing our code. First we need to take a look at the index.php file inside our child theme folder. Open the file and highlight the following code:

<?php if ( have_posts() ) : ?>
    <?php twentyeleven_content_nav( 'nav-above' ); ?>
    <?php /* Start the Loop */ ?>
    <?php while ( have_posts() ) : the_post(); ?>
        <?php get_template_part( 'content', get_post_format() ); ?>
    <?php endwhile; ?>
    <?php twentyeleven_content_nav( 'nav-below' ); ?>
<?php else : ?>
    <article id="post-0">
        <header>
            <h1><?php _e( 'Nothing Found', 'twentyeleven' ); ?></h1>
        </header><!-- .entry-header -->
        <div>
            <p><?php _e( 'Apologies, but no results were found for the requested archive. Perhaps searching will help find a related post.', 'twentyeleven' ); ?></p>
            <?php get_search_form(); ?>
        </div><!-- .entry-content -->
    </article><!-- #post-0 -->
<?php endif; ?>

Copy this code and then paste it into the loopHandler.php file you created. After copying the code to your loopHandler.php file, make sure to remove this code from your index.php


Step 5 Cleaning Up the Loop

We will now clean this code up. Primarily, we will strip the code of anything we will not need. I have personal preferences in how I format my code, but you are free to format it any way that works for you. The main thing we want to accomplish here is to only keep the necessary and discard the rest. This is what we will end up with:

<?php 

// our loop
if (have_posts()) {
 while (have_posts()){
 the_post();
 get_template_part( 'content', get_post_format() );
 }
}
?>

As you can see here, we have broken the code down to its basics. I prefer to use the standard “if”, “else” syntax, but again, you can format it as you wish. We now have the guts that we need to get the posts from our database.


Step 6 Including wp-load.php (it’s what makes this whole thing work well)

One thing that stands in our way, at this point, is that our loopHandler.php file has no knowledge of WordPress or WordPress functions on its own. To mitigate this, we have to add a couple lines of code which will include the necessary data. WordPress made this easy for us by giving us wp-load.php file. It is located in the main directory of our installation. We will add the code above our loop. Our file should now look like the following:

<?php
// Our include
define('WP_USE_THEMES', false);
require_once('../../../wp-load.php');

// our loop
if (have_posts()) {
       while (have_posts()){
              the_post();
              get_template_part( 'content', get_post_format() );
       }
}
?>

We need to define our WP_USE_THEMES constant to false, so that we do not load any extra data than we need. We then require_once() our wp-load.php. Since we put our loopHandler.php in the root of our theme folder, it’s easy enough to use a relative path to wp-load.php. It’s only three levels up :).

“Since we put our loopHandler.php in the root of our theme folder, it’s easy enough to use a relative path to wp-load.php. It’s only three levels up :)”


Step 7 Storing GET Data as Variables in Our Handler.

The next step is to add a few lines to grab GET data that we will later send. We want to add two variables: One that will store the requested number of pages and one that will store the “page” number. The reason I wrote “page” in quotes is that we will not truly have pages but a single page that will continue loading more and more posts as we scroll down. However, when we query the database, we will send it a page to fetch. You will see how this works later in this tutorial. Let’s add our variables. Our code should now look like the following:

<?php
// Our include
define('WP_USE_THEMES', false);
require_once('../../../wp-load.php');

// Our variables
$numPosts = (isset($_GET['numPosts'])) ? $_GET['numPosts'] : 0;
$page = (isset($_GET['pageNumber'])) ? $_GET['pageNumber'] : 0;

// our loop
if (have_posts()) {
       while (have_posts()){
              the_post();
              get_template_part( 'content', get_post_format() );
       }
}
?>

If you are not familiar of the short hand “if” statements, this might look funky to you, but it is the same as creating an “if” statement. In the parenthesis we have our condition (is numPost set in the $_GET global variable?), then we follow it with a question mark. The left side of the colon signifies what will happen if our condition is true and the right side signifies what will happen if our condition is false. It is essentially the same as writing the following:

if( isset($_GET['numPosts']) ) {
    $numPosts = $_GET['numPosts'];
} else {
    $numPosts = 0;
}
if( isset($_GET['pageNumber']) ) {
    $page = $_GET['pageNumber'];
} else {
    $page = 0;
}

Step 8 Using wp-query.

Now we need to add just a couple more lines of code. To be able to query the database we need to create a new query using the query_posts() function. We need to pass an array of arguments to the query which will request the number of pages and the page number we wish to get. We will query the database, loop through the results, and then we will need to reset the query afterwards for good measure. Our code will now look like the following:

 <?php
// Our include
define('WP_USE_THEMES', false);
require_once('../../../wp-load.php');

// Our variables
$numPosts = (isset($_GET['numPosts'])) ? $_GET['numPosts'] : 0;
$page = (isset($_GET['pageNumber'])) ? $_GET['pageNumber'] : 0;

query_posts(array(
       'posts_per_page' => $numPosts,
       'paged'          => $page
));

// our loop
if (have_posts()) {
       while (have_posts()){
              the_post();
              get_template_part( 'content', get_post_format() );
       }
}
wp_reset_query();
?>

Step 9 Using jQuery, Create Our AJAX Call Function.

Now that we have a decent base to work with, let’s add some javascript to our ajaxLoop.js. First let’s add a jQuery function that waits for the document to load. We will then add our script inside. In your ajaxLoop.js file, add the following lines of code:

// ajaxLoop.js
jQuery(function($){
   // we will insert code here
});

 

This function wrap is the same as calling jQuery(‘document’).ready(function($){});. What we are doing here is calling jQuery rather than the dollar symbol ($), and the passing the dollar symbol to the function so that we can use it as an alias for jquery inside this function. We do this in case you are using $.noConflict() with other script libraries that may use the dollar symbol. If you are not sure what $.noConflict() is, you can search the jQuery documentation for further explanation. Next, let’s set up some variables:

// ajaxLoop.js
jQuery(function($){
    var page = 1;
    var loading = true;
    var $window = $(window);
    var $content = $('body.blog #content');
});

The “page” variable will store which page we will be loading and will increase each time we load more content. Our second variable “loading” will keep track of the content status. When we will write our function to check the scroll of the window, we do not want it to execute if we are in the loading state. Since we will load our first “page” automatically, we will set loading to “true”. The next variable “$window” will store the window DOM element after we query it with jQuery. Storing this query in a variable is useful because we do not have to make additional calls to jQuery and it helps improve performance.

Our last variable “$content” will store the returned element of the container we wish to use for loading our content. In WordPress, we are provided a class on the “body” element for the blog page called “blog”. Here I targeted the content that belongs to the blog page only so that other pages will not be affected. There are better ways of accomplishing this, but for the purposes of this tutorial, this is the quickest.

Now we need to create our AJAX call function. After setting up theAJAX function your code should look like the following:

// ajaxLoop.js
jQuery(function($){
    var page = 1;
    var loading = true;
    var $window = $(window);
    var $content = $('body.blog #content');
    var load_posts = function(){
            $.ajax({
                type       : "GET",
                data       : {numPosts : 1, pageNumber: page},
                dataType   : "html",
                url        : "http://WWW.YOURSITE.COM/wp-content/themes/YOUR_THEME_NAME/loopHandler.php",
                beforeSend : function(){
                },
                success    : function(data){
                },
                error     : function(jqXHR, textStatus, errorThrown) {
                    alert(jqXHR + " :: " + textStatus + " :: " + errorThrown);
                }
        });
    }
});

We stored the load_posts() function as a variable and can reuse it as necessary. So far we have just created the Shell for the call. When we make a jQuery AJAX call, we pass an object as the argument. The object consists of key-value pairs which will be the options we set. First we set the ‘type’ to use ‘GET’. Second we set the ‘data’ option to another object of key-value pairs consisting of our options (numPosts and pageNumber).

The ‘dataType’ option specifies the type of data that will be returned from the server. In this case it will be ‘HTML’. The ‘url’ option points to our loopHandler.php file. This is the file it will request data from. You must replace WWW.YOURSITE.COM with your site url and then replace YOUR_THEME_NAME with the name you have given your child theme!

“You must replace WWW.YOURSITE.COM with your site url and then replace YOUR_THEME_NAME with the name you have given your child theme.”

Then, we have setup options for three callbacks: ‘beforeSend’, ‘success’ and ‘error’. We will pass a parameter (I named it ‘data’) to the success function and this will be the returned data object from the server. We will be setting up this function soon.

Our ‘error’ callback will handle any server errors returned. For the purposes of this tutorial we will just output the error messages. In the ‘beforeSend’ callback we will add logic to create an animated loading gif to display while the data is being requested.


Step 10 Adding the ‘Success!’ Callback

Now we need to build our ‘success’ callback function. First, we will want to hide the data before it is shown so that we can nicely fade it in. We will then append the data to our content and fade it in. Let’s modify our ajaxLoop.js file to have the following:

// ajaxLoop.js
jQuery(function($){
    var page = 1;
    var loading = true;
    var $window = $(window);
    var $content = $("body.blog #content");
    var load_posts = function(){
            $.ajax({
                type       : "GET",
                data       : {numPosts : 1, pageNumber: page},
                dataType   : "html",
                url        : "http://WWW.YOURSITE.COM/wp-content/themes/YOUR_THEME_NAME/loopHandler.php",
                beforeSend : function(){
                },
                success    : function(data){
                    $data = $(data);
                    $data.hide();
                    $content.append($data);
                    $data.fadeIn(500);
                },
                error     : function(jqXHR, textStatus, errorThrown) {
                    alert(jqXHR + " :: " + textStatus + " :: " + errorThrown);
                }
        });
    }
});

So far, we have passed the data to jQuery ($(data)) and stored it in a variable we named $data. We used the jQuery function to hide the data. We then append the data to our content container. Once the data is appended, we fade it in.


Step 11 Displaying the Data on Page Scroll.

Now we will add three more items. The first will be a function which handles loading posts, that will be called on page scroll. The second will call our load_posts() function for the first time. In our page scroll handler we need to check to see if data is currently waiting to be loaded, call our load_posts() function and set our “loading” variable to ‘true’. For our third item, we will set the “loading” variable to ‘false’ in the callback of our fadeIn() function call. Let’s add the code as follows:

 // ajaxLoop.js
jQuery(function($){
    var page = 1;
    var loading = true;
    var $window = $(window);
    var $content = $("body.blog #content");
    var load_posts = function(){
            $.ajax({
                type       : "GET",
                data       : {numPosts : 1, pageNumber: page},
                dataType   : "html",
                url        : "http://WWW.YOURSITE.COM/wp-content/themes/YOUR_THEME_NAME/loopHandler.php",
                beforeSend : function(){
                },
                success    : function(data){
                    $data = $(data);
                    $data.hide();
                    $content.append($data);
                    $data.fadeIn(500, function(){
                        loading = false;
                    });
                },
                error     : function(jqXHR, textStatus, errorThrown) {
                    alert(jqXHR + " :: " + textStatus + " :: " + errorThrown);
                }
        });
    }
    $window.scroll(function() {
        var content_offset = $content.offset(); 
        console.log(content_offset.top);
        if(!loading && ($window.scrollTop() + 
            $window.height()) > ($content.scrollTop() +
            $content.height() + content_offset.top)) {
                loading = true;
                page++;
                load_posts();
        }
    });
    load_posts();
});

Here we put in the logic to check the location of our scroll relative to the end of the content container. Before every call to the load_posts() function we add one to our page variable, so that we get new data. The reason we add to the page before the load_posts() function call is that we have already called it once during the initialization of the script. We also set loading to true, so that we do not make additional calls before our new data is loaded.


Step 12 Adding a Loader gif.

Finally we will add a loader gif, so that on every load, the user has some feedback that the page is processing data. We will also include a check to make sure that the first load does not show the gif. In our success and error callback functions, we will remove the gif so that it doesn’t stay spinning on screen.

First things first, we need to add a loader.gif to our images folder. I suggest visiting http://www.ajaxload.info/ where you can download the loading gif of your liking. Save the image as ajax-loader.gif inside the images folder we created within our child theme’s root folder. We then will add the code to our ajaxLoop.js file that will handle this loader. Our file will now look like the following:

// ajaxLoop.js
jQuery(function($){
    var page = 1;
    var loading = true;
    var $window = $(window);
    var $content = $("body.blog #content");
    var load_posts = function(){
            $.ajax({
                type       : "GET",
                data       : {numPosts : 1, pageNumber: page},
                dataType   : "html",
                url        : "http://WWW.YOURSITE.COM/wp-content/themes/YOUR_THEME_NAME/loopHandler.php",
                beforeSend : function(){
                    if(page != 1){
                        $content.append('<div id="temp_load" style="text-align:center">\
                            <img src="../images/ajax-loader.gif" />\
                            </div>');
                    }
                },
                success    : function(data){
                    $data = $(data);
                    if($data.length){
                        $data.hide();
                        $content.append($data);
                        $data.fadeIn(500, function(){
                            $("#temp_load").remove();
                            loading = false;
                        });
                    } else {
                        $("#temp_load").remove();
                    }
                },
                error     : function(jqXHR, textStatus, errorThrown) {
                    $("#temp_load").remove();
                    alert(jqXHR + " :: " + textStatus + " :: " + errorThrown);
                }
        });
    }
    $window.scroll(function() {
        var content_offset = $content.offset();
        console.log(content_offset.top);
        if(!loading && ($window.scrollTop() +
            $window.height()) > ($content.scrollTop() +
            $content.height() + content_offset.top)) {
                loading = true;
                page++;
                load_posts();
        }
    });
    load_posts();
});

We have also added a check to make sure that if there is no data, the loading gif is removed. When our last call is sent to the server and there are no more posts, we will no longer be setting our “loading” variable to ‘false’. We will be in a loading state from then on and our scroll function will no longer make any more calls to our load_posts() function. At the same time, we make sure to clean up the last ajax-loader gif.


Wrapping Up

This tutorial was meant as an example of what can be done with posts inside of WordPress using AJAX and jQuery. We only cover a basic example of what can be accomplished here, but have provided some important concepts to take away from this. The major points to look at are how we included wp-load.php, queuing our scripts in WordPress and handling our AJAX calls.


About the Authors

Dennis Baskin

Dennis Baskin is a front-end web developer and designer working at the heart of Silicon Valley. He specializes in javascript and jQuery, but enjoys a variety of programming languages. Through his career, he has developed a variety of customized WordPress installs for clients and loves working with the framework. For more information, you can find him on LinkedIn.

Jerry Bates

Jerry Bates is a freelance developer, designer, and WordPress geek since 2.6 days. He currently creates WordPress-powered websites through his business, FittingSites, and he also publishes video tutorial content for new users of WordPress on his YouTube Channel. You can follow him on Twitter @JerrySarcastic

Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • http://www.obenlands.de/ Konstantin

    Hey,
    how about a tutorial on how you guys make those nice screenshots? Or did I miss that? :)

    • http://fittingsites.com/ Jerry

      @Konstantin – The screenshots were just something thrown together in Photoshop… we never thought of doing a tut around them, but perhaps this is a good subject for PSD tuts. :)

      • Darko

        Great Tutorial.

        Thank You very much!

  • Pingback: My Stream » Getting Loopy – Ajax Powered Loops with jQuery and WordPress

  • http://360signals.com Maor

    Great article. Though, about the inclusion of the wp-load.php file, I don’t remember exactly where I saw it, but it was saying that including the wp-load.php file is a bad practice.

    Why not use the native WordPress AJAX API function handlers, exactly as seen in this recent post by Soumitra Chakraborty? I have no doubt that this is a better approach for a challenge like this.

    • Dennis Baskin
      Author

      Hi Maor. The main reason for using wp-load in this tutorial was to demonstrate a way of handling php files outside of WordPress. I completely agree that when you are able to dump all of your server side code in the the template functions php file, that Soumitra’s solution is a great way to go.

      However what I tried to demonstrate is the fact that you do not need to handle all ajax requests in the functions.php file. Let’s say you have an e-commerce solution with a WordPress install. If you want to display your most recent posts from your blog (which is a sub directory), you do not have the luxury of using the wordpress functions.php file to display the posts elsewhere on your e-commerce installation. Using the method I have described in the tutorial would be one way to solve that.

      Tthere are many ways to handle this, but this tutorial demonstrates just one way.

      • Thomas Bennett

        Hey Dennis,

        Nice article. It is possible to use the wp-load file then to make a directory on the root (outside of WP) aware of WP functions in a way that I could register a custom sidebar from the root? Long story short, I’ve got some files aren’t inside WordPress but I would like to add a widgetized sidebar to them at this time.

        Thanks!

  • http://www.obenlands.de/ Konstantin

    Oh, and on topic:
    I’d really appreciate you using WordPress best practices, especially when using AJAX. Have a look in the codex or check out theses five tipps.
    And maybe you want to revisit the code samples for all those <strong>-tags.

    Other than that: Nice idea!

    • Dennis Baskin
      Author

      I apologize for the strong tags, when we submitted the tutorial, It was structured to work with pre tags. When I receive my login/pass so I can edit this post, I will clean it up.

      • Brandon Jones

        Just updated it for you Dennis – Thanks for following up on this!

  • http://www.sennza.com.au/ Bronson Quick

    Great article Dennis! I’m starting to use a lot more ajax in my WordPress themes these days.

    What’s your rationale in Step 2? WordPress 3.2 core ships with jQuery 1.6.1 out of the box so you could remove lines 3 & 4 from that and just have wp_enqueue_script( ‘jquery’ ); and WordPress 3.3 ships with jQuery 1.7.1. If you're just doing that in case the user has a cached copy of jQuery from Google's CDN then that's cool but if you're doing that you should have a fallback just in case the CDN happens to go down. I know the chances of that are very small but it's best to be safe :)

    • http://wp.envato.com/ Japh

      Quite right, Bronson. WordPress ships with jQuery and unless you’re deregistering it and reregistering it for the CDN benefits, there’s no need to do anything more than enqueuing jQuery.

      The method described above is covered in the WordPress Codex under Load a default WordPress script from a non-default location, and there’s actually a note there recommending against it.

      In fact, usually you’re including jQuery for use with another script, so you could simply indicate jQuery as a dependancy for your script in it’s enqueue and voila! This is covered on that Codex page too, under Load a script from your theme which depends upon a WordPress Script

    • Dennis Baskin
      Author

      Hi Bronson. You bring up a very good point as far as having a fail safe way of including jQuery. I did not want to stray too far away from the point of the article and get into the many details of when and how one should load jQuery on their wordpress installation. I think there are other articles that cover that pretty well. But neither did I want to just say “include jQuery” and be done with it (which I pretty much did for creating a child theme).

      If you have some good tips, or know of some great articles on the subject, please post them. I think it is a very valid point to observe. Thanks for your comments! :)

    • Brandon Jones

      Thanks guys! I’ve made a couple updates to Step 2 and you both get credit ;)

    • Dennis Baskin
      Author

      I do want to make one note on the fact that the update of jQuery to 1.7 has made changes to the ways it handles event binding, which includes the .live() and .die() methods, which have been deprecated. If you are using these methods elsewhere on your site, you might have issues with compatibility. This is one reason you might not want to use what WordPress gives you out of the box.

      While there are very valid reasons to update your jQuery library, you should be aware that there is also a possibility that plugin authors might not be coding for the newest updates, and might have their code possibly break.

      That said, if you are just starting from scratch, as we did in this tutorial, or you are not worried about possibly outdated plugins, then use the latest and greatest version of jQuery, it will only benefit you in the future :).

  • Lefteris

    A killer tut really! Original, clear and in depth.
    Thank you tut plus and authors, hope to see in the future more articles of this kind.

  • http://www.ryanmaurodesign.com Ryan Mauro

    I can’t tell you how excited I am to try this out! I’ve been looking for a way to implement an “infinite scrolling” function into my own themes without using a plugin for quite some time now. Thank you!

  • http://kg69design.com kg69design

    Really useful tutorial. But it will be very interesting for me to see a tutorial about filtering posts (with ajax) by category or tag (or even better – by customfields). For example, you have a select box on site with categories and when you change it – posts are filtered. It is very interesting for me how to deal with pagination in that case.

    • Federico

      Totally Agree!! I would also love reading a tutorial on that. Filtering posts with ajax based on diferent criterias on a form. Hope someone posts something like that.

      I think this tutorial should be the begining of a series on ajax. Thanks a lot for sharing.

      • DH

        You can create a new instance of WP_Query class instead of using query_posts(). That will give you more control over the loop. There are tons of parameters you can pass to filter the posts as you want. Check out the codex http://codex.wordpress.org/Class_Reference/WP_Query

  • http://twitter.com/drale2k Drazen Mokic

    Useful tutorial but please leave that “zoom-in/out” into the code every 2 seconds out, i had to skip that part because i got headache. The code is perfectly readable without zooming in and if you really have to zoom in then stay in the zoom for a while instead of jumping in and out.

    • Jerry Bates

      @Drazen – Thanks for the feedback; I happen to agree. Too late for us to address it in this tut, sadly, but future ones will handle the zoom a little more elegantly (and less frequently.)

  • http://kg69design.com kg69design

    I totally agree with Drazen Mokic, zoom in video is very annoying. It just “de-focus” from everything. But tha tutorial is great!

  • http://borayalcin.me bora yalçın

    Last year there was a post by Otto just about this including wp-load.php issue.

    He says (and when he talks about wordpress I believe him) “Don’t include wp-load, please.”
    here is the link to that article
    http://ottopress.com/2010/dont-include-wp-load-please/

    besides this issue, nice tutorial and thanks

    • Dennis Baskin
      Author

      Thank you for sharing, but if you read the article, you will see that the three reasons the author brings up of why its bad. The reasons listed were that you don’t know where wp-load is located, the fact that it doubles the load on the server, and that creating JavaScript on the server end is terrible.

      Since we are not generating a plugin here, we know where wp-load is located. We are setting the constant WP_USE_THEMES to false, so that there is no extra load. We are not generating JavaScript on the server side.

      I agree that there are other methods, but this was just one way.

  • Pingback: WordPress Community Roundup for the Week Ending December 17 - Charleston WordPress User Group

  • http://thomasgbennett.com Thomas

    Seems like wp-load is fine here. In general, can you use wp-load to allow other WP functions to work? (get_sidebar) for instance? Or is that a poor use?

    • Dennis Baskin
      Author

      I have not tried adding a sidebar through wp-load, but I am sure you should be able to use it just fine. The one thing I know is that we are not loading any themes, so you will not have any of your CSS styles available to you if you are using it outside of WordPress (I don’t think there’s a reason to use it within the wp framework).

      As far as what is proper and what is not, I believe that there are reasons which prompted the wordpress team to include wp-load. If a tool such as this exists, and it works, you can use it. You should always weigh your options of whether or not to use it. Consider load times, check to see if there is a better tool out there, and make sure it has not been deprecated or removed from the framework. If it is supported and it is your only choice to achieve your goal, then I do not see why you should not use it.

      There are many “purists” that claim to know what is best, but you should make that decision on your own after weighing your options. As much as I hate admitting it, but there have been times I had to use the !important statement in my CSS when working on an already created site and I had no access to change the original styling.

      Some people say PHP is a terrible language in general which shouldn’t be used, and I personally began to prefer c# recently myself, but I like PHP for when I need to use it. Its worth trying something out first and seeing if it works for you.

      Man, this reply turned into a ramble, I apologize. Anyhow, I hope that helped answer your question.

  • Dennis Baskin
    Author

    I just realized that I left console.log() statement in the scroll area. I went back to grab a piece of the code and saw it. Anyone trying this example in IE should omit or comment out that line for this example to work properly.

  • Pingback: Best of Tuts+ in December 2011 | SearchPsd Blog

  • Pingback: Best of Tuts+ in December 2011 | linuxin.ro

  • Pingback: Best of Tuts+ in December 2011 | Shadowtek | Hosting and Design Solutions

  • Pingback: Best of Tuts+ in December 2011

  • Pingback: Best of Tuts+ in December 2011 – blog

  • Pingback: Best of Tuts+ in December 2011 | Graphfucker

  • DH

    Good article guys!

    Although I agree that you should use functions.php and built-in tools for server-side scripting in this particular case. If you want to demonstrate a way of handling php files outside of WordPress it is better to do in a separate article.

    A couple of JS tips: window is a global object in client-side JavaScript not a DOM element and for your task quering body element is more appropriate than wrapping the whole window object.

    • Dennis Baskin
      Author

      Hi Dh,

      You are correct in that window is a global object not a DOM element, my mistake when I wrote it. By wrapping the window object, however, we do get the benefit of using the shortcut for binding on scroll using jQuery, as well as other jQuery functions.

      Thanks for the clarification. :)

  • Sam

    This is an awesome tutorial, thanks!

  • Pingback: My Stream » Best of Tuts+ in December 2011

  • Pingback: Best of Tuts+ in December 2011 | Wptuts+

  • Pingback: Ajax Powered WordPress Loops with jQuery » VC-TEL Team Blog

  • Ryan Mauro

    I’m applying this concept to a new template i’m developing (i.e. not a child of twentyeleven as in the tutorial), but I’ve run into a problem: I have no idea how to limit the usage of the Ajax loading. For example, if I create a single.php file with its query, a few posts from the loop in loopHandler show up at the bottom of the page. Where can I throw in a conditional statement ( like if (is_front_page()) { … } else { … } to limit the use of the Ajax loading to certain pages? This would be a huge help for me. Thanks!

    • Dennis
      Author

      If I understand you correctly, then I think you would have to look at the js file instead of just the php file.

  • Pingback: Best of Tuts+ in December 2011 | HowDoDesign

  • Pingback: Best of Tuts+ in December 2011 | cssWOW Showcase | Css Gallery | Css Awards | Design Inspiration Tutorials

  • John

    Any way to limit the amount of posts and have a load more button? If there’s a large number of posts, the site footer will be a hard thing to come by.

    • Dennis
      Author

      That’s a great idea John. All you need to do is wire up the function to only fire on a button click event, instead of the window scroll. Or allow to auto load on scroll for a limited amount and if that number is reached add / show a “load more” button and when it’s clicked allow the auto loading for another limited set.

  • Pingback: 16 Useful jQuery Tutorials to Enhance your WordPress Site

  • Pingback: 16 Useful jQuery Tutorials to Enhance your WordPress Site | WPhub.biz

  • http://youtube.com/izvarzone AntoxaGray

    The downside is, users can’t add bookmarks to pages, if they want to see older posts then will have to scroll down every time.

    • http://fittingsites.com Jerry Bates

      I’m pretty sure you could still bookmark a particular title by clicking on it’s title, which will take you to the post page. This just changes the loop behavior, but single articles are still created as usual in WordPress.

    • Dennis
      Author

      You right in thinking that. This tutorial does not keep history state. You will still be able to bookmark the individual page, but not your location in the blog roll. This tutorial is primarily aimed as an inspiration to something more with it. I do not personally think that it is ready for prime time if you only use just what this tutorial has, without adding to it. I think you bring up a good point though about history state with an Ajax blog …. Hmm maybe this should be revisited and revised, or furthered….

  • http://Www.leblogger.com Soufiane

    Can anyone give us a clue how to create similar Screenshots ???
    They are really awesome

    • http://youtube.com/izvarzone AntoxaGray

      Lens Blur filter in photoshop.

      • http://fittingsites.com Jerry Bates

        We did the screenshots in Photoshop, and the script we used to process the images started it’s life as a “toy camera” effect I found somewhere on the web. We modified the action to fit our needs, but basically it goes through a bunch of hoops… lens blur, camera noise, vignetting, and a slight sepia tone are all in the mix.

        Just search Google for photoshop actions that mimick old cameras or toy cameras. That should get you in the ballpark.

    • Soufiane

      Thanks for both answers :)

  • http://www.time7.com.br Gustavo Viegas

    But who wants to get to the bottom of the page? The important thing is to make you get more time browsing the site …. advantage is more important than getting to the bottom …

  • Gustavo

    how to implement in category page … does anyone know?

  • Pingback: 16 Useful jQuery Tutorials to Enhance your WordPress Site | Wordpress Themes

  • http://www.adamcrooker.com adamTheGr8t

    I’m trying to detect the number of posts and add a conditional statement in the jquery to stop the loop once all the posts have been loaded. How would I go about this? I positive it should take place in the window scroll call but unsure how to detect the total number of posts from the php core.

  • John

    Hi, do you have a solution when using facebook like/send/comments on this code? It does not work, my guess is Facebook is waiting for the DOM to load and then begins parsing the FBML. This is all fine an dandy except that when you make an AJAX call, this doesn’t cause the FBML to be re-parsed. But I don’t know how to implement that in AJAX :(

  • http://paulzaich.com Paul

    I’ve been able to successfully implement your tutorial but I’m having problems removing the loader when the posts run out. In the console, I keep getting an error: Syntax error, unrecognized expression: referencing the jquery file. The final get request returns blank html. Any ideas?

    • Dennis
      Author

      If you are seeing something like this, you can probably add a check in the success function to see if data is empty. For the error, did it give you any more details?

  • Pingback: WCKC | WordCamp Kansas City | Wordpress & AJAX

  • http://www.wpexplorer.com AJ Clarke

    that’s not really a good way to include wp-load.php – you should use wp_localize_script

    • Dennis
      Author

      Interesting. Just curious, how does this function relate to wp-load? I am under the impression that this just loads localized javascript files.

  • Michael

    This is an amazing tutorial, I can utilize this for many applications. I have one question though, is there any way to load the comments with the post? I tried adding comments_template() to the loop in the loopHandler.php with no luck. Any help would be greatly appreciated.

  • http://www.webentwickler-oase.de Philipp

    Great tutorial,
    i got the whole thing work after a lot of invested time in searching for this turorial.
    But, i dont get any CSS working in my loaded content, is their something to know :-) ???

    Thanks a lot

  • http://www.customicondesign.com/ CUSTOM ICON DESIGN

    very good example to the wordpress about jquery and ajax. I am using the same solution to solve my problem. but I dont understand “success : function(data){ $data = $(data);….” why using this. I think using data is enough. I use the $data = $(data) to my code, but failed, but I use data in my code, it’s correct. I dont know why it’s correct in your code. could you give me some suggestion?

  • http://www.zubzub.info Panagiotis

    Great start for ajax, but can someone tell me how to use WPML or qtranslate on these posts? I have WPML enabled but I only get the english posts and not my other languages. Which variable should I check?

  • http://movie-trailer.tv Nikesh Bhansali

    can this be used for calling multiple dropdown form elements to replace in query_posts args.

  • http://www.lesenfantsdelo.com/ Ness

    Hi!
    This is an awesome tutorial, thanks! I’m in the process of creating a new website and I’ll be using ajax powered loops, but I’m not sure what I need to achieve is doable…
    Maybe you can give me some pointers?
    I’m planning to do a wordpress blog with horizontal navigation, and a slide effect created with mootools. My point would be to have the user select a category, and his selection would be stored in a variable (I guess javascript). When he clicks on the category, it should initiate a wordpress loop to display the list of subcategories in this category, fetching the variable from javascript, but without reloading the page. Then, when the user clicks on a subcategory, same thing, but this time it displays a list of posts for this subcategory (still without reloading the page). And finally, when the user selects an article, it should appear on the side, still without any page refresh…
    So my question is : Do you think this can be done? I have no knowledge of ajax at the moment, but I’m used to working with php and actionscript, so I guess learning to use it wouldn’t be that hard.

  • http://www.lesenfantsdelo.com/ Ness

    Oh, and by the way, I tried the tutorial and I can’t get it to work… Nothing shows up in the content div. Is it compatible with the latest version of WordPress?
    I’ve double checked everything, and I can’t find what’s wrong.

    • http://www.lesenfantsdelo.com/ Ness

      After spending 2 hours on it with my boyfriend, redoing every step and watching the video three times to make sure I didn’t make a mistake following the tutorial, we found out that the ajaxLoop never reaches the success point, but I also don’t get any specific error message, only [object Object] :: error ::
      The data from loophandler probably never gets passed to the function, but I can’t understand why. Could you give me some pointers on where a mistake might have been made? loopHandler.php works (I tested it and it outputs the posts).

      • http://www.facebook.com/people/Vladimir-Andreev/100000653863185 Vladimir Andreev

        Had the same problem. Found, that I had written template name (for url of loopHandler.php) in lowercase, but there where used capital letters.
        so i changed “test” to “Test” and that was it.
        Sorry for poor english, hope it will help.

  • radiofranky

    Nice tutorial. I was wondering if you could help me to achieve this.
    I would like to create a menu tab in the #content block and loads list of posts from different categories when tabs are clicked.

    For example,

    [recent posts] [top 20] [most viewed posts]

    by default it will show 10 posts from “recent posts” and when user clicks on “top 20″ it will load the top 20(which I will have the loop for it) and so on for “most viewed posts”.

    Thanks for the help

  • Pingback: WordPress AJAX Tutorials - Jean Galea | Web Designer and Developer in Malta | WordPress Consultant

  • Mike

    Thanks for a great tutorial. Could someone give some pointers on how to get this to work on custom post type archives? No posts get pulled. If I specify the post type in the loop handler it works but I’d love to be able to use it on several custom post types.

    query_posts(array(
    ‘posts_per_page’ => $numPosts,
    ‘paged’ => $page,
    ‘post_type’ => ‘my_post_type’

    ));

    Any help would be greatly appreciated.
    Thanks.

  • http://www.simondelasalle.com Simon

    Hat’s off what an AWESOME tutorial!
    Thanks for saving me heaps of research!

  • http://www.mindinventory.com/android_application_development.php android apps development

    Lots of People are thinking that coding is very tough job,but Google is provide lots of help.You can easy your job searching online anythings,this tutorial is on of best example.

  • Johnray Strickland

    I know this is an older post, but no one has mentioned SEO. I notice that the content on load fades in, does that mean we are initially showing a blank or CSS hidden page to google?

  • http://www.facebook.com/rickleyten Rick Leijten

    Nice tutorial, but before I try it out.
    Does this also change the url on release? I havn’t seen this part in the tutorial.

  • http://twitter.com/willi828 willi828

    Nice tutorial. Too bad you have so many asking for “pointers.” :)

  • http://twitter.com/hamedhemmati Hamed Hemmati

    This is a great tutorial. I have got it working well but in my case I have two issues. The first issue is how do I do a prefill. Some times the content is smaller than the monitor resolution so it won’t load more unless I resize until I get a scrollbar.

    The second issue I have is that I use this inside of a div with horizontal scroll. How do I detect that I am at the end of the scroll.

  • http://twitter.com/Itsandyontheweb AndrewMorris

    I just get [object Object]:: error :: Not Found
    Anyone know what could be wrong?

  • http://twitter.com/noafmhd Naif Mohamed

    do i have to make any changes if i use this with a noon child theme. because i am not able to get it to work

  • Dennis
    Author

    This has been bugging me a bit: in the following code:

    $content.append('

    ');

    It really needs to be:

    $content.append('' +
    '' +
    '');

    Any time that you are writing multiline strings in javascript, you should not start the next line by terminating the last with the escape character, the slash. It just escapes a new line character (when you hit enter) but is bound for trouble if you add a space afterward. Always do it by concatenation instead.

    Sorry… Was just bothering me

    • Conor

      Hi Dennis, I’ve followed the tutorial but I can’t understand how the index page calls the functions. Theres nothing there, so I assume the #content id in the ajaxloop is the only way any connection is made, and with the script loaded, it is always checking for anything with an id of content. I can’t seem to get this working on a particular page on my site.

  • abhay

    i have facing problem in implementation. i have no return any value from loop handeler.php