WP_Query Pagination na single-custom.php

16

Co chcę zrobić:

Skonfiguruj WP_Querypaginację w pliku szablonu single-custom-post-type.php

Co zrobiłem

1) Utworzono typ postu o nazwie „autorzy”. Każdy post w ramach tego typu postów jest indywidualnym autorem.

2) Standardowe strony ekranu edycji postów zawierają menu rozwijane, które zawiera listę wszystkich postów (autorów) z niestandardowego typu postów autorów.

3) Utworzono szablon single-author.php, który wyszukuje wszystkie posty za pomocą metadanych autora z menu rozwijanego, więc wynikiem jest lista postów, do których przypisano tego samego autora (coś w rodzaju archiwum):

<?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();
?>

Na czym utknąłem

Łącza do stronicowania nie są wyświetlane. Przeprowadziłem badania i odkryłem, że używają tej $wp_queryzmiennej, jednak kiedy zmieniłem zmienną zapytania na $wp_query, pojawiły się linki, ale po kliknięciu nic nie zrobiłem.

Masz pomysł, gdzie się mylę?

Edytować:

Aby odpowiedzieć na niektóre pytania, moje zapytanie z powodzeniem wyświetla posty, o które pytam, $ autor_id ma już wartość, której nie zawarłem w tym fragmencie kodu. Podobnie pominąłem rzeczywistą treść wyjściową w pętli while, ponieważ ta część nie stanowi problemu. Problem polega na tym, że muszę paginować treść, która już istnieje w tym pojedynczym poście.

Celem tej funkcji było umożliwienie autorom niestandardowych postów (poza wbudowanym systemem użytkowników), a celem tego szablonu jest wyprowadzenie wszystkich postów dla danego autora (który już działa).

Shane
źródło
3
Głosowanie za dobrze sformatowanym pytaniem, choć nie opisałeś, dlaczego to robisz, czy jest to powiązane posty aktualnego autora?
Tom J Nowell
1
Naprawdę zgadzam się z @TomJNowell. +1
Pieter Goosen
2
Niepowiązane, ale echo nie jest koniecznethe_title()
Pieter Goosen
2
Czy 'meta_value' => $author_idwspomniano o wypełnianiu listy rozwijanej? A czy podczas wybierania każdego autora za pomocą listy rozwijanej pierwsze dziesięć postów wyświetla się poprawnie?
Stephen S.
1
Czy upewniłeś się, że $author_query->have_posts()zwroty truei że $author_queryfaktycznie zawiera jakieś posty?
kaiser

Odpowiedzi:

17

Masz 2 problemy.

Pierwszy problem

Linia

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

zawiedzie, ponieważ w pojedynczym widoku postu, gdy adres URL zawiera '/page/XX/', zmienne zestawy WordPress są 'page'i nie są 'paged'.

Możesz pomyśleć o użyciu 'page'zamiast 'paged', ale to też nie zadziała, ponieważ gdy 'page'zmienna ma być używana do wielostronicowego pojedynczego postu (przy użyciu rozdzielania stron <!--nextpage-->), a gdy post nie jest wielostronicowy, WordPress przekieruje żądanie na adres URL bez '/page/XX/'.

Tak dzieje się, gdy nazwiesz zmienną zapytania $wp_query.

Rozwiązaniem jest zapobieganie temu przekierowaniu poprzez usunięcie odpowiedzialnej za to funkcji, która jest 'redirect_canonical'zaczepiona o 'template_redirect':

Tak więc w swoim functions.phpdodaniu:

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

Teraz WordPress nie będzie już przekierowywać i ustawi poprawnie 'paged'zapytanie var.

Drugi problem

next_posts_link()i previous_posts_link()oba zaznaczają, if ( ! is_single() )aby wyświetlić paginację.

Tak is_single()jest w twoim przypadku, ponieważ jesteś w jednym poście typu „autor”, więc te funkcje nie mogą działać zgodnie z oczekiwaniami.

Masz 3 możliwości:

  1. Użyj query_postszastąpić główny zapytanie (naprawdę nie zalecane)
  2. Użyj niestandardowego szablonu strony zamiast niestandardowego typu postu, ponieważ is_single()jest fałszywy dla stron, a Twój kod będzie tam działał.
  3. Napisz własną funkcję paginacji i skorzystaj z niej

To jest kod rozwiązania nr 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 ) );
}

i użyj go w następujący sposób single-authors.php:

my_pagination_link( 'Older Entries', 'next', $author_query );
my_pagination_link( 'Newer Entries', 'prev', $author_query );
gmazzap
źródło
Bardzo szczegółowa odpowiedź, dziękuję! Działa to po angielskiej stronie strony, ale po stronie francuskiej linki do stronicowania nic nie robią, tylko odświeżają stronę. Używam WPML.
Shane
1
@Shane wydaje się, że WPML uruchamia jakiś filtr, który uniemożliwia działanie kodu. Ale jest tak dużą wtyczką, więc nie mogę wykopać tysięcy wierszy kodu, aby zrozumieć, gdzie jest konflikt. Spróbuj poprosić o wsparcie WPML.
gmazzap
@Shane Fora wsparcia WPML - a jeśli powyższe działa dla (co zakładam), proszę oznaczyć to jako rozwiązanie. Konflikt WPML jest poza tematem / poza zakresem tej strony.
kaiser
Fantastyczna odpowiedź, głównie dlatego, że pomogła mi rozwiązać problem z paginacją. Wykonałem podobne zadanie i stworzyłem drugą WP_Query do zapętlenia. Zadzwoniłem, the_posts_paginationale musiałem pobrać kopię oryginalnego wp_query, jak opisano w tym pytaniu: wordpress.stackexchange.com/questions/216821/...
Alexander Holsgrove
1
Masz rację @HongPong, naprawiono, dziękuję.
gmazzap
0

Opierając się na innym podobnym pytaniu WPSE „ Nie działa paginacja wartości pól niestandardowych wp_query ”, sugerowałbym dodanie global $paged;na początku pliku szablonu:

global $paged;
$paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;
Stephen S.
źródło
1
Dzięki za odpowiedzi! Niestety wydaje się, że nie ma to żadnej różnicy. Linki do stronicowania nie pojawiają się
Shane
1
Stephen, dlaczego miałoby to pomóc? Tak, przyniesie to z globalnego kontekstu, ale jak dotąd nic z tym nie robisz. Jeśli chcesz zastąpić globalny, użyj $GLOBALS['paged'] = get_query_var( 'paged' );. W przeciwnym razie skorzystaj z treści globalnych.
kaiser
@Shane Hmm, czy strona szablonu jest używana jako statyczna strona główna?
Stephen S.
Nie, jest on używany tylko jako szablon pojedynczego postu dla niestandardowego typu postu. Próbowałem zmienić zapytanie z $author_queryna $wp_queryi wydawało się, że pojawia się paginacja, ale kiedy klikam, strona odświeża się i nie przechodzi do następnej strony, mimo że jest wiele stron. Zaktualizowałem swoją odpowiedź, aby odzwierciedlić te zmiany.
Shane
1
Php.net wyjaśnienie nie jest tak źle. Proponuję po prostu bawić się z globali $GLOBALS. Trochę var_dump(), niektóre funkcje i wszystko w porządku. Aby naprawdę to zrozumieć przy odrobinie prób / błędów, będziesz mieć ok. potrzebuję pół godziny. Pomoże ci to znacznie lepiej zrozumieć funkcje w porównaniu do klas i podejście OOP jako całości. I to wyraźnie przybliży cię do zrozumienia przestrzeni nazw :)
kaiser