web-dev-qa-db-fra.com

WP_Query Pagination sur single-custom.php

Ce que je cherche à faire:

Configurez la pagination WP_Query dans un fichier de modèle single-custom-post-type-php.

Ce que j'ai fait

1) Créé un type de message appelé "auteurs". Chaque poste de ce type de poste est un auteur individuel.

2) Les pages d'écran d'édition standard contiennent un menu déroulant qui répertorie tous les articles (auteurs) à partir du type d'article personnalisé.

3) Création d'un modèle single-authors.php qui interroge toutes les publications avec les métadonnées auteur du menu déroulant. Le résultat est donc une liste de publications auxquelles le même auteur est affecté (un peu comme une archive):

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

Sur quoi je suis coincé

Les liens de pagination n'apparaissent pas. J'ai effectué des recherches et découvert qu'ils utilisaient la variable $wp_query; toutefois, lorsque j'ai modifié ma variable de requête en $wp_query, les liens sont apparus, mais aucun clic ne leur a été donné.

Une idée où je vais mal?

Modifier:

Pour répondre à certaines de vos questions, ma requête génère avec succès les publications que je cherche. $ Author_id a déjà une valeur que je n'ai pas incluse dans cet extrait de code. De même, j'ai omis le contenu réel dans la boucle while car cette partie n'est pas en cause. Le problème est que je dois paginer le contenu qui existe déjà sur cet article.

Le but de cette fonctionnalité était de permettre aux publications d'avoir des auteurs personnalisés (en dehors du système Utilisateurs intégré) et le but de ce modèle est de générer toutes les publications d'un auteur donné (qui fonctionne déjà).

13
Shane

Vous avez 2 problèmes.

Premier problème

La ligne

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

échouera, car dans une vue unique, lorsque l'URL contient '/page/XX/', la variable WordPress définit est 'page' et non 'paged'.

Vous pouvez penser à utiliser 'page' au lieu de 'paged', mais cela ne fonctionnera pas non plus, car une fois que la variable 'page' est destinée à être utilisée pour un message singulier de plusieurs pages (séparation de page à l'aide de <!--nextpage-->) et lorsque le message n'est pas multi-page, WordPress va rediriger la demande vers l'URL sans '/page/XX/'.

C'est ce qui se produit lorsque vous nommez votre variable de requête $wp_query.

La solution consiste à empêcher cette redirection en supprimant la fonction qui en est responsable, à savoir 'redirect_canonical' accroché dans 'template_redirect':

Donc, dans votre functions.php, ajoutez:

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'
            $query->set( 'page', 1 );
            $query->set( 'paged', $page );
        }
        // prevent redirect
        remove_action( 'template_redirect', 'redirect_canonical' );
    }
}, 0 ); // on priority 0 to remove 'redirect_canonical' added with priority 10

Désormais, WordPress ne redirigera plus et définira correctement la requête 'paged' var.

Deuxième problème

next_posts_link() et previous_posts_link() vérifient tous deux if ( ! is_single() ) pour afficher la pagination.

Maintenant, is_single() est vrai dans votre cas, car vous êtes dans une seule publication de type "auteur", de sorte que ces fonctions ne peuvent pas fonctionner comme prévu.

Vous avez 3 possibilités:

  1. Utilisez query_posts pour remplacer la requête principale
  2. Utilisez un modèle de page personnalisé au lieu d'un type de publication personnalisé, car is_single() est false pour les pages et votre code y travaillera.
  3. Écrivez votre propre fonction de pagination et utilisez-la

C'est le code de la solution numéro 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 we are in 1st page and required previous or in last page and required 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 ), $label );
}

et l'utiliser comme ça dans le single-authors.php:

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

Sur la base d'une autre question WPSE similaire " La pagination ne fonctionne pas pour les champs personnalisés de wp_query ", je suggérerais d'ajouter global $paged; au début de votre fichier de modèle:

global $paged;
$paged = ( get_query_var( 'paged' ) ) ? get_query_var( 'paged' ) : 1;
0
Stephen S.