web-dev-qa-db-fra.com

Trois types d'articles différents sur la page d'accueil

Mise à jour: Merci pour la réponse, mais après avoir implémenté ce code, le thème/site est brisé. Je suis sûr que c'est moi, mais voici mon fichier functions.php:

// Custom posts for homepage
function get_featured_one() { /* returns post #1 */ }
function get_featured_two() { /* returns posts #2 and #3 */ }

add_action( 'pre_get_posts', function( $query ) {
    if ( ! $query->is_main_query() || is_admin() )
        return;

    if ( is_front_page() ) {
        $featured_one = get_featured_one();
        $featured_two = get_featured_two();

        $exclude = array_merge( wp_list_pluck( $featured_one->posts , 'ID' ), wp_list_plugk( $featured_two->posts, 'ID' ) );
        $query->set( 'post__not_in', $exclude );
    }
});

function get_featured_one() {
    return new WP_Query( array(
        'ignore_sticky_posts' => true,
        'posts_per_page' => 1,
    ) );
}

function get_featured_two() {
    return new WP_Query( array(
        'ignore_sticky_posts' => true,
        'tag' => 'featured',
        'posts_per_page' => 2,
    ) );
}

Ceci est mon fichier d'en-tête contenant le dernier message:

<section class="header-latest-post">    
    <?php if ( is_front_page() && ! is_paged() ) :
        $latest = get_featured_one();
        while ( $latest->have_post() ) : $latest->the_post();
            get_template_part('content',get_post_format());
        endwhile;
    endif; ?>
</section>
<!-- End latest post -->

Et voici le code des deux derniers posts et de la boucle standard sur la page d'accueil:

<!-- Start two featured posts -->
<section class="two-feat-posts">
    <?php if ( is_front_page() && ! is_paged() ) :
    $latest = get_featured_two();
    while ( $latest->have_post() ) : $latest->the_post();
        get_template_part('content',get_post_format());
    endwhile;
    endif; ?>
</section>
<!-- End two featured posts -->

<h4 class="main-title">Previous episodes</h4>

<!-- Start standard loop -->
<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
    <?php get_template_part('content',get_post_format()); ?>
<?php endwhile; endif; ?>
<!-- End standard loop -->

Toute aide supplémentaire serait grandement appréciée :)


Je suis en train de coder un thème et je suis tombé sur un cornichon que j'ai à moitié résolu mais que je me suis heurté à un mur.

Ce que j'essaie essentiellement de réaliser est le suivant:

  1. Le dernier message (post 1) à afficher dans la zone d'en-tête de la page d'accueil
  2. Deux poteaux décrits (poteaux 2 et 3) chacun 50% de largeur
  3. Ensuite, les postes restants dans une liste de 10 (postes 4 à 13)

J'ai la boucle principale affichant les dix posts qui compense également le dernier post (car le dernier se trouve dans la partie supérieure du site):

<?php

        $paged = (get_query_var('paged')) ? get_query_var('paged') : 1;
        $args = array (
            'post_type' => 'post',
            'posts_per_page' => '10',
            'paged' => $paged
        );

        $mainLoop = new WP_Query( $args );

        if( $mainLoop->have_posts() ) :

        while( $mainLoop->have_posts() ) : $mainLoop->the_post(); ?>

    <?php get_template_part( 'content', get_post_format() ); ?>

    <?php endwhile;

        the_posts_pagination( array(
            'mid_size'  => 2,
            'prev_text' => __( 'Previous', 'textdomain' ),
            'next_text' => __( 'Next', 'textdomain' ),
        ) );

        wp_reset_postdata();

        else : get_template_part( 'content', 'none' );

        endif;

    ?>

Voici le code de la dernière publication dans l'en-tête:

<?php
            $args = array (
                'post_type' => 'post',
                'posts_per_page' => '1'
            );

            $latestPost = new WP_Query( $args );

            if( $latestPost->have_posts() ):

            while( $latestPost->have_posts() ): $latestPost->the_post();

                 get_template_part('content',get_post_format());

             endwhile;

            endif;

            wp_reset_postdata();
        ?>

Le problème que j'ai rencontré était la pagination. Il affichait les mêmes messages sur chaque page, de sorte que j’ai mis en oeuvre ce correctif à partir du codex. le dernier message dans l'en-tête est également compensé par un et n'affiche pas le dernier message.

Je n'ai pas encore codé les deux articles en vedette, je peux donc aussi utiliser certains conseils (est-ce correct de disposer de 3 boucles personnalisées sur une page?).

Merci.

3
Garry Aylott

Étant donné que vous n'affichez pas un nombre différent de publications sur la page d'accueil et sur les pages paginées pour votre requête principale, vous n'avez pas vraiment besoin de modifier le décalage. Tout ce dont vous avez besoin est d'exclure les trois publications que vous avez déjà affichées de votre requête, ce que vous pouvez faire avec l'action pre_get_posts:

function get_featured_one() { /* returns your post #1 */ }
function get_featured_two() { /* returns your posts #2 and #3 */ }

add_action( 'pre_get_posts', function( $query ) {
    if ( ! $query->is_main_query() || is_admin() )
        return;

    if ( is_front_page() ) {
        $featured_one = get_featured_one();
        $featured_two = get_featured_two();

        $exclude = array_merge( wp_list_pluck( $featured_one->posts , 'ID' ), wp_list_plugk( $featured_two->posts, 'ID' ) );
        $query->set( 'post__not_in', $exclude );
    }
});

Puis, dans vos fichiers de modèle, supprimez simplement votre $mainLoop, car WordPress traite déjà cette requête bien avant qu’elle n’atteigne votre fichier de modèle. Il n’est donc pas nécessaire de la réexécuter. Tout ce dont vous avez besoin est d’afficher votre dernier message dans votre en-tête:

<?php if ( is_front_page() && ! is_paged() ) : ?>
    <?php $latest = get_featured_one(); ?>
    <?php while ( $latest->have_post() ) : $latest->the_post(); ?>
        <!-- Output stuff here. -->
    <?php endwhile; ?>
<?php endif; ?>

Et même chose mais get_featured_two() pour votre modèle d’archive/page de garde/index pour vos deux publications 50/50. Après cela, la boucle principale (réelle) s'occupera de tout le reste. Donc ceci est votre commande:

  • $latest->have_posts()
  • $featured->have_posts()
  • have_posts()

Pour les pages paginées, vous voudrez probablement omettre la sortie $featured, tout en maintenant ces publications exclues de la requête principale, car vous les avez déjà affichées sur votre page d'accueil. Les inclure également dans votre requête principale modifiera le nombre total de publications renvoyées par la requête principale (sur les pages paginées) et rompra la pagination.

Les deux fonctions get_featured_* doivent renvoyer un objet WP_Query:

function get_featured_one() {
    return new WP_Query( array(
        'ignore_sticky_posts' => true,
        'posts_per_page' => 1,
    ) );
}

function get_featured_two() {
    return new WP_Query( array(
        'ignore_sticky_posts' => true,
        'tag' => 'featured',
        'posts_per_page' => 2,
    ) );
}

Ils peuvent aussi probablement utiliser une mise en cache statique pour améliorer les performances, mais uniquement si vous êtes absolument certain de les appeler plusieurs fois dans une même demande, ce qui produira exactement le même résultat (c'est-à-dire, jamais utilisé dans un contexte switch_to_blog()).

Ce sera probablement aussi une bonne idée d’exclure le message renvoyé dans _one() de _two() car un message peut probablement être à la fois présenté et le plus récent.

J'ai fait quelque chose de similaire bien que un peu plus complexe dans mon thème de point-virgule. C'est plus compliqué parce que le nombre de messages doit rester le même, que les messages présentés soient collés au sommet, d'où la magie de l'offset. Mais l'idée est très similaire.

J'espère que cela pourra aider.

1
kovshenin