Фильтр сообщений по категориям ajax показывает все сообщения.

Вопрос или проблема

Я пытаюсь фильтровать посты по каскадному выпадающему меню категорий. Но когда я выбираю опцию из каскадного меню, он показывает все посты. Как я могу фильтровать ТОЛЬКО посты по выбранной опции?

Вот моя структура:

Functions.php

    function ajax_filter_posts_scripts() {
  // Подключение скрипта
  wp_register_script('afp_script', get_template_directory_uri() . '/assets/js/ajax-filter-posts.js', false, null, false);
  wp_enqueue_script('afp_script');

  wp_localize_script( 'afp_script', 'afp_vars', array(
        'afp_nonce' => wp_create_nonce( 'afp_nonce' ), // Создание nonce, который мы позже будем использовать для проверки AJAX-запроса
        'afp_ajax_url' => admin_url( 'admin-ajax.php' ),
      )
  );
}
add_action('wp_enqueue_scripts', 'ajax_filter_posts_scripts', 100);

// Скрипт для получения постов
function ajax_filter_get_posts( $taxonomy ) {

  // Проверка nonce
  if( !isset( $_POST['afp_nonce'] ) || !wp_verify_nonce( $_POST['afp_nonce'], 'afp_nonce' ) )
    die('Доступ запрещен');

  $taxonomy = $_POST['taxonomy'];

  // WP Query
    $args = array(
    'exclude' => '1,2,4,5,7,8,9,10,11,12',
    'post_type' => 'post',
    'nopaging' => true, // показывать все посты сразу
    );
  echo $taxonomy;
  // Если таксономия не установлена, удалите ключ из массива и получите все посты
  if( !$taxonomy ) {
    unset( $args['tag'] );
  }

  $query = new WP_Query( $args );

  if ( $query->have_posts() ) : while ( $query->have_posts() ) : $query->the_post(); ?>
      <div class="col-md-4">
        <div class="img-thumb">
            <a href="https://wordpress.stackexchange.com/questions/260141/<?php the_field("link_do_case'); ?>">
                <?php the_post_thumbnail(); ?>      
            </a>                                                                    
        </div>
        <small><?php the_title(); ?></small>
    </div>

  <?php endwhile; ?>
  <?php else: ?>
    <h2>Кейс не найден</h2>
  <?php endif;

  die();
}

add_action('wp_ajax_filter_posts', 'ajax_filter_get_posts');
add_action('wp_ajax_nopriv_filter_posts', 'ajax_filter_get_posts');

Вот мой скрипт

jQuery(document).ready(function(jQuery) {
    jQuery('.post-tags select').on('change', function(event) {
        console.log('изменилось');
        // Предотвращаем действие по умолчанию - открытие страницы тега
        if (event.preventDefault) {
            event.preventDefault();
        } else {
            event.returnValue = false;
        }

        // Получаем slug тега из атрибута title
        var selecetd_taxonomy = jQuery(this).attr('title');

        // После того, как пользователь нажимает на тег, скрываем список постов
        jQuery('.tagged-posts').fadeOut();

        data = {
            action: 'filter_posts', // функция для выполнения
            afp_nonce: afp_vars.afp_nonce, // wp_nonce
            taxonomy: selecetd_taxonomy, // выбранный тег
            };

        jQuery.post( afp_vars.afp_ajax_url, data, function(response) {

            if( response ) {
                // Отображаем посты на странице
                jQuery('.tagged-posts').html( response );
                // Восстанавливаем видимость div
                jQuery('.tagged-posts').fadeIn();
            };
        });
    });
});

А вот и моя структура страницы

<div id="ajax-cases">
<?php
    // WP Query
    $args = array(
    'post_type' => 'post',
    'exclude' => '1,2,4,5,7,8,9,10,11',
    'post_status' => 'publish',
    'nopaging' => true, // показывать все посты сразу
    );
   $query = new WP_Query( $args );
   $tax = 'category';
   $terms = get_terms( $tax, $args);
   $count = count( $terms );

    if ( $count > 0 ): ?>
        <div class="post-tags">
            <h2>Ищите по типу Работы</h2>
            <?php
            echo '<select>';
                foreach ( $terms as $term ) {
                    $term_link = get_term_link( $term, $tax ); 
                    echo '<option value="' . $term_link . '" class="tax-filter">' . $term->name . '</option> ';

                }
            echo '</select>';
             ?>
        </div>
    <?php endif ;?>
    <div class="tagged-posts">
      // здесь должны отображаться посты, выбранные через опцию категории
    </div>              

В вашем коде я нашел 2 проблемы:

1) В вашей AJAX-функции ajax_filter_get_posts() вы пропустили tax_query в своих аргументах.

Ваша AJAX-функция ajax_filter_get_posts() должна выглядеть следующим образом:

function ajax_filter_get_posts( $taxonomy ) {

 // Проверка nonce
 if( !isset( $_POST['afp_nonce'] ) || !wp_verify_nonce( $_POST['afp_nonce'], 'afp_nonce' ) )
   die('Доступ запрещен');

 $taxonomy = $_POST['taxonomy'];

 // WP Query
   $args = array(
   'exclude' => '1,2,4,5,7,8,9,10,11,12',
   'post_type' => 'post',
   'nopaging' => true, // показывать все посты сразу
   );
 echo $taxonomy;
 // Если таксономия не установлена, удалите ключ из массива и получите все посты
 if( !$taxonomy ) {
   unset( $args['tag'] );
 }else{
   // Это код, который вы пропустили. Вам нужно добавить запрос таксономии, если таксономия установлена.
   $arg['tax_query']= array(
     array(
       'taxonomy' => 'category',
       'field' => 'slug',
       'terms' => array( $taxonomy ),
       'include_children' => true, // установите true, если хотите посты его дочерней категории тоже
       'operator' => 'IN'
           ),
   );
 }

 $query = new WP_Query( $args );

 if ( $query->have_posts() ) : while ( $query->have_posts() ) : $query->the_post(); ?>
     <div class="col-md-4">
       <div class="img-thumb">
           <a href="https://wordpress.stackexchange.com/questions/260141/<?php the_field("link_do_case'); ?>">
               <?php the_post_thumbnail(); ?>      
           </a>                                                                    
       </div>
       <small><?php the_title(); ?></small>
   </div>

 <?php endwhile; ?>
 <?php else: ?>
   <h2>Кейс не найден</h2>
 <?php endif;

 die();
}

2) На вашей странице структуры замените строку ссылки тега на следующую строку:

echo '<option value="' . $term_link . '" class="tax-filter" title="'.$term->slug.'">' . $term->name . '</option> ';

3) В вашем jQuery измените способ получения значения выбранной таксономии:

var selecetd_taxonomy = jQuery(this).find('option:selected').attr("title");

Внесите вышеуказанные 3 изменения, и вы получите посты только выбранной категории.

Надеюсь, это поможет вам.

В вашем jQuery у вас есть jQuery('.post-tags select').on('change', function(event) {, но когда я смотрю на исходный код вашей страницы, выпадающее меню – это <select id="dropdown_select" class="dropdown_options">, я не думаю, что ваш скрипт отслеживает правильный элемент. Попробуйте исправить это вместе с другим ответом и посмотрите, принесет ли это результат.

Ответ или решение

Основная проблема, с которой вы столкнулись, заключается в том, что ваш AJAX-запрос не фильтрует записи по выбранной категории. Ваша реализация нуждается в некоторых доработках, чтобы отобразить только посты конкретной категории, выбранной в выпадающем списке.

Анализ проблемы

  1. Отсутствие tax_query: В функции обработки AJAX-запроса ajax_filter_get_posts вы не добавили параметр tax_query в массив $args, что делает невозможным фильтрацию по таксономии.

  2. Идентификация категории: В вашем HTML-коде для выпадающего списка отсутствует правильное поведение для извлечения категории. Вы должны использовать атрибуты, чтобы получить слаг выбранной категории.

  3. Правильный селектор: Убедитесь, что JavaScript код правильно отслеживает изменения в нужном элементе.

Рекомендации по исправлению

1. Измените функцию ajax_filter_get_posts

Для фильтрации записей по таксономии вам нужно добавить массив tax_query в ваш WP_Query. Вот обновлённая версия кода функции:

function ajax_filter_get_posts() {
    // Проверка nonce
    if (!isset($_POST['afp_nonce']) || !wp_verify_nonce($_POST['afp_nonce'], 'afp_nonce')) {
        die('Permission denied');
    }

    $taxonomy = $_POST['taxonomy']; // Получение значения из запроса

    // WP Query
    $args = array(
        'post_type' => 'post',
        'exclude' => '1,2,4,5,7,8,9,10,11,12',
        'nopaging' => true,
    );

    // Добавление tax_query, если категория выбрана
    if ($taxonomy) {
        $args['tax_query'] = array(
            array(
                'taxonomy' => 'category',
                'field' => 'slug', // используем slug для фильтрации
                'terms' => array($taxonomy),
                'include_children' => true, // Включить дочерние категории
                'operator' => 'IN'
            ),
        );
    }

    $query = new WP_Query($args);

    if ($query->have_posts()) :
        while ($query->have_posts()) : $query->the_post(); ?>
            <div class="col-md-4">
                <div class="img-thumb">
                    <a href="<?php the_field("link_do_case"); ?>">
                        <?php the_post_thumbnail(); ?>
                    </a>                                                                    
                </div>
                <small><?php the_title(); ?></small>
            </div>
        <?php endwhile; ?>
    <?php else: ?>
        <h2>Записи не найдены</h2>
    <?php endif;

    wp_reset_postdata(); // Сбрасываем пост данные
    die();
}

add_action('wp_ajax_filter_posts', 'ajax_filter_get_posts');
add_action('wp_ajax_nopriv_filter_posts', 'ajax_filter_get_posts');

2. Убедитесь, что выпадающий список правильно получает слаг

В вашем HTML-коде измените строку для добавления атрибута title, чтобы он содержал слаг:

echo '<option value="' . esc_attr($term_link) . '" class="tax-filter" title="' . esc_attr($term->slug) . '">' . esc_html($term->name) . '</option>';

3. Обновите JavaScript код

Теперь убедитесь, что вы правильно получаете выбранный слаг из вашего выпадающего списка:

jQuery(document).ready(function($) {
    $('.post-tags select').on('change', function(event) {
        event.preventDefault();

        // Получаем слаг выбранной категории
        var selected_taxonomy = $(this).find('option:selected').attr('title');

        // Скрываем список записей
        $('.tagged-posts').fadeOut();

        var data = {
            action: 'filter_posts',
            afp_nonce: afp_vars.afp_nonce,
            taxonomy: selected_taxonomy
        };

        $.post(afp_vars.afp_ajax_url, data, function(response) {
            if (response) {
                $('.tagged-posts').html(response).fadeIn();
            }
        });
    });
});

Заключение

Применив вышеуказанные изменения, вы сможете создать функциональный фильтр для постов на основе выбранной категории в каскадном выпадающем меню. Убедитесь, что все скрипты и стили подключены корректно. Это создаст более интерактивный пользовательский интерфейс и улучшит опыт пользователей на вашем сайте.

Оцените материал
Добавить комментарий

Капча загружается...