Пагинация не работает

28 апр. 2015 г., 00:39:14
Просмотры: 25.6K
Голосов: 2

Я использовал один и тот же код пагинации для большинства созданных мной сайтов. В этот раз он почему-то не работает. Я использовал ссылки для устранения неполадок пагинации здесь, но ничего не помогает. Ниже я прикрепил свой код.

В этот раз я вывожу записи в таблице, и думаю, что это может быть связано с этим, хотя я пробовал выводить и без таблицы - все равно не работает. Вот мой код:

Новый запрос

<?php
$args = array(
    'post_type' => 'custom_post_type',
    'posts_per_page' => 5,
    'paged' => ( get_query_var('paged') ? get_query_var('paged') : 1),
);
query_posts($args);
?>

Таблица с данными из моих пользовательских мета-полей:

<table>
    <thead>
        <tr>

            <th>заголовок</th>
            <th>заголовок</th>
            <th>заголовок</th>
            <th>заголовок</th>

        </tr>
    </thead>
    <tbody>

        <?php  while (have_posts()) : the_post();?>
            <tr>

                <td><?php echo get_post_meta($post->ID, 'metakey', true); ?></td>
                <td><?php echo get_post_meta($post->ID, 'metakey', true); ?></td>
                <td><?php echo get_post_meta($post->ID, 'metakey', true); ?></td>    
                <td><?php echo get_post_meta($post->ID, 'metakey', true); ?></td>    

            </tr>
        <?php
        endwhile;
        ?>

    </tbody>
</table>

Мои ссылки пагинации

<?php
global $wp_query;

$big = 999999999; // нужно невероятно большое число

echo paginate_links( array(
    'base' => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ),
    'format' => '?paged=%#%',
    'prev_text'          => __('Предыдущая'),
    'next_text'          => __('Следующая'),
    'current' => max( 1, get_query_var('paged') ),
    'total' => $wp_query->max_num_pages
) );
?>

Когда я говорю, что пагинация не работает, я имею в виду, что ссылки пагинации отображаются с правильным количеством страниц, но при нажатии на вторую страницу ничего не меняется. Пермалинки правильные, отображается domain/page/2, но страница остается такой же, как и первая. Это происходит на шаблоне страницы, который я создал как home-page.php. Буду признателен за предложения.

5
Комментарии

уточните, что вы имеете в виду под не работает, что происходит? На какой странице это происходит?

Milo Milo
28 апр. 2015 г. 01:49:05

Привет @Milo Спасибо за ответ. Когда я говорю, что не работает, я имею в виду, что ссылки пагинации отображают правильное количество страниц. Но когда я нажимаю на вторую страницу, страницы не меняются. Постоянные ссылки правильные - отображается domain/page/2, но контент остается таким же, как на первой странице. Это происходит на шаблонной странице, которую я создал для home-page.php. Благодарю за помощь.

steamfunk steamfunk
28 апр. 2015 г. 02:49:07

Не используйте query_posts, это ломает пагинацию и основной запрос

Pieter Goosen Pieter Goosen
28 апр. 2015 г. 07:59:24

Также обратите внимание, что ваш комментарий должен быть [редактированием] вашего вопроса. Многие просто пропускают и игнорируют комментарии, и они также пропустят и проигнорируют ваш вопрос, так как не работает для них не имеет особого смысла.

Pieter Goosen Pieter Goosen
28 апр. 2015 г. 08:55:18

@PieterGoosen еще раз спасибо, я буду иметь это в виду!

steamfunk steamfunk
28 апр. 2015 г. 09:25:40
Все ответы на вопрос 2
2

Как я уже упоминал в комментариях, вам никогда не следует использовать query_posts, используйте query_posts только если вы намеренно хотите сломать функциональность вашей страницы. Добавьте query_posts в самый верх вашего СПИСКА ЗЛА.

query_posts ломает основной объект запроса, тот самый объект, на который полагается ваша функция пагинации. Ваша функция пагинации использует свойство $max_num_pages из основного запроса. Это лишь одна из многих вещей, которые ломает query_posts.

Для решения вашей проблемы используйте WP_Query, так как похоже, что вы используете здесь пользовательский шаблон страницы. Одно замечание: если home-page.php — это статическая главная страница (что я подозреваю по названию шаблона), тогда

'paged' => ( get_query_var('paged') ? get_query_var('paged') : 1),

должно быть

'paged' => ( get_query_var('page') ? get_query_var('page') : 1),

поскольку статические главные страницы используют page, а не paged.

Вы можете попробовать что-то вроде этого: (Очень важно: это не тестировалось и скопировано из вопроса, и всегда помните о сбросе postdata после завершения работы с пользовательским запросом)

<?php
$args = array(
    'post_type' => 'custom_post_type',
    'posts_per_page' => 5,
    'paged' => ( get_query_var('paged') ? get_query_var('paged') : 1),
);
$query = new WP_Query($args);
?>
<table>
    <thead >
        <tr>

            <th>заголовок</th>
            <th>заголовок</th>
            <th>заголовок</th>
            <th>заголовок</th>

        </tr>
    </thead>
    <tbody>

        <?php  while ($query->have_posts()) : $query->the_post();?>
            <tr>

                <td><?php echo get_post_meta($post->ID, 'metakey', true); ?></td>
                <td><?php echo get_post_meta($post->ID, 'metakey', true); ?></td>
                <td><?php echo get_post_meta($post->ID, 'metakey', true); ?></td>    
                <td><?php echo get_post_meta($post->ID, 'metakey', true); ?></td>    

            </tr>
        <?php
        endwhile;
        wp_reset_postdata();
        ?>

    </tbody>
</table>

Затем вам просто нужно обновить вашу функцию пагинации, используя свойство $max_num_pages из вашего пользовательского запроса:

<?php
$big = 999999999; // нужно очень большое число

echo paginate_links( array(
    'base' => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ),
    'format' => '?paged=%#%',
    'prev_text'          => __(' Назад'),
    'next_text'          => __('Вперед '),
    'current' => max( 1, get_query_var('paged') ),
    'total' => $query->max_num_pages
) );
?>
28 апр. 2015 г. 20:21:05
Комментарии

Потрясающе, спасибо, я действительно ценю это. Я не знал об этом раньше.

steamfunk steamfunk
29 апр. 2015 г. 00:39:36

это изменилось недавно? По состоянию на 2018 год "paged" работал, но перестал работать недавно (2020). Изменил на "page", и теперь работает

thebigtine thebigtine
22 февр. 2021 г. 18:30:30
0

Я использовал пользовательский запрос и мне нужно было добавить пагинацию для результатов запроса. Поскольку оригинальная функция paginate_links() тесно связана с глобальными контекстами $wp_query и $wp_rewrite, я адаптировал её для полностью независимой работы. Пример использования:

function myPaginateLinks( WP_Query $wp_query, $args = '' ) {
    global $wp_rewrite;

    // Установка значений по умолчанию на основе текущего URL.
    $pagenum_link = html_entity_decode( get_pagenum_link() );
    $url_parts    = explode( '?', $pagenum_link );

    // Получение общего числа страниц и текущей страницы из запроса, если доступно.
    $total   = isset( $wp_query->max_num_pages ) ? $wp_query->max_num_pages : 1;
    $current = !empty($_GET['pg']) ? absint($_GET['pg']) : 1;

    // Добавление плейсхолдера формата к базовому URL.
    $pagenum_link = trailingslashit( $url_parts[0] ) . '%_%';

    // База URL зависит от настроек постоянных ссылок.
    $format  = $wp_rewrite->using_index_permalinks() && ! strpos( $pagenum_link, 'index.php' ) ? 'index.php/' : '';
    $format .= '?pg=%#%';

    $defaults = array(
        'base'               => $pagenum_link, // http://example.com/all_posts.php%_% : %_% заменяется на format (ниже).
        'format'             => $format, // ?page=%#% : %#% заменяется на номер страницы.
        'total'              => $total,
        'current'            => $current,
        'aria_current'       => 'page',
        'show_all'           => false,
        'prev_next'          => true,
        'prev_text'          => __( '&laquo; Назад' ),
        'next_text'          => __( 'Вперёд &raquo;' ),
        'end_size'           => 1,
        'mid_size'           => 2,
        'type'               => 'plain',
        'add_args'           => array(), // Массив дополнительных аргументов запроса.
        'add_fragment'       => '',
        'before_page_number' => '',
        'after_page_number'  => '',
    );

    $args = wp_parse_args( $args, $defaults );

    if ( ! is_array( $args['add_args'] ) ) {
        $args['add_args'] = array();
    }

    // Объединение дополнительных параметров запроса из оригинального URL с массивом 'add_args'.
    if ( isset( $url_parts[1] ) ) {
        // Находим аргумент формата.
        $format       = explode( '?', str_replace( '%_%', $args['format'], $args['base'] ) );
        $format_query = isset( $format[1] ) ? $format[1] : '';
        wp_parse_str( $format_query, $format_args );

        // Находим аргументы запроса из запрошенного URL.
        wp_parse_str( $url_parts[1], $url_query_args );

        // Удаляем аргумент формата из массива аргументов запроса, чтобы избежать перезаписи пользовательского формата.
        foreach ( $format_args as $format_arg => $format_arg_value ) {
            unset( $url_query_args[ $format_arg ] );
        }

        $args['add_args'] = array_merge( $args['add_args'], urlencode_deep( $url_query_args ) );
    }

    // Кто знает, что ещё могут передать в $args.
    $total = (int) $args['total'];
    if ( $total < 2 ) {
        return;
    }
    $current  = (int) $args['current'];
    $end_size = (int) $args['end_size']; // Вне границ? Устанавливаем значение по умолчанию.
    if ( $end_size < 1 ) {
        $end_size = 1;
    }
    $mid_size = (int) $args['mid_size'];
    if ( $mid_size < 0 ) {
        $mid_size = 2;
    }

    $add_args   = $args['add_args'];
    $r          = '';
    $page_links = array();
    $dots       = false;

    if ( $args['prev_next'] && $current && 1 < $current ) :
        $link = str_replace( '%_%', 2 == $current ? '' : $args['format'], $args['base'] );
        $link = str_replace( '%#%', $current - 1, $link );
        if ( $add_args ) {
            $link = add_query_arg( $add_args, $link );
        }
        $link .= $args['add_fragment'];

        $page_links[] = sprintf(
            '<a class="prev page-numbers" href="%s">%s</a>',
            /**
             * Фильтр для пагинированных ссылок архивных страниц.
             *
             * @since 3.0.0
             *
             * @param string $link URL пагинированной ссылки.
             */
            esc_url( apply_filters( 'paginate_links', $link ) ),
            $args['prev_text']
        );
    endif;

    for ( $n = 1; $n <= $total; $n++ ) :
        if ( $n == $current ) :
            $page_links[] = sprintf(
                '<span aria-current="%s" class="page-numbers current">%s</span>',
                esc_attr( $args['aria_current'] ),
                $args['before_page_number'] . number_format_i18n( $n ) . $args['after_page_number']
            );

            $dots = true;
        else :
            if ( $args['show_all'] || ( $n <= $end_size || ( $current && $n >= $current - $mid_size && $n <= $current + $mid_size ) || $n > $total - $end_size ) ) :
                $link = str_replace( '%_%', 1 == $n ? '' : $args['format'], $args['base'] );
                $link = str_replace( '%#%', $n, $link );
                if ( $add_args ) {
                    $link = add_query_arg( $add_args, $link );
                }
                $link .= $args['add_fragment'];

                $page_links[] = sprintf(
                    '<a class="page-numbers" href="%s">%s</a>',
                    /** Этот фильтр документирован в wp-includes/general-template.php */
                    esc_url( apply_filters( 'paginate_links', $link ) ),
                    $args['before_page_number'] . number_format_i18n( $n ) . $args['after_page_number']
                );

                $dots = true;
            elseif ( $dots && ! $args['show_all'] ) :
                $page_links[] = '<span class="page-numbers dots">' . __( '&hellip;' ) . '</span>';

                $dots = false;
            endif;
        endif;
    endfor;

    if ( $args['prev_next'] && $current && $current < $total ) :
        $link = str_replace( '%_%', $args['format'], $args['base'] );
        $link = str_replace( '%#%', $current + 1, $link );
        if ( $add_args ) {
            $link = add_query_arg( $add_args, $link );
        }
        $link .= $args['add_fragment'];

        $page_links[] = sprintf(
            '<a class="next page-numbers" href="%s">%s</a>',
            /** Этот фильтр документирован в wp-includes/general-template.php */
            esc_url( apply_filters( 'paginate_links', $link ) ),
            $args['next_text']
        );
    endif;

    switch ( $args['type'] ) {
        case 'array':
            return $page_links;

        case 'list':
            $r .= "<ul class='page-numbers'>\n\t<li>";
            $r .= implode( "</li>\n\t<li>", $page_links );
            $r .= "</li>\n</ul>\n";
            break;

        default:
            $r = implode( "\n", $page_links );
            break;
    }

    /**
     * Фильтр для HTML вывода пагинированных ссылок архивов.
     *
     * @since 5.7.0
     *
     * @param string $r    HTML вывод.
     * @param array  $args Массив аргументов. Смотрите paginate_links()
     *                     для информации о принимаемых аргументах.
     */
    $r = apply_filters( 'paginate_links_output', $r, $args );

    return $r;
}

Пример использования:

$myQuery = new WP_Query();

$cars = $myQuery->query([
    'post_type' => 'cars',
    'paged' => !empty($_GET['pg']) ? absint($_GET['pg']) : 1,
]);

foreach ($cars as $car) {
    echo $car->post_title;
}

echo myPaginateLinks($myQuery);

Что даёт точно такой же результат, как и paginate_links, но без привязки к глобальному запросу или правилам перезаписи:

Пагинация WordPress для пользовательского запроса и типа записи CPT

Обратите внимание, что я использую $_GET['pg'] вместо ?paged для пагинации, так как не хотел, чтобы "магия перезаписи" мешала работе пагинации.

20 июн. 2021 г. 19:32:49