Как сделать, чтобы пагинация и фильтрация работали вместе?
Фильтрация по дате и пагинация отдельно работают вроде правильно. Но, после выбора даты и вывода записей в соответствие с ней, пагинация остается той же. И если после фильтрации нажать на пагинацию, то показываются соответственно записи без учета фильтрации по дате. Как это можно объединить? Чтобы после фильтрации по дате пагинация обновлялась и учитывались параметры фильтра.
archive.php
<div class="news__content"> <div class="news__items" id="news-container"> <?php $args = array( 'post_type' => 'news', 'posts_per_page' => 12, 'paged' => get_query_var('paged') ? get_query_var('paged') : 1, ); $query = new WP_Query($args); if ($query->have_posts()) : while ($query->have_posts()) : $query->the_post(); ?> <a href="<?php the_permalink(); ?>" class="news__item"> <?php echo get_the_post_thumbnail($id, 'thumbnail', array('class' => 'news__item__img')); ?> <p class="news__item__date"><?php echo get_the_date('d.m.Y'); ?></p> <h3 class="news__item__title"><?php the_title(); ?></h3> <div class="news__descr"><?php echo mb_substr(strip_tags(get_the_excerpt()), 0, 80, 'UTF-8'); ?>...</div> </a> <?php endwhile; wp_reset_postdata(); else : echo ''; endif; ?> </div> <div class="news__pagination"> <?php $big = 999999; echo paginate_links(array( 'base' => str_replace($big, '%#%', esc_url(get_pagenum_link($big))), 'format' => '?paged=%#%', 'current' => $query->get('paged') ? $query->get('paged') : 1, 'total' => $query->max_num_pages, 'prev_text' => __('← '), 'next_text' => __(' →'), )); ?> </div> </div> <div class="news__archive"> <h3 class="news__archive__title">Архив новостей</h3> <?php $archive_query = new WP_Query(array( 'post_type' => 'news', 'posts_per_page' => -1, 'orderby' => 'date', 'order' => 'DESC', )); $archive_data = array(); while ($archive_query->have_posts()) : $archive_query->the_post(); $year = get_the_date('Y'); $month = get_the_date('m'); $archive_data[$year][$month] = date_i18n('F', mktime(0, 0, 0, $month, 1, $year)); endwhile; wp_reset_postdata(); foreach ($archive_data as $year => $months) : ?> <div class="archive-year"> <span class="year-toggle"><?php echo $year; ?></span> <div class="archive-months"> <?php foreach ($months as $monthNum => $monthName) : ?> <span class="month-link" data-year="<?php echo $year; ?>" data-month="<?php echo $monthNum; ?>"><?php echo $monthName; ?></span> <?php endforeach; ?> </div> </div> <?php endforeach; ?> </div> |
<div class="news__content"> <div class="news__items" id="news-container"> <?php $args = array( 'post_type' => 'news', 'posts_per_page' => 12, 'paged' => get_query_var('paged') ? get_query_var('paged') : 1, ); $query = new WP_Query($args); if ($query->have_posts()) : while ($query->have_posts()) : $query->the_post(); ?> <a href="<?php the_permalink(); ?>" class="news__item"> <?php echo get_the_post_thumbnail($id, 'thumbnail', array('class' => 'news__item__img')); ?> <p class="news__item__date"><?php echo get_the_date('d.m.Y'); ?></p> <h3 class="news__item__title"><?php the_title(); ?></h3> <div class="news__descr"><?php echo mb_substr(strip_tags(get_the_excerpt()), 0, 80, 'UTF-8'); ?>...</div> </a> <?php endwhile; wp_reset_postdata(); else : echo ''; endif; ?> </div> <div class="news__pagination"> <?php $big = 999999; echo paginate_links(array( 'base' => str_replace($big, '%#%', esc_url(get_pagenum_link($big))), 'format' => '?paged=%#%', 'current' => $query->get('paged') ? $query->get('paged') : 1, 'total' => $query->max_num_pages, 'prev_text' => __('← '), 'next_text' => __(' →'), )); ?> </div> </div> <div class="news__archive"> <h3 class="news__archive__title">Архив новостей</h3> <?php $archive_query = new WP_Query(array( 'post_type' => 'news', 'posts_per_page' => -1, 'orderby' => 'date', 'order' => 'DESC', )); $archive_data = array(); while ($archive_query->have_posts()) : $archive_query->the_post(); $year = get_the_date('Y'); $month = get_the_date('m'); $archive_data[$year][$month] = date_i18n('F', mktime(0, 0, 0, $month, 1, $year)); endwhile; wp_reset_postdata(); foreach ($archive_data as $year => $months) : ?> <div class="archive-year"> <span class="year-toggle"><?php echo $year; ?></span> <div class="archive-months"> <?php foreach ($months as $monthNum => $monthName) : ?> <span class="month-link" data-year="<?php echo $year; ?>" data-month="<?php echo $monthNum; ?>"><?php echo $monthName; ?></span> <?php endforeach; ?> </div> </div> <?php endforeach; ?> </div>
script.js
$(".archive-year .month-link").click(function () { var year = $(this).data("year"); var month = $(this).data("month"); var currentPage = 1; $("#news-container").html("<p>Loading...</p>"); $.ajax({ type: "POST", url: ajaxurl, data: { action: "get_news_by_month", year: year, month: month, page: currentPage, }, beforeSend: function () { $("#news-container").html("<p>Loading...</p>"); }, success: function (response) { $("#news-container").html(response); }, complete: function () {}, }); }); |
$(".archive-year .month-link").click(function () { var year = $(this).data("year"); var month = $(this).data("month"); var currentPage = 1; $("#news-container").html("<p>Loading...</p>"); $.ajax({ type: "POST", url: ajaxurl, data: { action: "get_news_by_month", year: year, month: month, page: currentPage, }, beforeSend: function () { $("#news-container").html("<p>Loading...</p>"); }, success: function (response) { $("#news-container").html(response); }, complete: function () {}, }); });
functions.php
function get_news_by_month() { $year = $_POST['year']; $month = $_POST['month']; $page = $_POST['page']; $args = array( 'post_type' => 'news', 'posts_per_page' => 12, 'paged' => $page, 'year' => $year, 'monthnum' => $month, ); $query = new WP_Query($args); if ($query->have_posts()) : while ($query->have_posts()) : $query->the_post(); ?> <a href="<?php the_permalink(); ?>" class="news__item"> <?php echo get_the_post_thumbnail($id, 'thumbnail', array('class' => 'news__item__img')); ?> <p class="news__item__date"><?php echo get_the_date('d.m.Y'); ?></p> <h3 class="news__item__title"><?php the_title(); ?></h3> <div class="news__descr"><?php echo mb_substr(strip_tags(get_the_excerpt()), 0, 80, 'UTF-8'); ?>...</div> </a> <?php endwhile; wp_reset_postdata(); else : echo 'No posts found'; endif; die(); } |
function get_news_by_month() { $year = $_POST['year']; $month = $_POST['month']; $page = $_POST['page']; $args = array( 'post_type' => 'news', 'posts_per_page' => 12, 'paged' => $page, 'year' => $year, 'monthnum' => $month, ); $query = new WP_Query($args); if ($query->have_posts()) : while ($query->have_posts()) : $query->the_post(); ?> <a href="<?php the_permalink(); ?>" class="news__item"> <?php echo get_the_post_thumbnail($id, 'thumbnail', array('class' => 'news__item__img')); ?> <p class="news__item__date"><?php echo get_the_date('d.m.Y'); ?></p> <h3 class="news__item__title"><?php the_title(); ?></h3> <div class="news__descr"><?php echo mb_substr(strip_tags(get_the_excerpt()), 0, 80, 'UTF-8'); ?>...</div> </a> <?php endwhile; wp_reset_postdata(); else : echo 'No posts found'; endif; die(); }
Дополнительно:
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопрос
Пагинация и фильтрация должны работать на одном и том же запросе. Сейчас у Вас фильтр по дате меняет набор записей, а пагинация остаётся старой, потому что ссылка на страницу не несёт параметр даты или AJAX-обработчик строит новый
WP_Queryбез выбранного фильтра.Нужно передавать выбранную дату вместе с номером страницы и на сервере каждый раз собирать один общий
$args: post type, paged, posts_per_page и date_query/meta_query/tax_query.$paged = max(1, absint($_POST['paged'] ?? 1)); $date = sanitize_text_field($_POST['date'] ?? ''); $args = [ 'post_type' => 'news', 'posts_per_page' => 12, 'paged' => $paged, ]; if ($date) { $args['date_query'] = [[ 'after' => $date . ' 00:00:00', 'before' => $date . ' 23:59:59', 'inclusive' => true, ]]; } $query = new WP_Query($args);
После вывода карточек пагинацию тоже нужно строить от этого же
$query, а не от глобального запроса. В AJAX-ответ удобно возвращать HTML карточек и HTML пагинации.На фронте при клике по странице берите номер страницы и отправляйте его вместе с текущими фильтрами:
$(document).on('click', '.news-pagination a', function (e) { e.preventDefault(); $.post(ajaxurl, { action: 'filter_news', paged: $(this).data('page'), date: $('#news-date').val() }, function (response) { $('#news-container').html(response.items); $('.news-pagination').html(response.pagination); }); });$(document).on('click', '.news-pagination a', function (e) { e.preventDefault(); $.post(ajaxurl, { action: 'filter_news', paged: $(this).data('page'), date: $('#news-date').val() }, function (response) { $('#news-container').html(response.items); $('.news-pagination').html(response.pagination); }); });
Если пагинация обычная, без AJAX, добавляйте фильтр в URL:
?news_date=2026-05-01&paged=2, а вpre_get_postsучитывайте этот параметр. Но смешивать “фильтр AJAX, пагинация обычная” не стоит: именно из-за этого состояние и теряется.