Hi there,
This is driving me a little crazy.
I’m developing a plugin to retrieve the next couple of posts using AJAX. Here’s the basic idea of what I’m trying to do:
Count the number of posts currently displayed;
Send an AJAX request to a plugin function get_more_posts;
get_more_posts() instantiates a WP_Query object using the AJAX data as its arguments;
get_more_posts() uses a function format_category_posts to convert the WP_Query object into a string of formated posts;
The string is echoed in the function;
The AJAX return is appended to the DOM.
Wordpress has its own (somewhat convoluted) method for handing AJAX calls (http://codex.wordpress.org/AJAX_in_Plugins):
Since Ajax is already built into the core WordPress administration screens, adding more administration-side Ajax functionality to your plugin is fairly straightforward…
Note: Unlike on the admin side, the ajaxurl javascript global does not get automatically defined for you, unless you have BuddyPress or another Ajax-reliant plugin installed. So instead of relying on a global javascript variable, use the tip suggested in the article 5 tips for using Ajax in WordPress and declare a javascript namespace object with its own property, ajaxurl. As the article suggests, use wp_localize_script() to make the URL available to your script, and generate it using this expression: admin_url(‘admin-ajax.php’)
Anyway, after a lot of searching and trying things out, I got a basic AJAX call working on the front end of my site using a plugin:
Plugin php code:
<?php
/*
Plugin Name: More Posts
Description: Get more posts using ajax
Version: 1.0
*/
add_action('wp_enqueue_scripts', 'add_more_posts_script'); //add plugin script;
function add_more_posts_script(){
if(!is_admin() && is_category()){
wp_enqueue_script('more-posts', plugins_url( '/js/more-posts.js' , __FILE__ ), array('jquery'), 1.0, true);
wp_localize_script('more-posts', 'more_posts', array('ajaxurl' => admin_url('admin-ajax.php'))); //create ajaxurl global for front-end AJAX call;
}
}
add_action('wp_ajax_more_posts', 'get_more_posts'); //fire get_more_posts on AJAX call for logged-in users;
add_action('wp_ajax_nopriv_more_posts', 'get_more_posts'); //fire get_more_posts on AJAX call for all other users;
function get_more_posts(){
echo "Hello World";
exit();
}
Plugin JS code:
jQuery(document).ready(function($){
$.ajax({
url: more_posts.ajaxurl,
type: "GET",
data: {
action: 'more_posts'
},
dataType: "html",
success: function(response){
alert(response);
}
});
});
At this point I have a working plugin, which makes an AJAX call, and alerts the response (Hello World);
Ok, next step:
I have a function in my functions.php file, which wraps posts in the required mark up. Here it is:
function format_category_posts($query, $i = 1){
$output = '';
if( $query->have_posts() ) while( $query->have_posts() ) : the_post();
$image = get_field('image');
switch($i % 7){
case 1:
$output .= '<div class="row">';
$class = 'third dark-box';
break;
case 2:
$class = 'third light-box';
break;
case 3:
$class = 'third dark-box';
break;
case 4:
$output .= '</div><div class="row">';
$class = 'two-thirds light-box';
break;
case 5:
$class = 'third dark-box';
break;
case 6:
$output .= '</div><div class="row">';
$class = 'half light-box';
break;
case 0:
$class = 'half dark-box';
break;
}
$output .= '<div class="col ' . $class .'">' . "\\r\
";
$output .= "\ <article>\\r\
";
if($image){
$output .= "\ \ " . '<div class="images">' ."\\r\
\ \ \ " . '<img src="' . $image['sizes']['large'] . '" alt="' . $image['alt'] . '" />' . "\\r\
\ \ </div>";
}
$output .= "\ \ " . '<div class="copy">' . "\\r\
";
$output .= "\ \ \ <header>\\r\
\ \ \ \ " . '<h2>' . get_the_title() . '</h2>' . "\\r\
\ \ \ </header>\\r\
";
$output .= "\ \ \ " . wpautop(get_the_excerpt()) . "\\r\
";
$output .= "\ \ </div>\\r\
";
$output .= "\ </article>\\r\
";
$output .= "</div>";
if($i == (int)$query->found_posts || $i % 7 == 0) $output .= '</div>';
$i++; endwhile;
return $output;
}
So I amend my get_more_posts function:
function get_more_posts(){
$args = $_GET;
unset($args['action']);
$more_posts_query = new WP_Query($args);
echo format_category_posts($more_posts_query);
exit();
}
and the javascript:
jQuery(document).ready(function($){
var offset = $('article').length;
$.ajax({
url: more_posts.ajaxurl,
type: "GET",
data: {
action: 'more_posts',
posts_per_page: 3,
offset: offset
},
dataType: "html",
success: function(response){
alert(response);
}
});
});
So I’m expecting to get an alert box containing 3 posts wrapped in HTML tags, ready for insertion into the DOM. And I get… nothing.
If I check the Network tab on console, the AJAX call takes about a minute to respond, and sends around 70MB of data.
If I var_dump the WP_Object in get_more_posts, the AJAX will happily return an object with 3 posts in it.
If I var_dump(function_exists(‘format_category_posts’)), I get bool(true) as the response.
I use the format_category_posts on my category.php script, so I know the function works as expected.
I’m totally at a loss. Does anyone have any ideas?
Thanks in advance,
Mike