Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

What's the best way to fetch the next page in post archives and other lists like search results?

This question has been asked many times already, but the answers not good enough for me. So far, I've found two ways of doing it.

  1. Using an AJAX request to the standard URL (like example.com/category/mycat/page/2). This is done using the $.load function of JQuery which strips the result leaving only the contents of some block with the specified id. I believe this is inefficient both for the client (because unnecessary content is loaded and processed) and for the server (because such a request processes menus, widgets, etc., that are not needed).

  2. With a custom ajax handler using the add_action function. The big problem with this option is that the handler is not universal! It circumvents the normal query parsing, creating a custom WP_Query object instead. Clearly, this is not the way.

I am considering the following:

  1. Register a query variable that would make the template display the page in JSON format and make a request like so: example.com/category/mycat/page/2?showjson=true. In the theme check for this variable and adjust output accordingly.

  2. Get query_vars and using wp_localize_script pass them to the script. Then make the AJAX call with these variables and handle them appropriately. (Basically, this would be a beefed-up version of option 2 above).

Then maybe there is some other way of doing this?

ADDED: Making a custom handler could be potentially used to improve performance, as not all of Wordpress needs to be loaded.

share|improve this question

1 Answer 1

up vote 1 down vote accepted

I ended up modifying the archive.php file to serve different content when requested normally and via ajax.

if ((isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest')) {
    $response = array();
    $response['posts'] = '';
    if (have_posts()) {
        ob_start();
        while (have_posts()) {
            the_post();
            get_template_part('content');
        }
        $response['posts'] .= ob_get_clean();
    } else {
        //no posts
        $response['posts'] .= 'nothing';
    }
    echo json_encode($response);
} else {    
    //normal template code here
}

After that, getting items via JS is easy:

$.ajax ({
    type: "GET",
    url: more_ajax_url,
    data: {},
    dataType: 'json',
    success: function (result) {
        $('#archive_container').append(result.items);
    }
});

There is also some code to pass the link to the next page, but that should not be hard to implement.

The advantage of this method is that the request is fully processed by wordpress and all its filters and actions. And it is much better than the $.load, because no unnecessary data is passed from the server.

share|improve this answer

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.