I created a shortcode returning the three last articles, and i set an attribute that lets me chose the category depending on the page i'm on.
function return_actu_home($atts) {
ob_start();
extract( shortcode_atts( array(
'category' => ''
), $atts ) );
$args = array(
'post_type' => 'post',
'posts_per_page' => 3,
'order' => 'DESC',
'paged' => 1
);
if ( ! empty( $category ) ) {
$args['category_name'] = $category;
}
$jp_query = new WP_Query($args);
if($jp_query->have_posts()) {
echo '<div class="container">
<div class="row pt-3 stjp2-posts">';
while ($jp_query->have_posts() ) : $jp_query->the_post();
get_template_part( 'template-parts/content', get_post_format() );
endwhile;
echo '</div>
<div class="spinner hidden text-center" role="status">';
get_template_part('img/inline', 'dna.svg');
echo '</div>
<div class="loadmore p-2 px-3 mx-auto museo-700">Voir plus dʼactus</div>
</div>';
wp_reset_query();
}
return ob_get_clean();
}
add_shortcode('actu_home', 'return_actu_home');
Works great. Then i add a load more button and call posts with load_post_by_ajax
add_action('wp_ajax_load_posts_by_ajax', 'load_posts_by_ajax_callback');
add_action('wp_ajax_nopriv_load_posts_by_ajax', 'load_posts_by_ajax_callback');
//Load more CallBack
function load_posts_by_ajax_callback() {
check_ajax_referer('load_more_posts', 'security');
$paged = $_POST['page'];
$args = array(
'post_type' => 'post',
'posts_per_page' => '3',
'paged' => $paged,
'cat' => $catid,
);
$my_posts = new WP_Query( $args );
ob_start();
if ( $my_posts->have_posts() ) : while ( $my_posts->have_posts() ) : $my_posts->the_post();
get_template_part( 'template-parts/content-alt', get_post_format() );
endwhile;
endif;
wp_die();
return ob_get_clean();
}
Working great too, except that obviously, it loads posts from all categories. I suppose it is not possible to return the attribute from the shortcode, so i tried to create a conditional statement to change the $catid variable
if(is_page(14)) {
$catid = '4';
}
But this does not work because it runs outside the loop.
Have been scratching my head around this for some time, any ideas appreciated.
Here is the AJAX part
<script>
var ajaxurl = "<?php echo admin_url( 'admin-ajax.php' ); ?>";
var page = 2;
jQuery(function($) {
$('body').on('click', '.loadmore', function() {
var data = {
'action': 'load_posts_by_ajax',
'page': page,
'security': '<?php echo wp_create_nonce("load_more_posts"); ?>'
};
$('.spinner').show();
$.post(ajaxurl, data, function(response) {
$('.stjp2-posts').append(response);
page++;
$('.spinner').hide();
timeout = setTimeout(function () {
$('.frame').removeClass('article-hidden');
}, 50);
});
});
});
</script>
I created a shortcode returning the three last articles, and i set an attribute that lets me chose the category depending on the page i'm on.
function return_actu_home($atts) {
ob_start();
extract( shortcode_atts( array(
'category' => ''
), $atts ) );
$args = array(
'post_type' => 'post',
'posts_per_page' => 3,
'order' => 'DESC',
'paged' => 1
);
if ( ! empty( $category ) ) {
$args['category_name'] = $category;
}
$jp_query = new WP_Query($args);
if($jp_query->have_posts()) {
echo '<div class="container">
<div class="row pt-3 stjp2-posts">';
while ($jp_query->have_posts() ) : $jp_query->the_post();
get_template_part( 'template-parts/content', get_post_format() );
endwhile;
echo '</div>
<div class="spinner hidden text-center" role="status">';
get_template_part('img/inline', 'dna.svg');
echo '</div>
<div class="loadmore p-2 px-3 mx-auto museo-700">Voir plus dʼactus</div>
</div>';
wp_reset_query();
}
return ob_get_clean();
}
add_shortcode('actu_home', 'return_actu_home');
Works great. Then i add a load more button and call posts with load_post_by_ajax
add_action('wp_ajax_load_posts_by_ajax', 'load_posts_by_ajax_callback');
add_action('wp_ajax_nopriv_load_posts_by_ajax', 'load_posts_by_ajax_callback');
//Load more CallBack
function load_posts_by_ajax_callback() {
check_ajax_referer('load_more_posts', 'security');
$paged = $_POST['page'];
$args = array(
'post_type' => 'post',
'posts_per_page' => '3',
'paged' => $paged,
'cat' => $catid,
);
$my_posts = new WP_Query( $args );
ob_start();
if ( $my_posts->have_posts() ) : while ( $my_posts->have_posts() ) : $my_posts->the_post();
get_template_part( 'template-parts/content-alt', get_post_format() );
endwhile;
endif;
wp_die();
return ob_get_clean();
}
Working great too, except that obviously, it loads posts from all categories. I suppose it is not possible to return the attribute from the shortcode, so i tried to create a conditional statement to change the $catid variable
if(is_page(14)) {
$catid = '4';
}
But this does not work because it runs outside the loop.
Have been scratching my head around this for some time, any ideas appreciated.
Here is the AJAX part
<script>
var ajaxurl = "<?php echo admin_url( 'admin-ajax.php' ); ?>";
var page = 2;
jQuery(function($) {
$('body').on('click', '.loadmore', function() {
var data = {
'action': 'load_posts_by_ajax',
'page': page,
'security': '<?php echo wp_create_nonce("load_more_posts"); ?>'
};
$('.spinner').show();
$.post(ajaxurl, data, function(response) {
$('.stjp2-posts').append(response);
page++;
$('.spinner').hide();
timeout = setTimeout(function () {
$('.frame').removeClass('article-hidden');
}, 50);
});
});
});
</script>
The AJAX handler doesn't know anything about the page or context that the request was made from, so you're going to need to send the category along with AJAX request, alongside the page number.
So you're going to need to store the category name somewhere in the shortcode output, and then retrieve that with your JavaScript when sending the request. A data-
attribute on the load more button would be a relatively straightforward way to do this:
'<div class="loadmore p-2 px-3 mx-auto museo-700" data-category="' . esc_attr( $category ) . '">Voir plus dʼactus</div>'
(Please consider making this a proper button element)
You haven't included your JavaScript in the question, so I can't make direct edits, but it would look something like this:
jQuery( '.loadmore' ).click( function( e ) {
e.preventDefault();
var $button = jQuery( this );
var category = $button.data( 'category' ); // <-- Important bit.
// Figure out page number etc.
jQuery.post( {
// Set URL, success handler, etc.
data: {
action: 'load_posts_by_ajax',
page: page,
category: category, // <-- Important bit.
}
} )
} );
(This type of request should really be a GET
, not a POST
.)
And then in your AJAX handler, use the passed value the same way you do in your original query:
if ( ! empty( $_POST['category'] ) ) {
$args['category_name'] = $_POST['category'];
}