WP_Query Пагинація на single-custom.php


16

Що я хочу зробити:

Налаштування WP_Queryнумерації сторінок у файлі шаблону одного на замовлення після type.php

Що я зробив

1) Створено тип публікації під назвою "автори". Кожна публікація в межах цього типу публікації - це окремий автор.

2) Стандартні сторінки редагування екрана публікації містять спадне меню, в якому перераховані всі публікації (автори) від власного типу публікацій авторів.

3) Створено шаблон-один-автори.php, який запитує всі публікації з метаданими автора з випадаючого списку, тому в результаті виходить список публікацій, яким призначений той самий автор (на зразок архіву):

<?php

// set the "paged" parameter (use 'page' if the query is on a static front page)
global $paged;

/*We need this here to add and maintain Pagination if Template is assigned to Front Page*/
if ( get_query_var( 'paged' ) ) {
    $paged = get_query_var('paged');
} elseif ( get_query_var( 'page' ) ) {
    $paged = get_query_var( 'page' );
} else {
    $paged = 1;
}

$args = array(
    'posts_per_page'    =>  10,
    'meta_key'          => 'author_select',
    'meta_value'        => $author_id,
    'paged'             => $paged,
);

$temp = $wp_query;
$wp_query = NULL;

$wp_query = new WP_Query($args);

?>

<?php if( $wp_query->have_posts() ) : ?>    
    <?php while ( $wp_query->have_posts() ) : $wp_query->the_post(); ?>
    <?php // Successfully outputs the results of the above query, so I've omitted the code from this example. ?>

    <?php endwhile; ?>

<div class="single_navigation"> 
    <?php if( get_adjacent_post( false, '', true ) ) { ?>
        <span class="prev"><?php previous_post_link( '&lt; %link' ) ?></span>
    <?php } ?>

    <?php if( get_adjacent_post( false, '', false ) ) { ?>
        <span class="next"><?php next_post_link( '%link &gt;' ) ?></span>
    <?php } ?>
    </div><!--/single navigation-->
<?php endif; ?>

<?php
    $wp_query = null;
    $wp_query = $temp;
    wp_reset_query();
?>

На чому я застряг

Посилання на сторінки не відображаються. Я провів деякі дослідження і виявив, що вони використовують цю $wp_queryзмінну, проте коли я змінив змінну запиту на $wp_query, з'явилися посилання, але при натисканні нічого не робилося.

Будь-яка ідея, де я помиляюся?

Редагувати:

Щоб відповісти на деякі ваші запитання, мій запит успішно виводить публікації, які я запитую, $ author_id вже має значення, яке я не включив у цей фрагмент коду. Так само я випустив фактичний вихід вмісту в циклі while, оскільки ця частина не є проблемою. Проблема полягає в тому, що мені потрібно погіршити патент, який вже є в цій одній публікації.

Метою цієї функціональності було дозволити публікаціям користувальницьких авторів (за межами вбудованої системи Користувачів), а мета цього шаблону - вивести усі публікації для певного автора (що вже працює).


3
Висновок для добре відформатованого запитання, хоча ви не описували, чому ви це робите, чи це пов’язані публікації поточного авторського поля?
Том Дж. Ноуелл

1
Я дійсно згоден з @TomJNowell. +1
Пітер Гусен

2
Неспоріднені, але не варто перегукуватисьthe_title()
Пітер Гусен

2
Чи 'meta_value' => $author_idзаповнюється згадане спадне меню? І коли вибираєте кожного автора через спадне меню, чи відображаються перші десять публікацій правильно?
Стівен С.

1
Ви переконалися, що $author_query->have_posts()повертається trueі що $author_queryнасправді містять будь-які повідомлення?
кайзер

Відповіді:


17

У вас є 2 проблеми.

Перша проблема

Лінія

$paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;

не вдасться, тому що в єдиному поданні публікації, коли URL-адреса міститься '/page/XX/', змінна множина WordPress є 'page'і ні 'paged'.

Ви можете подумати використовувати 'page' замість цього 'paged', але це також не вийде, тому що коли 'page'змінна призначена для використання для багатосторінкового сингулярного допису (розділення сторінки з використанням <!--nextpage-->), і коли повідомлення не буде багатосторінковим, WordPress перенаправить запит до URL-адреси без '/page/XX/'.

Це те, що відбувається, коли ви називаєте змінну запиту $wp_query.

Рішення полягає в тому, щоб запобігти перенаправленню, видаливши відповідальну за нього функцію, яка 'redirect_canonical'підключена до 'template_redirect':

Отже, у вашому functions.php додаванні:

add_action( 'template_redirect', function() {
    if ( is_singular( 'authors' ) ) {
        global $wp_query;
        $page = ( int ) $wp_query->get( 'page' );
        if ( $page > 1 ) {
            // convert 'page' to 'paged'
            $wp_query->set( 'page', 1 );
            $wp_query->set( 'paged', $page );
        }
        // prevent redirect
        remove_action( 'template_redirect', 'redirect_canonical' );
    }
}, 0 ); // on priority 0 to remove 'redirect_canonical' added with priority 10

Тепер WordPress більше не буде перенаправлятись і правильно встановить 'paged'вар. Запиту.

Друга проблема

next_posts_link()і previous_posts_link()обидва перевіряютьif ( ! is_single() ) щоб відобразити сторінку.

Тепер is_single()це правда у вашому випадку, тому що ви знаходитесь в одній посаді типу "автор", тому ці функції не можуть працювати, як ви очікували.

У вас є 3 можливості:

  1. Використовувати query_postsдля заміщення основного запиту (дійсно не рекомендується)
  2. Використовуйте власний шаблон сторінки замість спеціального типу публікації, оскільки is_single()для сторінок помилковий, і ваш код буде там працювати.
  3. Напишіть власну функцію сторінки та використовуйте її

Це код рішення №3:

function my_pagination_link( $label = NULL, $dir = 'next', WP_Query $query = NULL ) {
    if ( is_null( $query ) ) {
        $query = $GLOBALS['wp_query'];
    }
    $max_page = ( int ) $query->max_num_pages;
    // only one page for the query, do nothing
    if ( $max_page <= 1 ) {
        return;
    }
    $paged = ( int ) $query->get( 'paged' );
    if ( empty( $paged ) ) {
        $paged = 1;
    }
    $target_page = $dir === 'next' ?  $paged + 1 : $paged - 1;
    // if 1st page requiring previous or last page requiring next, do nothing
    if ( $target_page < 1 || $target_page > $max_page ) {
        return;
    }
    if ( null === $label ) {
        $label = __( 'Next Page &raquo;' );
    }

    $label = preg_replace( '/&([^#])(?![a-z]{1,8};)/i', '&#038;$1', $label );
    printf( '<a href="%s">%s</a>', get_pagenum_link( $target_page ), esc_html( $label ) );
}

і використовувати його так у single-authors.php:

my_pagination_link( 'Older Entries', 'next', $author_query );
my_pagination_link( 'Newer Entries', 'prev', $author_query );

Дуже детальна відповідь, дякую! Це працює для англійської сторони сайту, але з французької сторони посилання на сторінки не роблять нічого, вони лише оновлюють сторінку. Я використовую WPML.
Шейн

1
@Shane так здається, що WPML запускає якийсь фільтр, який заважає коду працювати. Але це настільки великий плагін, і тому я не можу викопати тисячі рядків коду, щоб зрозуміти, де знаходиться конфлікт. Спробуйте запитати підтримку WPML.
gmazzap

@Shane Форуми підтримки WPML - і якщо вище працює (що я припускаю), то, будь ласка, позначте це як рішення. Конфлікт WPML так чи інакше поза темою / поза межами цього веб-сайту.
кайзер

Фантастична відповідь, головним чином тому, що це допомогло мені виправити свою проблему з сторінкою. Я робив подібне завдання і створив другу WP_Query, щоб перетворити цикл. Я зателефонував, the_posts_paginationале мусив взяти копію оригіналу wp_query, як зазначено в цьому запитанні: wordpress.stackexchange.com/questions/216821/…
Олександр Холсгров

1
Ви прав @HongPong, виправлено, дякую.
gmazzap

0

Виходячи з іншого подібного питання WPSE " Сторінка не працює wp_query значення спеціальних полів ", я б запропонував додати global $paged;до початку файлу шаблону:

global $paged;
$paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;

1
Дякуємо за відповідь! На жаль, це не має жодного значення. Посилання на сторінки не відображаються
Шейн

1
Стівен, чому це повинно допомагати? Так, це призведе до глобального контексту, але поки ви з цим нічого не робите. Якщо ви хочете перекрити глобальний, тоді використовуйте $GLOBALS['paged'] = get_query_var( 'paged' );. Ще просто використовуйте вміст глобалів.
кайзер

@Shane Хм, чи використовується сторінка шаблону як статична титульна сторінка?
Стівен С.

Ні, він використовується лише як єдиний шаблон публікації для спеціального типу публікації. Я намагався змінити свій запит з $author_queryна, $wp_queryі, здавалося, змушує відображатися сторінки, але коли я натискаю на неї, сторінка оновлюється і насправді не переходить на наступну сторінку, навіть якщо є кілька сторінок. Я оновив свою відповідь, щоб відобразити ці зміни.
Шейн

1
Php.net пояснення не так уже й погано. Я б запропонував просто пограти з globalі $GLOBALS. Трохи var_dump(), деякі функції, і ти все добре. Щоб реально зрозуміти це з невеликою кількістю спроб / помилок, ви прибл. потрібно півгодини. Це допоможе вам набагато краще зрозуміти функції порівняно з класами та підходом ООП в цілому. І це явно наблизить вас до розуміння просторів імен :)
кайзер
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.