Почему дублируются новости при выводе постов через ajax wp?
Создал страницу и накатил туда вывод определенных постов, добавил пагинацию + ajax. Вопрос, при клике на кнопку просто новости дублируются, подскажите что сделал не так? А так же как сделать динамическую пагинацию? а то при показать еще, остается такой какой и был
Вывожу посты так
<?php
$paged = (get_query_var('paged')) ? get_query_var('paged') : ((get_query_var('page')) ? get_query_var('page') : 1);
$posts = new WP_Query(array(
"post_type" => "post", # post, page, custom_post_type
"post_status" => "publish", # статус записи
"posts_per_page" => 3, # кол-во постов вывода/загрузки
"category_name" => "news",
'orderby' => 'date',
)); ?>
<?php if ($posts->have_posts()) : ?>
<?php while ($posts->have_posts()) : $posts->the_post(); ?>
<a class="col-md-4" href="<?php the_permalink(); ?>">
<div class="news-card">
<div class="thumbnail img__post" >
<?php echo get_the_post_thumbnail(); ?>
</div>
<div class="meta">
<div class="date"><?php echo get_the_date('d F Y'); ?></div>
<div class="view">
<i class="fa fa-eye" aria-hidden="true"></i>
<?php echo getPostViews(get_the_ID()); ?>
</div>
</div>
<div class="block">
<h3 class="posts-title"><?php the_title(); ?></h3>
</div>
<!--здесь выводится миниатюра записи-->
<?php the_content(); ?>
</div></a>
<?php endwhile; ?>
<?php endif; ?>
<?php // AJAX загрузка постов
if ($posts->max_num_pages > 1) { ?>
<script>
var current_page = 1;
</script>
<button
type="button"
class="btn--load"
data-param-posts='<?= json_encode($posts->query_vars); ?>'
data-max-pages="<?= $posts->max_num_pages; ?>"
data-tpl="portfolio"
>
Загрузить ещё
</button>
<?php } ?>
<?php post_pagination($paged, $posts->max_num_pages);
?>
<?
wp_reset_postdata(); ?>
js
jQuery(function ($) {
$(".btn--load").on("click", function () {
const button = $(this);
button.html("Загрузка...");
const data = {
"action": "load_more",
"query": button.data("param-posts"),
"page": current_page,
"tpl": button.data("tpl")
}
$.ajax({
url: "/wp-admin/admin-ajax.php",
data: data,
type: "POST",
success: function (data) {
if (data) {
button.html("Загрузить ещё");
button.prev().prev().after(data);
current_page++;
if (current_page == button.attr("data-max-pages")) {
button.remove();
}
} else {
button.remove();
}
}
});
});
});
load-posts.php
<?php
add_action("wp_ajax_load_more", "load_posts");
add_action("wp_ajax_nopriv_load_more", "load_posts");
function load_posts()
{
$args = json_decode(stripslashes($_POST["query"]), true);
$args["paged"] = $_POST["page"] + 1;
$posts = new WP_Query(array(
"post_type" => "post",
"category_name" => "news",
));
$html = '';
if ($posts->have_posts()) : while ($posts->have_posts()) : $posts->the_post();
?>
<a class="col-md-4" href="<?php the_permalink(); ?>">
<div class="news-card">
<div class="thumbnail img__post" >
<?php echo get_the_post_thumbnail(); ?>
</div>
<div class="meta">
<div class="date"><?php echo get_the_date('d F Y'); ?></div>
<div class="view">
<i class="fa fa-eye" aria-hidden="true"></i>
<?php echo getPostViews(get_the_ID()); ?>
</div>
</div>
<div class="block">
<h3 class="posts-title"><?php the_title(); ?></h3>
</div>
<!--здесь выводится миниатюра записи-->
<?php the_content(); ?>
</div></a>
<?
endwhile;
endif;
wp_reset_postdata();
die($html);
}
Ответы (1 шт):
Вы используете новый экземпляр WP_Query в функции load_posts(), не передавая в него параметры запроса, что приводит к тому, что он отображает все записи из выбранной категории.
Вы используете стандартный цикл WP if ($posts->have_posts()) : while ($posts->have_posts()) : $posts->the_post();, который не учитывает текущую страницу и поэтому выводит все записи каждый раз, когда происходит AJAX-загрузка
Что касаемо динамической пагинации, вам нужно добавить параметры paged и posts_per_page в WP_Query и передать их в AJAX-запрос, эти параметры должны быть вычислены на стороне сервера, а не на стороне клиента.
AJAX-обработчик:
add_action('wp_ajax_load_more', 'load_more');
add_action('wp_ajax_nopriv_load_more', 'load_more');
function load_more() {
$query = $_POST['query'];
$page = $_POST['page'];
$postsPerPage = $_POST['posts_per_page'];
$args = json_decode($query, true);
$args['paged'] = $page;
$args['posts_per_page'] = $postsPerPage;
$posts = new WP_Query($args);
if ($posts->have_posts()) {
while ($posts->have_posts()) {
$posts->the_post();
get_template_part('template-parts/content', 'post');
}
}
wp_reset_postdata();
die();
}
JS:
jQuery(function($) {
$('#load-more').on('click', function() {
var button = $(this),
container = $('#posts-container'),
currentPage = button.data('current-page'),
maxPages = button.data('max-pages'),
newPage = currentPage + 1,
postsPerPage = button.data('posts-per-page'),
ajaxUrl = '/wp-admin/admin-ajax.php',
data = {
'action': 'load_more',
'query': button.data('query'),
'page': newPage,
'posts_per_page': postsPerPage,
'tpl': button.data('tpl')
};
button.addClass('loading').text('Загрузка...');
$.ajax({
url: ajaxUrl,
type: 'post',
data: data,
success: function(result) {
button.removeClass('loading');
if (result) {
container.append(result);
if (newPage == maxPages) {
button.remove();
} else {
button.data('current-page', newPage).text('Загрузить еще');
}
} else {
button.remove();
}
}
});
});
});
Темплейт:
<?php
$paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
$posts_per_page = 3;
$posts = new WP_Query(array(
"post_type" => "post",
"post_status" => "publish",
"posts_per_page" => $posts_per_page,
"category_name" => "news",
'orderby' => 'date',
'paged' => $paged,
)); ?>
<?php if ($posts->have_posts()) : ?>
<div id="posts-container" class="row">
<?php while ($posts->have_posts()) : $posts->the_post(); ?>
<div class="col-md-4">
<div class="news-card">
<div class="thumbnail img__post">
<?php echo get_the_post_thumbnail(); ?>
</div>
<div class="meta">
<div class="date"><?php echo get_the_date('d F Y'); ?></div>
<div class="view">
<i class="fa fa-eye" aria-hidden="true"></i>
<?php echo getPostViews(get_the_ID()); ?>
</div>
</div>
<div class="block">
<h3 class="posts-title"><?php the_title(); ?></h3>
</div>
<?php the_content(); ?>
</div>
</div>
<?php endwhile; ?>
</div>
<?php if ($posts->max_num_pages > 1) : ?>
<div class="text-center">
<button id="load-more" class="btn btn-primary" data-current-page="<?php echo $paged; ?>" data-max-pages="<?php echo $posts->max_num_pages; ?>" data-posts-per-page="<?php echo $posts_per_page; ?>">
Загрузить еще
</button>
</div>
<?php endif; ?>
<?php wp_reset_postdata(); ?>
<?php endif; ?>