Вопрос или проблема
У меня на сайте реализована загрузка постов с помощью 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.
Основные проблемы:
-
Параметр
cat
: Вы передаете строку в качестве категории, а не массив.WP_Query
ожидает массив идентификаторов категорий. Вам нужно декодировать JSON и передать массив. -
Использование
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 запросы выполняются корректно.