简体   繁体   中英

Filter posts by categories in Wordpress with ajax

so this can be duplicate but i can't find the same question. I have a big trouble that possibly have really small cause. I want to filter my custom post type posts by their category with ajax.

What it does is that when i want to filter by my categories that are created and assigned to posts, i have a blank response with no posts. No problems from javascript console, so i assume there is so problem with names of slugs/categories.

Can you please help and look at this with 'cold head'.

My custom post type and custom taxonomy registered:

add_action( 'init', 'blog_register' );   

function blog_register() {   

    $labels = array( 
        'name' => _x('Blog', 'post type general name'), 
        'singular_name' => _x('Blog', 'post type singular name'), 
        'add_new' => _x('Add New', 'work item'), 
        'add_new_item' => __('Add New Blog Item'), 
        'edit_item' => __('Edit Blog Item'), 
        'new_item' => __('New Blog Item'), 
        'view_item' => __('View Blog Item'), 
        'search_items' => __('Search Blog'), 
        'not_found' => __('Nothing found'), 
        'not_found_in_trash' => __('Nothing found in Trash'), 
        'parent_item_colon' => '',
        'taxonomies' => array ('categories')
    );   
    
    $args = array( 
        'labels' => $labels, 
        'public' => true, 
        'publicly_queryable' => true, 
        'show_ui' => true, 
        'query_var' => true, 
        'rewrite' => array( 'slug' => 'blog', 'with_front'=> false ), 
        'capability_type' => 'post', 
        'hierarchical' => true,
        'has_archive' => true,  
        'menu_position' => null, 
        'supports' => array('title','editor','thumbnail') 
    );   

    register_post_type( 'blog' , $args ); 

    register_taxonomy( 'categories', array('blog'), array(
        'hierarchical' => true, 
        'label' => 'Categories', 
        'singular_label' => 'Category', 
        'rewrite' => array( 'slug' => 'categories', 'with_front'=> false )
        )
    );

    register_taxonomy_for_object_type( 'categories', 'blog' ); // Better be safe than sorry
}
function filter_posts() {
    $catSlug = $_POST['categories'];
  
    $ajaxposts = new WP_Query([
      'post_type' => 'blog',
      'posts_per_page' => -1,
      'category_name' => $catSlug,
      'orderby'=> 'post_date', 
      'order' => 'desc',
    ]);
    $response = '';
  
    if($catSlug == '') {  
        $response .= get_template_part('template_parts/blog-item');
    } else {
        if($ajaxposts->have_posts()) {
          while($ajaxposts->have_posts()) : $ajaxposts->the_post();
            $response .= get_template_part('template_parts/blog-item');

          endwhile;
        } else {

            echo " ";
        }
    }
  
    echo $response;
    exit;
  
  }
  add_action('wp_ajax_filter_posts', 'filter_posts');
  add_action('wp_ajax_nopriv_filter_posts', 'filter_posts');

And here i have my js code:

jQuery(function($){
$('.cat-item').on('click', function() {
    $('.cat-item').removeClass('active');
    $(this).addClass('active');

    $.ajax({
      type: 'POST',
      url: '/wp-admin/admin-ajax.php',
      dataType: 'html',
      data: {
        action: 'filter_posts',
        category: $(this).data('slug'),
      },
      success: function(res) {
        $('.blog-listing .row').html(res);
      }
    })
  });
});

How i display my content:

<div class="blog-listing">
        <div class='row'>
            <?php if (have_posts()) : while (have_posts()) : the_post();  ?>
                <?php get_template_part('template-parts/blog-item'); ?>
            <?php endwhile; endif; ?>
        </div>
      </div>

There are few logical mistakes and wrong implement in your code.

  1. Since it's your custom taxonomy you can't use category_name , you'll have to work with tax_query
  2. You need to make proper validation and sanitize the input before processing with $_POST['categories']
  3. if ( $catSlug == '' ) doesn't make sense, need to rewrite in a good way.

Suggestion: Please add a prefix on your function and action name so that they could be unique and doesn't conflict with any other things. Prefix will also remind you that you added this custom thing and it's not from theme or any other plugin, it's your code.

Now Let's fix your code:

function filter_posts() {
    // Validate with isset and not empty then sanitize with sanitize_text_text also use wp_unslash.
    $cat_slug = isset( $_POST['categories'] ) && ! empty( $_POST['categories'] ) ? sanitize_text_field( wp_unslash( $_POST['categories'] ) ) : '';

    // Define query args in a variable, it will help us to add tax query conditionally.
    $query_args = array(
        'post_type'      => 'blog',
        'posts_per_page' => -1,
        'orderby'        => 'date',
        'order'          => 'DESC',
        'tax_query'      => array( 'AND' ),
    );

    // if category slug is not empty then add a tax query args in query.
    if ( ! empty( $cat_slug ) ) {
        $query_args['tax_query'] = array(
            'taxonomy' => 'categories',
            'field'    => 'slug',
            'operator' => '=',
            'terms'    => $cat_slug,
        );
    }

    // Run the query.
    $ajaxposts = new WP_Query( $query_args );

    // We will use ob functions to collect the buffered output.
    ob_start();

    // check if has posts.
    if ( $ajaxposts->have_posts() ) {

        // Loop through the posts.
        while ( $ajaxposts->have_posts() ) :

            $ajaxposts->the_post();

            // Get content.
            get_template_part( 'template_parts/blog-item' );

        endwhile;
    }

    wp_reset_postdata();

    $response = ob_get_clean();

    echo $response;

    exit;
}
add_action( 'wp_ajax_filter_posts', 'filter_posts' );
add_action( 'wp_ajax_nopriv_filter_posts', 'filter_posts' );

Note: When the category is empty we're fetching all the posts without a category.

I have not tested the code if you find any syntax or critical error after using the code, please let me know should that i could fix my answer and could fix the issue

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM