Вопрос или проблема
Я пытаюсь фильтровать посты по каскадному выпадающему меню категорий. Но когда я выбираю опцию из каскадного меню, он показывает все посты. Как я могу фильтровать ТОЛЬКО посты по выбранной опции?
Вот моя структура:
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-запрос не фильтрует записи по выбранной категории. Ваша реализация нуждается в некоторых доработках, чтобы отобразить только посты конкретной категории, выбранной в выпадающем списке.
Анализ проблемы
-
Отсутствие
tax_query
: В функции обработки AJAX-запросаajax_filter_get_posts
вы не добавили параметрtax_query
в массив$args
, что делает невозможным фильтрацию по таксономии. -
Идентификация категории: В вашем HTML-коде для выпадающего списка отсутствует правильное поведение для извлечения категории. Вы должны использовать атрибуты, чтобы получить слаг выбранной категории.
-
Правильный селектор: Убедитесь, что 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();
}
});
});
});
Заключение
Применив вышеуказанные изменения, вы сможете создать функциональный фильтр для постов на основе выбранной категории в каскадном выпадающем меню. Убедитесь, что все скрипты и стили подключены корректно. Это создаст более интерактивный пользовательский интерфейс и улучшит опыт пользователей на вашем сайте.