Как сделать, чтобы пагинация и фильтрация работали вместе?

Ссылка скопирована
1 ответ

Фильтрация по дате и пагинация отдельно работают вроде правильно. Но, после выбора даты и вывода записей в соответствие с ней, пагинация остается той же. И если после фильтрации нажать на пагинацию, то показываются соответственно записи без учета фильтрации по дате. Как это можно объединить? Чтобы после фильтрации по дате пагинация обновлялась и учитывались параметры фильтра.

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(); }

Дополнительно:

Нужно решить такую задачу?

Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.

Заказать помощь
Лучший ответ
1
Сергей Миронов Ответ

Пагинация и фильтрация должны работать на одном и том же запросе. Сейчас у Вас фильтр по дате меняет набор записей, а пагинация остаётся старой, потому что ссылка на страницу не несёт параметр даты или 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);

$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, пагинация обычная” не стоит: именно из-за этого состояние и теряется.

Другие ответы (0)

Пока нет других ответов. Будьте первым, кто поможет автору.

Ответить на вопрос

комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Вам также может быть интересно