Impaginazione WP_Query su single-custom.php


16

Cosa sto cercando di fare:

Imposta l' WP_Queryimpaginazione in un file modello single-custom-post-type.php

Cosa ho fatto

1) Crea un tipo di post chiamato "autori". Ogni post all'interno di quel tipo di post è un singolo autore.

2) Le pagine della schermata dei post di modifica standard contengono un menu a discesa che elenca tutti i post (autori) del tipo di post personalizzato degli autori.

3) Crea un modello single-autori.php che interroga tutti i post con i metadati dell'autore dal menu a discesa, quindi il risultato è un elenco di post a cui è assegnato lo stesso autore (un po 'come un archivio):

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

Ciò su cui sono bloccato

I collegamenti di impaginazione non vengono visualizzati. Ho fatto qualche ricerca e ho scoperto che usano la $wp_queryvariabile, tuttavia quando ho cambiato la mia variabile di query in $wp_query, i collegamenti sono apparsi, ma quando si fa clic non ha fatto nulla.

Qualche idea su dove sbaglio?

Modificare:

Per rispondere ad alcune delle tue domande, la mia query genera correttamente i post che sto interrogando, $ author_id ha già un valore che non ho incluso in questo frammento di codice. Allo stesso modo, ho omesso l'output del contenuto effettivo all'interno del ciclo while perché quella parte non è il problema. Il problema è che devo impaginare il contenuto già esistente in questo singolo post.

Lo scopo di questa funzionalità era quello di consentire ai post di avere autori personalizzati (al di fuori del sistema Users incorporato) e lo scopo di questo modello è quello di produrre tutti i post per un determinato autore (che sta già funzionando).


3
Un voto per una domanda ben formattata, anche se non hai descritto il motivo per cui lo stai facendo, è un post correlato dalla casella dell'autore corrente?
Tom J Nowell

1
Sono davvero d'accordo con @TomJNowell. +1
Pieter Goosen

2
Non correlato, ma non è necessario fare ecothe_title()
Pieter Goosen

2
Viene 'meta_value' => $author_idcompilato dal menu a discesa menzionato? E quando si seleziona ciascun autore tramite il menu a discesa, i primi dieci post vengono visualizzati correttamente?
Stephen S.

1
Ti sei assicurato che $author_query->have_posts()ritorni truee che $author_queryeffettivamente contenga post?
Kaiser

Risposte:


17

Hai 2 problemi.

Primo problema

La linea

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

fallirà, perché nella visualizzazione dei post singoli, quando l'URL contiene '/page/XX/', la variabile WordPress imposta è 'page'e non 'paged'.

Potresti pensare di utilizzare 'page'invece di 'paged', ma non funzionerà neanche, perché una volta che la 'page'variabile è destinata a essere utilizzata per post singolari multipagina (usando la separazione delle pagine <!--nextpage-->) e una volta che il post non è multipagina, WordPress reindirizzerà la richiesta all'URL senza '/page/XX/'.

Questo è ciò che accade quando si assegna un nome alla variabile di query $wp_query.

La soluzione è impedire quel reindirizzamento rimuovendo la funzione responsabile per esso, che è 'redirect_canonical'agganciata a 'template_redirect':

Quindi, nel tuo functions.phpaggiungi:

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

Ora WordPress non reindirizzerà più e imposterà correttamente la 'paged'query var.

Secondo problema

next_posts_link()ed previous_posts_link()entrambi selezionano if ( ! is_single() )per visualizzare l'impaginazione.

Ora, is_single()è vero nel tuo caso, perché sei in un singolo post di tipo "autore", quindi quelle funzioni non possono funzionare come previsto.

Hai 3 possibilità:

  1. Utilizzare query_postsper ignorare l'interrogazione principale (in realtà non consigliata)
  2. Utilizza un modello di pagina personalizzato anziché un tipo di post personalizzato, perché is_single()è falso per le pagine e il tuo codice funzionerà lì.
  3. Scrivi la tua funzione di impaginazione e usala

Questo è il codice per la soluzione numero 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 ) );
}

e usalo così nel single-authors.php:

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

Risposta molto dettagliata, grazie! Funziona sul lato inglese del sito, ma sul lato francese i link di impaginazione non fanno nulla, ma aggiornano solo la pagina. Sto usando WPML.
Shane,

1
@Shane sembra quindi che WPML esegua alcuni filtri che impediscono il funzionamento del codice. Ma è un plugin così grande, e quindi non riesco a scavare migliaia di righe di codice per capire dov'è il conflitto. Prova a chiedere supporto WPML.
gmazzap

@Shane I forum di supporto di WPML - e se sopra funziona per (che presumo), quindi contrassegnalo come soluzione. Il conflitto WPML è comunque fuori tema / al di fuori dell'ambito di questo sito.
Kaiser

Risposta fantastica, soprattutto perché mi ha aiutato a risolvere il mio problema di impaginazione. Ho svolto un compito simile e ho creato un secondo WP_Query da ripetere. Ho chiamato the_posts_paginationma ho dovuto prendere una copia dell'originale wp_query come indicato in questa domanda: wordpress.stackexchange.com/questions/216821/…
Alexander Holsgrove

1
Hai ragione @HongPong, risolto, grazie.
gmazzap

0

Sulla base di un'altra domanda WPSE simile "La paginazione non funziona con i valori dei campi personalizzati di wp_query ", suggerirei di aggiungere global $paged;all'inizio del file modello:

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

1
Grazie per la risposta! Sfortunatamente non sembra fare alcuna differenza. I link di impaginazione non vengono visualizzati
Shane

1
Stephen, perché dovrebbe essere d'aiuto? Sì, questo lo porterebbe dal contesto globale, ma finora non ci stai facendo nulla. Se si desidera sovrascrivere il globale, utilizzare $GLOBALS['paged'] = get_query_var( 'paged' );. Altrimenti basta usare il contenuto globale.
Kaiser

@Shane Hmm, la pagina del modello viene utilizzata come prima pagina statica?
Stephen S.

No, viene utilizzato solo come modello di post singolo per il tipo di post personalizzato. Ho provato a cambiare la mia query da $author_querya $wp_querye che sembrava far apparire l'impaginazione, ma quando faccio clic su di essa la pagina si aggiorna e in realtà non passa alla pagina successiva, anche se ci sono più pagine. Ho aggiornato la mia risposta per riflettere tali cambiamenti.
Shane,

1
La spiegazione di php.net non è poi così male. Suggerirei solo di giocare con globale $GLOBALS. Un po 'di var_dump()alcune funzioni e stai bene. Per capirlo davvero con un po 'di tentativi / errori dovrai ca. ho bisogno di mezz'ora. Ciò ti aiuterà a comprendere meglio le funzioni rispetto alle classi e anche l'approccio OOP nel suo insieme. E ti porterà chiaramente più vicino alla comprensione degli spazi dei nomi :)
kaiser
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.