Как правильно вывести ajax подгрузку по клике на показать еще?
Есть страница постов.
На ней посты выводятся следующим образом.
1.
<section class="blog" style="background-image: url(<?php bloginfo('template_url');?>/assets/images/blog/bg.png);"> <div class="container"> <div class="blog__inner posts-container" id="custom-posts-container"> <?php $args = array( 'post_type' => 'Blog', 'order' => 'ASC', 'posts_per_page' => 3, 'paged' => 1, ); $the_query = new WP_Query($args); ?> <?php if ($the_query->have_posts()) : ?> <?php while ($the_query->have_posts()) : $the_query->the_post(); ?> <?php $post_id = get_the_ID(); ?> <div class="blog__inner__item"> <div class="blog__inner__item__img"> <img src="<?php the_field('post_image')?>" alt="capture" width="370" height="235"> </div> <span class="blog__inner__item__title"><?php the_title(); ?></span> <?php the_excerpt(); ?> <span class="h-reset blog__inner__item__date" datetime="<?php the_date(); ?>"><?php echo get_the_date(); ?></span> <a href="<?php the_permalink(); ?>" class="blog__inner__item__link btn-red">Читать полностью</a> </div> <?php endwhile; ?> <?php wp_reset_postdata(); ?> <?php endif; ?> </div> <button id="load-more-posts" class="btn-red blog__inner__more">Показать еще</button> </div> </section> |
<section class="blog" style="background-image: url(<?php bloginfo('template_url');?>/assets/images/blog/bg.png);"> <div class="container"> <div class="blog__inner posts-container" id="custom-posts-container"> <?php $args = array( 'post_type' => 'Blog', 'order' => 'ASC', 'posts_per_page' => 3, 'paged' => 1, ); $the_query = new WP_Query($args); ?> <?php if ($the_query->have_posts()) : ?> <?php while ($the_query->have_posts()) : $the_query->the_post(); ?> <?php $post_id = get_the_ID(); ?> <div class="blog__inner__item"> <div class="blog__inner__item__img"> <img src="<?php the_field('post_image')?>" alt="capture" width="370" height="235"> </div> <span class="blog__inner__item__title"><?php the_title(); ?></span> <?php the_excerpt(); ?> <span class="h-reset blog__inner__item__date" datetime="<?php the_date(); ?>"><?php echo get_the_date(); ?></span> <a href="<?php the_permalink(); ?>" class="blog__inner__item__link btn-red">Читать полностью</a> </div> <?php endwhile; ?> <?php wp_reset_postdata(); ?> <?php endif; ?> </div> <button id="load-more-posts" class="btn-red blog__inner__more">Показать еще</button> </div> </section>
здесь специально созданный тип записи "блог "
2. Дальше js
jQuery(function($) { var page = 1; var $loadMoreButton = $('#load-more-posts'); var $postContainer = $('#custom-posts-container'); $loadMoreButton.on('click', function() { $loadMoreButton.text('Загрузка...'); $.ajax({ url: ajaxurl, type: 'post', data: { action: 'load_more_custom_posts', page: page, }, success: function(response) { if (response) { $postContainer.append(response); $loadMoreButton.text('Показать еще'); page++; } else { $loadMoreButton.text('Больше записей нет'); } }, error: function() { $loadMoreButton.text('Ошибка при загрузке. Попробуйте снова.'); } }); }); }); |
jQuery(function($) { var page = 1; var $loadMoreButton = $('#load-more-posts'); var $postContainer = $('#custom-posts-container'); $loadMoreButton.on('click', function() { $loadMoreButton.text('Загрузка...'); $.ajax({ url: ajaxurl, type: 'post', data: { action: 'load_more_custom_posts', page: page, }, success: function(response) { if (response) { $postContainer.append(response); $loadMoreButton.text('Показать еще'); page++; } else { $loadMoreButton.text('Больше записей нет'); } }, error: function() { $loadMoreButton.text('Ошибка при загрузке. Попробуйте снова.'); } }); }); });
3. functions.php
add_action('wp_ajax_load_more_custom_posts', 'load_more_custom_posts'); add_action('wp_ajax_nopriv_load_more_custom_posts', 'load_more_custom_posts'); function load_more_custom_posts() { $page = $_POST['page']; $args = array( 'post_type' => 'Blog', 'posts_per_page' => 3, 'paged' => $page, ); $custom_query = new WP_Query($args); if ($custom_query->have_posts()) { while ($custom_query->have_posts()) { $custom_query->the_post(); // Вывод содержимого каждой загруженной записи // Например: the_title(), the_content(), и т.д. ?> <div class="blog__inner__item"> <div class="blog__inner__item__img"> <img src="<?php the_field('post_image')?>" alt="capture" width="370" height="235"> </div> <span class="blog__inner__item__title"><?php the_title(); ?></span> <?php the_excerpt(); ?> <span class="h-reset blog__inner__item__date" datetime="<?php the_date(); ?>"><?php echo get_the_date(); ?></span> <a href="<?php the_permalink(); ?>" class="blog__inner__item__link btn-red">Читать полностью</a> </div> <?php } wp_reset_postdata(); } else { wp_send_json(''); } wp_die(); } |
add_action('wp_ajax_load_more_custom_posts', 'load_more_custom_posts'); add_action('wp_ajax_nopriv_load_more_custom_posts', 'load_more_custom_posts'); function load_more_custom_posts() { $page = $_POST['page']; $args = array( 'post_type' => 'Blog', 'posts_per_page' => 3, 'paged' => $page, ); $custom_query = new WP_Query($args); if ($custom_query->have_posts()) { while ($custom_query->have_posts()) { $custom_query->the_post(); // Вывод содержимого каждой загруженной записи // Например: the_title(), the_content(), и т.д. ?> <div class="blog__inner__item"> <div class="blog__inner__item__img"> <img src="<?php the_field('post_image')?>" alt="capture" width="370" height="235"> </div> <span class="blog__inner__item__title"><?php the_title(); ?></span> <?php the_excerpt(); ?> <span class="h-reset blog__inner__item__date" datetime="<?php the_date(); ?>"><?php echo get_the_date(); ?></span> <a href="<?php the_permalink(); ?>" class="blog__inner__item__link btn-red">Читать полностью</a> </div> <?php } wp_reset_postdata(); } else { wp_send_json(''); } wp_die(); }
Сталкиваюсь со следующими проблемами:
1. во первых выше я редактирую количество слов для вывода в excerpt,
function my_excerpt_length( $length ) { return 30; // Указываем количество слов } |
function my_excerpt_length( $length ) { return 30; // Указываем количество слов }
,но при подгрузке либо игнорируется, либо выводится the_content().
2. У меня например выводится три поста, но осталось всего не выведенных два.. Но вместо того что вывести оставшиееся два, он выводит два +1 с начала....и так дальше по циклу, то есть бесконечно крутит все посты.
Что не так делаю, буду рад любой помощи....
Дополнительно:
несколько соображений:
1. регистрация my_excerpt_length может и не происходить в случае AJAX запроса, зависит от того как именно она регистрируется, но детальнее не подскажу, т.к. ковырялся с этим относительно давно
2. дозагрузка начинается со страницы 1, хотя по идее должна начинаться со страницы 2, это я про var page = 1;
3. порядок сортировки разнится между изначальным циклом и подзагрузкой
$content = get_the_content(); // Получаем содержимое записи $trimmed_content = wp_trim_words($content, 20, ' [...]'); // Обрезаем до 20 слов и добавляем " [...]" в конце echo $trimmed_content; // Выводим обрезанный текст |
$content = get_the_content(); // Получаем содержимое записи $trimmed_content = wp_trim_words($content, 20, ' [...]'); // Обрезаем до 20 слов и добавляем " [...]" в конце echo $trimmed_content; // Выводим обрезанный текст
Вопрос закрыт..
Опишите проблему, и специалист поможет с настройкой, исправлением ошибки или доработкой сайта. Подберём понятный план работ без лишней переписки.
Пока нет других ответов. Будьте первым, кто поможет автору.
Ответить на вопрос
AJAX-подгрузка “Показать ещё” должна хранить текущую страницу и каждый раз отдавать следующую порцию через отдельный обработчик. Важно:
post_typeдолжен быть реальным slug типа записи, обычно в нижнем регистре. Если CPT называетсяblog, используйте'post_type' => 'blog', а неBlog.На странице выводите первые записи и кнопку с данными:
$query = new WP_Query([ 'post_type' => 'blog', 'posts_per_page' => 3, 'paged' => 1, ]); // вывод карточек if ($query->max_num_pages > 1) { echo '<button class="js-load-more" data-page="1" data-max="' . esc_attr($query->max_num_pages) . '">Показать ещё</button>'; } wp_reset_postdata();
Обработчик:
add_action('wp_ajax_load_more_blog', 'load_more_blog'); add_action('wp_ajax_nopriv_load_more_blog', 'load_more_blog'); function load_more_blog() { $paged = max(1, absint($_POST['page'] ?? 1)); $query = new WP_Query([ 'post_type' => 'blog', 'posts_per_page' => 3, 'paged' => $paged, ]); ob_start(); while ($query->have_posts()) { $query->the_post(); get_template_part('template-parts/blog-card'); } wp_reset_postdata(); wp_send_json_success([ 'html' => ob_get_clean(), 'max' => $query->max_num_pages, ]); }
JS должен увеличивать страницу и убирать кнопку, когда страниц больше нет:
$(document).on('click', '.js-load-more', function () { const btn = $(this); const nextPage = Number(btn.data('page')) + 1; $.post(ajaxData.url, { action: 'load_more_blog', page: nextPage }, function (res) { if (!res.success) return; $('#custom-posts-container').append(res.data.html); btn.data('page', nextPage); if (nextPage >= Number(btn.data('max'))) btn.remove(); }); });$(document).on('click', '.js-load-more', function () { const btn = $(this); const nextPage = Number(btn.data('page')) + 1; $.post(ajaxData.url, { action: 'load_more_blog', page: nextPage }, function (res) { if (!res.success) return; $('#custom-posts-container').append(res.data.html); btn.data('page', nextPage); if (nextPage >= Number(btn.data('max'))) btn.remove(); }); });
Не забудьте передать
ajaxData.urlчерезwp_localize_script()и вынести карточку в шаблон, чтобы первый вывод и AJAX-вывод были одинаковыми.Также добавьте nonce, если подгрузка доступна только для доверенных действий, и не передавайте в AJAX сырые значения из формы без очистки. Если вместе с “Показать ещё” будут фильтры, отправляйте их в этот же обработчик и добавляйте в
WP_Query. Главная ошибка в таких задачах — первый вывод построен одним запросом, а AJAX другим, из-за чего карточки, порядок и количество страниц начинают расходиться.