@Smirator

Из-за чего дубли в Ajax подгрузке?

Столкнулся со странным поведением в WordPress. Я пытаюсь реализовать Ajax подгрузку постов. Проблема в том, что посты дублируются. На сайте 82 записи, если дойти до самого конца, то отобразятся все 82, но в них есть дубли. Например, одна запись может повторяться 2-3 раза. Я пытался переписывать код, выводил текущую страницу для отладки, все кажется верным. Но код работает не правильно. Идеи закончились, прошу помощь или совет.

Мой код: front-page.php
<?php
            if (have_posts()) {
                $arr_id = [];
                while (have_posts()) {
                    the_post();
                    array_push($arr_id, get_the_id());
                }

                // Обработка и вывод постов
                $arr_processed_post = process_posts($arr_id);
                render_articles($arr_processed_post);

                // Пагинация
                $big = 999999999; // нужно необычное число
                echo paginate_links(array(
                    'base' => str_replace($big, '%#%', esc_url(get_pagenum_link($big))),
                    'format' => '?paged=%#%',
                    'current' => max(1, get_query_var('paged')),
                    'total' => $GLOBALS['wp_query']->max_num_pages,
                    'prev_text' => __('« Предыдущая'),
                    'next_text' => __('Следующая »'),
                ));

            } else {
                // Если результатов нет, очистите параметры таксономии
                $GLOBALS['wp_query']->set('category_name', '');
                $GLOBALS['wp_query']->set('tag', '');
                echo '<p>Результаты не найдены. Попробуйте изменить запрос.</p>';
            }
            ?>


ajax-load.php

<?php
 function ajax_enqueue_scripts() {
    // Подключаем наш скрипт
    wp_enqueue_script('ajax-load-more', get_template_directory_uri() . '/assets/js/ajax-load.js', array('jquery'), null, true);

    // Локализация скрипта для передачи AJAX URL и параметров
    global $wp_query;
    wp_localize_script('ajax-load-more', 'ajax_load_more_params', array(
        'ajaxurl' => admin_url('admin-ajax.php'),
        'nonce' => wp_create_nonce('load_more_nonce'),
        'current_page' => max(1, get_query_var('paged')),
        'max_page' => $wp_query->max_num_pages,
        'query' => json_encode($wp_query->query_vars) // параметры текущего запроса
    ));
}
add_action('wp_enqueue_scripts', 'ajax_enqueue_scripts');

function loadmore_ajax_handler() {
    check_ajax_referer('load_more_nonce', 'nonce');

    $args = json_decode(stripslashes($_POST['query']), true);
    $args['paged'] = $_POST['page'] + 1; // следующая страница
    $args['post_status'] = 'publish';

    if (isset($_POST['term_id']) && isset($_POST['taxonomy']) && $_POST['term_id'] != 0) {
        $args['tax_query'] = array(
            array(
                'taxonomy' => sanitize_text_field($_POST['taxonomy']),
                'field'    => 'term_id',
                'terms'    => intval($_POST['term_id']),
            ),
        );
    }

    $query = new WP_Query($args);

    if ($query->have_posts()) :
        $arr_id = [];
        while ($query->have_posts()): $query->the_post();
            $post_id = get_the_ID();
            array_push($arr_id, $post_id);
            error_log('Loaded post ID: ' . $post_id); // Отладочный вывод
        endwhile;
        wp_reset_postdata();

        // Фильтрация уникальных ID перед передачей в process_posts
        $arr_id = array_unique($arr_id);
        error_log(print_r($arr_id, true)); // Отладочный вывод массива уникальных ID

        $arr_processed_post = process_posts($arr_id);
    endif;

    render_articles($arr_processed_post);
    die; // выход необходим для правильного завершения запроса
}

add_action('wp_ajax_loadmore', 'loadmore_ajax_handler'); // если пользователь авторизован
add_action('wp_ajax_nopriv_loadmore', 'loadmore_ajax_handler'); // если пользователь не авторизован */
?>


ajax-load.js:

/**Ajax подгрузка статей на главной странице, странице меток и категорий**/

jQuery(document).ready(function($) {
    $('#load-more').click(function() {
        var button = $(this),
            data = {
                'action': 'loadmore',
                'query': ajax_load_more_params.query,
                'page': ajax_load_more_params.current_page,
                'nonce': ajax_load_more_params.nonce,
                'term_id': button.data('term-id'),
                'taxonomy': button.data('taxonomy')
            };

            console.log('Current Page (before AJAX):', ajax_load_more_params.current_page); // Выводим номер страницы до отправки запроса


        $.ajax({
            url: ajax_load_more_params.ajaxurl, // AJAX handler
            data: data,
            type: 'POST',
            beforeSend: function (xhr) {
                button.text('Загружаем...'); // меняем текст кнопки
            },
            success: function(data) {
                if (data) { 
                    button.text('Загрузить еще'); // возвращаем текст кнопки
                    $('#content').append(data); // вставка новых постов
                    ajax_load_more_params.current_page++;

                    if (ajax_load_more_params.current_page == ajax_load_more_params.max_page) 
                        button.remove(); // если достигли последней страницы, удаляем кнопку
                } else {
                    button.remove(); // если больше нечего загружать, удаляем кнопку
                }
            }
        });
    });
});
  • Вопрос задан
  • 117 просмотров
Решения вопроса 2
pLavrenov
@pLavrenov
Разработка сайтов
if (window.jQuery) {
    jQuery(function($){
        $('#loadmore').click(function(){
            let btn_load = $(this);
            let load_list = $('#load_list');
            let data = {
                'action': action,
                'query': true_posts,
                'page' : current_page
            };
            btn_load.text('Загружаю...');
            $.ajax({
                url:ajaxurl, // обработчик
                data:data, // данные
                type:'POST', // тип запроса
                success:function(data){
                    if(data) {
                        btn_load.text('Загрузить ещё');
                        load_list.append(data);
                        current_page++;
                        if (current_page == max_pages) btn_load.remove();
                    } else {
                        btn_load.remove();
                    }
                }
            });
        });
    });
}


add_action('wp_ajax_loadmore', 'load_more');
add_action('wp_ajax_nopriv_loadmore', 'load_more');
function load_more(){
    $args = unserialize( stripslashes( $_POST['query'] ) );
    $args['paged'] = $_POST['page'] + 1; // следующая страница
    $args['post_status'] = 'publish';
    query_posts( $args );
    if( have_posts() ) {
        while( have_posts() ): the_post();
            switch ($args['post_type']) {
                case 'news':
                    get_template_part( 'tpl/path/news/news-list-item', get_post_format() );
                    break;
            }

        endwhile;
    }
    die();
}


<?php
/**
 * Template Name: Страница новостей
 */
get_header(); ?>

    <?php query_posts([
        'post_type' => 'news',
        'post_status' => 'publish',
        'posts_per_page' => 12,
        'orderby'     => 'date',
        'order'       => 'DESC',
    ]); ?>

    <div id="load_list">
        <?php if( have_posts() ){
            while( have_posts() ){ the_post();
                get_template_part( 'tpl/path/news/news-list-item', get_post_format() );
            }
        } ?>
    </div>

    <?php if (  $wp_query->max_num_pages > 1 ) : ?>
        <script>
            var ajaxurl = '<?php echo site_url() ?>/wp-admin/admin-ajax.php';
            var true_posts = '<?php echo serialize($wp_query->query_vars); ?>';
            var current_page = <?php echo (get_query_var('paged')) ? get_query_var('paged') : 1; ?>;
            var max_pages = '<?php echo $wp_query->max_num_pages; ?>';
            var action = 'loadmore';
        </script>
        <div id="loadmore">Показать еще</div>
    <?php endif; ?>

    <?php wp_reset_query(); ?>


<?php get_footer(); ?>
Ответ написан
Комментировать
@Smirator Автор вопроса
Проблема была из-за того, что использовался не тот метод при получении постов. Решилось использованием WP_Query($args). Проблема была не в Ajax и определил это постепенным возвращением на шаг назад. Сначала просто к пагинации, которая также выводила дубли, а потом уже и к выводу всех постов сразу, так и определил.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы