дублирующие посты с ajax загрузкой еще в WordPress

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

У меня на сайте реализована загрузка постов с помощью ajax при прокрутке. Проблема заключается в появлении дубликатов постов. Я не могу понять, почему это происходит. Дубликаты есть только у некоторых постов. Вот мой код в function.php:

function loadmore_get_posts(){
  $paged = !empty($_POST['paged']) ? $_POST['paged'] : 1;
  $paged++;

  $args = array(
    'paged' => $paged,
    'posts_per_page' => $_POST['posts_per_page'],
    'post_type'      => 'post',
    'post_status' => 'publish',
    'cat' => $_POST['cats']
    );

  query_posts($args);
 
  while( have_posts() ) : the_post();
    get_template_part( 'this is template' );    
  endwhile;
  die;
}
add_action('wp_ajax_loadmore', 'loadmore_get_posts');
add_action('wp_ajax_nopriv_loadmore', 'loadmore_get_posts');

И это ajax на чистом javascript:

let ajaxurl="<?php echo admin_url("admin-ajax.php') ?>';
let section_posts = 1;
let postData = new FormData();

postData.append('action', 'loadmore');
postData.append('paged', section_posts);
postData.append('posts_per_page', 9);
postData.append('cats',  <?php print json_encode(get_selected_cats())?>);

  const xhr = new XMLHttpRequest();
  xhr.open('POST', ajaxurl);

  xhr.addEventListener('readystatechange', function (data) {
  if (this.readyState === 4 && this.status === 200) {
     section_posts++;
     document.querySelector('.articlefeed_template').innerHTML += data.target.responseText;
  } else {}
     xhr.send(postData);
  }

Пожалуйста, подскажите, что я делаю не так? Спасибо!

Во-первых, ваш параметр cat ожидает массив, а вы передаете ему json-строку… Вам нужно использовать json_decode, чтобы преобразовать вашу строку обратно в массив постов для выполнения запроса.

Во-вторых, вы используете query_posts(), о чем на странице документации написано:

Примечание: Эта функция полностью переопределяет основной запрос и не предназначена для использования плагинами или темами. Ее слишком упрощенный подход к изменению основного запроса может вызвать проблемы и должен быть избегнут, где это возможно. В большинстве случаев существуют лучшие, более производительные варианты для изменения основного запроса, такие как действие ‘pre_get_posts’ в WP_Query.

Эта функция не должна использоваться внутри цикла WordPress.

Поэтому исправьте проблемы с параметром cat и используйте get_posts() или WP_Query здесь, и я был бы очень удивлен, если у вас все еще останутся проблемы.

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

Конечно! Давайте разберем вашу проблему с дублирующимися записями при использовании AJAX для загрузки постов в WordPress.

Основные проблемы:

  1. Параметр cat: Вы передаете строку в качестве категории, а не массив. WP_Query ожидает массив идентификаторов категорий. Вам нужно декодировать JSON и передать массив.

  2. Использование query_posts(): Эта функция не рекомендуется к использованию в плагинах или темах, так как она изменяет основной запрос WordPress, что может привести к непредсказуемым последствиям, включая дублирование постов. Вместо этого лучше использовать WP_Query или get_posts().

Исправление вашего кода:

Обновите ваш код в functions.php следующим образом:

function loadmore_get_posts() {
    $paged = !empty($_POST['paged']) ? $_POST['paged'] : 1;
    $paged++;

    $cats = json_decode(stripslashes($_POST['cats'])); // Декодируем JSON строку в массив

    // Параметры запроса
    $args = array(
        'paged'          => $paged,
        'posts_per_page' => $_POST['posts_per_page'],
        'post_type'      => 'post',
        'post_status'    => 'publish',
        'category__in'   => $cats // Используем category__in для массива категорий
    );

    // Используем WP_Query
    $query = new WP_Query($args);

    // Проверяем, есть ли посты
    if ($query->have_posts()) :
        while ($query->have_posts()) : $query->the_post();
            get_template_part('this is template'); // Замените на ваш шаблон
        endwhile;
        wp_reset_postdata(); // Сбрасываем данные
    else :
        // Если постов нет, можно обработать это
        echo 'Нет постов для отображения.';
    endif;

    die; // Завершение работы
}
add_action('wp_ajax_loadmore', 'loadmore_get_posts');
add_action('wp_ajax_nopriv_loadmore', 'loadmore_get_posts');

Изменения в AJAX запросе (JavaScript):

Убедитесь, что в вашем JavaScript коде не происходит изменений, которые могут потенциально вызвать дублирование. Ниже приведен пример правильной обработки:

let ajaxurl = "<?php echo admin_url('admin-ajax.php'); ?>";
let section_posts = 1;
let postData = new FormData();

postData.append('action', 'loadmore');
postData.append('paged', section_posts);
postData.append('posts_per_page', 9);
postData.append('cats', JSON.stringify(<?php print json_encode(get_selected_cats()); ?>)); // Убедитесь, что cats - это массив

const xhr = new XMLHttpRequest();
xhr.open('POST', ajaxurl);

xhr.addEventListener('readystatechange', function () {
    if (this.readyState === 4 && this.status === 200) {
        section_posts++;
        document.querySelector('.articlefeed_template').innerHTML += this.responseText; // Корректный код для добавления данных
    }
 });

xhr.send(postData);

Заключение

Следуя этим исправлениям, вы устраните проблему с дублирующимися постами. Использование WP_Query вместо query_posts() обеспечит более стабильную и предсказуемую работу вашего кода. Если после этих коррекций дублирование сохранится, убедитесь, что ваши категории правильно установлены и что AJAX запросы выполняются корректно.

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

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