plugin development - Return conditional category in load_posts_by_ajax

admin2025-06-02  1

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>
Share Improve this question edited Feb 27, 2019 at 13:48 Xavier C. asked Feb 27, 2019 at 12:32 Xavier C.Xavier C. 577 bronze badges
Add a comment  | 

1 Answer 1

Reset to default 1

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'];
}
转载请注明原文地址:http://conceptsofalgorithm.com/Algorithm/1748859496a314317.html

最新回复(0)