web-dev-qa-db-fra.com

La pagination ne fonctionne pas

J'ai créé myfile.php avec le contenu suivant:

global $paged;
if ( get_query_var( 'paged' ) ) {
    $paged = get_query_var( 'paged' );
} else if ( get_query_var( 'page' ) ) {
    $paged = get_query_var( 'page' );
} else {
    $paged = 1;
}

$args = array(
    'post_type' => array('my_custom_post_type'),
    'paged' => $paged,
    'posts_per_page' => 3,
    'ignore_sticky_posts' => 1
);

$wp_query = new WP_Query( $args );
var_dump($wp_query);
if($wp_query->have_posts()) :
    while($wp_query->have_posts()) : $wp_query->the_post();
        // show post
    endwhile;
endif;

next_posts_link('Next posts');

wp_reset_query();
wp_reset_postdata();

et:

Je n'ai aucune idée de ce qui me manque ici, mais j'ai juste essayé chaque suggestion du guide de dépannage de cette page: https://codex.wordpress.org/Pagination - Ils suggèrent que "404 - non trouvé" est l’un des problèmes courants lorsque les permaliens sont définis sur "Structure personnalisée". Les développeurs WP ont donc connaissance d’un bogue ou d’un problème mais ne disent pas comment résoudre ce problème.

Mon serveur est WAMP pour Windows 7 (PHP 5.4.3, Apache 2.4.2, compatible avec mod_rewrite, les structures de liens personnalisées fonctionnent parfaitement bien lorsque le fichier "myfile.php" est utilisé comme page autre que "Page statique").

Mon .htaccess lorsque "Structure de lien permanent personnalisée" est définie sur "Nom du message":

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /wp/index.php [L]
</IfModule>

# END WordPress

Quand j'entre http://example.com/mypage/page/2 (ne fonctionne pas): SELECT wp_posts.* FROM wp_posts WHERE 1=1 AND wp_posts.post_name = 'page' AND wp_posts.post_type = 'my_custom_post_type' ORDER BY wp_posts.post_date DESC

Quand j'entre http://example.com/?page_id=1234&paged=2 (fonctionne): SELECT SQL_CALC_FOUND_ROWS wp_posts.ID FROM wp_posts WHERE 1=1 AND wp_posts.post_type = 'my_custom_post_type' AND (wp_posts.post_status = 'publish' OR wp_posts.post_status = 'private') ORDER BY wp_posts.post_date DESC LIMIT 2, 2

1
Paul

J'ai expérimenté cela avec plusieurs de mes propres plugins, tout en essayant d'afficher une pagination numérique pour mes types de publication personnalisés et mes taxonomies personnalisées.

Je crois comprendre qu'en utilisant WP_Query pour extraire les publications de la base de données selon votre propre méthode (autre que celle par défaut), vous ne pourrez pas utiliser les fonctions suivantes: attendu.

Ils sont destinés à être utilisés pour la requête de messages par défaut. Donc, si vous souhaitez utiliser ces fonctions comme prévu, vous devrez alors modifier la requête par défaut AVANT que la requête soit exécutée. Vous pouvez le faire en utilisant le hook pre_get_posts.

Toutefois, si vous souhaitez utiliser votre propre requête personnalisée à l'aide de WP_Query, vous devez également personnaliser le fonctionnement de la pagination numérique. Vous pouvez obtenir le même résultat net en utilisant les fonctionnalités standard de WordPress, mais quelques lignes de code supplémentaires sont nécessaires pour obtenir la pagination numérique comme prévu.

Supposons que votre requête personnalisée utilise WP_Query et ressemble à ceci:

$query = new WP_Query( $query_args );

Cela signifie que vous avez une requête complètement NOUVELLE qui est différente de la requête principale par défaut qui est exécutée lors du chargement de la page.

Maintenant, WordPress est conscient de deux requêtes pour la page en cours:

  1. Requête n ° 1 étant la requête par défaut .
  2. La requête n ° 2 est votre requête personnalisée que vous venez de créer à l'aide de WP_Query.

Si vous souhaitez que votre pagination numérique fonctionne avec votre requête personnalisée, vous devez connaître la page en cours sur laquelle la requête est exécutée.

Le numéro de page en cours est en fait appelé paged. Vous pouvez déterminer le numéro de page actuel en utilisant un code comme celui-ci:

$current_page = 1;

if ( get_query_var( 'paged' ) ) {
    $current_page = get_query_var( 'paged' );
}

Une fois que la page en cours a été déterminée, vous pouvez configurer votre requête personnalisée pour qu'elle ressemble à ceci:

$query_args = array(
    'post_type'      => 'products',
    'post_status'    => 'publish',
    'posts_per_page' => 10,
    'paged'          => absint( $current_page )
);

$query = new WP_Query( $query_args );

Une fois la requête effectuée, vous devez ensuite vérifier si elle a localisé dans la base de données les postes correspondant à vos critères:

if ( $query->have_posts() ) {

    while ( $query->have_posts() ) {

        $query->the_post();

        // Post content here...

    }

} else {

    // No posts...

}

Maintenant pour la pagination numérique! Je recommande d'utiliser une fonction WordPress appelée paginate_links() pour cette partie.

Je ne comprends pas vraiment la partie entière vraiment improbable pour la base, mais c'est ce qui est démontré sur la page WordPress Codex liée ci-dessus.

  • Vous devez spécifier la page actuelle (paged) - encore une fois.
  • Vous devez connaître le nombre total de publications (qui peut être obtenu à partir de l'objet variable $query).
  • Vous devez spécifier un type de retour pour cette fonction. (Personnellement, j'aime bien que ce soit au format tableau pour pouvoir personnaliser la pagination comme bon me semble).

$big = 999999999; // need an unlikely integer

$previous_text = '&laquo; Previous';
$next_text     = 'Next &raquo;';

$pagination = paginate_links( array(
    'base'      => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ),
    'format'    => '?current_page=%#%',
    'current'   => max( 1, $current_page ),
    'total'     => $query->max_num_pages,
    'type'      => 'array',
    'prev_text' => $previous_text,
    'next_text' => $next_text
) );

Ce code doit être placé dans la condition qui indique que nous avons des publications disponibles. Pas à l'intérieur de la boucle, mais immédiatement APRÈS la boucle.

Une fois la pagination numérique configurée, elle est prête à être imprimée (ou prête à être affichée). C'est ici que les éléments paginés sont retournés au format array.

J'aime l'envelopper d'une vérification conditionnelle, puis parcourir en boucle les éléments effectuant des vérifications conditionnelles supplémentaires.

if ( $pagination ) {

    $content .= '<div class="clearfix"></div>' . PHP_EOL;
    $content .= '<nav id="numerical-pagination" class="text-center">' . PHP_EOL;
    $content .= '<ul class="pagination">' . PHP_EOL;

    foreach ( $pagination as $pagination_item ) {

        $class = '';

        if ( stripos( $pagination_item, 'current' ) !== false ) {
            $class = ' class="active"';
        }

        if ( stripos( $pagination_item, 'dots' ) !== false ) {
            $class = ' class="disabled"';
        }

        $content .= '<li' . $class . '>' . $pagination_item . '</li>' . PHP_EOL;

    }

    $content .= '</ul>' . PHP_EOL;
    $content .= '</nav><!-- end #numerical-pagination .text-center -->' . PHP_EOL;
    $content .= '<div class="clearfix"></div>' . PHP_EOL;

    echo $content;

}

Remarque: J'utilise Bootstrap pour mes thèmes WordPress. Donc, si vous voulez que votre pagination soit géniale, avec un minimum d'effort. Essayez Bootstrap .

Pour conclure avec tout ce qui précède, voici une solution de départ tout-en-un copier/coller pour tous ceux qui souhaitent créer une pagination numérique avec une requête personnalisée en utilisant WP_Query.

$current_page = 1;

if ( get_query_var( 'paged' ) ) {
    $current_page = get_query_var( 'paged' );
}

$query_args = array(
    'post_type'      => 'products',
    'post_status'    => 'publish',
    'posts_per_page' => 10,
    'paged'          => absint( $current_page )
);

$query = new WP_Query( $query_args );

if ( $query->have_posts() ) {

    while ( $query->have_posts() ) {

        $query->the_post();

        // Post content here...

    }

    $big = 999999999; // need an unlikely integer

    $previous_text = '&laquo; Previous';
    $next_text     = 'Next &raquo;';

    $pagination = paginate_links( array(
        'base'      => str_replace( $big, '%#%', esc_url( get_pagenum_link( $big ) ) ),
        'format'    => '?current_page=%#%',
        'current'   => max( 1, $current_page ),
        'total'     => $query->max_num_pages,
        'type'      => 'array',
        'prev_text' => $previous_text,
        'next_text' => $next_text
    ) );

    $content = '';

    if ( $pagination ) {

        $content .= '<div class="clearfix"></div>' . PHP_EOL;
        $content .= '<nav id="numerical-pagination" class="text-center">' . PHP_EOL;
        $content .= '<ul class="pagination">' . PHP_EOL;

        foreach ( $pagination as $pagination_item ) {

            $class = '';

            if ( stripos( $pagination_item, 'current' ) !== false ) {
                $class = ' class="active"';
            }

            if ( stripos( $pagination_item, 'dots' ) !== false ) {
                $class = ' class="disabled"';
            }

            $content .= '<li' . $class . '>' . $pagination_item . '</li>' . PHP_EOL;

        }

        $content .= '</ul>' . PHP_EOL;
        $content .= '</nav><!-- end #numerical-pagination .text-center -->' . PHP_EOL;
        $content .= '<div class="clearfix"></div>' . PHP_EOL;

        echo $content;

    }

    wp_reset_postdata();

} else {
    // No posts...
}

wp_reset_query();
1
Michael Ecklund

Vous pouvez également essayer le code ci-dessous.

function custom_type_archive_display($query) {

    if (is_post_type_archive('custom_post_type') )
    {
        $query->set('posts_per_page',10);
        return;
    }
}

add_action('pre_get_posts', 'custom_type_archive_display');
0
Jigar Gorakhiya