web-dev-qa-db-fra.com

Comment afficher le nombre Y de messages personnalisés après chaque X messages normaux?

J'ai une boucle dans une boucle. J'ai compris comment afficher tout ou X nombre de messages personnalisés après le nombre Y de messages normaux. J'ai également compris comment afficher 1 message personnalisé après chaque Y message normal. Comment puis-je afficher X messages personnalisés après CHAQUE Y nombre de messages normaux.

En termes simples. Comment afficher 2 posts de livre (type de post personnalisé) après 4 envois de blog? Comment peut-on extraire plus d'un message à la fois de la boucle?

c’est la logique des x messages personnalisés après les y messages normaux. Comment puis-je obtenir x messages personnalisés après TOUTES les publications normales?

main query // normal query
$k=0 // setting iterator
while have posts, the post

---post markup---


if($k == 4 or $k % 4 == 0) { // whether after x number or after every x number
second query // using WP_Query
while second query has posts, the posts

---custom post type markup // I NEED TO SHOW MORE THAN ONE HERE IF IT IS AFTER EVERY X blogposts

endwhile; //second query ends

}

$k++;
endwhile // main query
5
thedigitalmonk

Voici une idée:

Définitions:

  • Publications par page: PPPname__
  • Type d'article personnalisé: Yname__
  • Type de poste de requête principal: Xname__
  • Combien de Yà injecter à chaque fois: yname__
  • Combien de messages Xà afficher avant d'injecter les messages Yname__: xname__

Formule:

Nous utiliserons:

    PPP(Y) = y * floor( ( PPP(X) -1 ) / x )

PPP(X), xet ysont positifs.

Exemples:

Configuration 1:

PPP(X)=1, x=3, y=2, PPP(Y) = 2 * floor( (1-1)/3 ) = 2 * 0 = 0
Loop: X 

Configuration 2:

PPP(X)=3, x=3, y=2, PPP(Y) = 2 * floor( (3-1)/3 ) = 2 * 0  = 0
Loop: XXX

Configuration 3:

PPP(X)=4, x=3, y=2, PPP(Y) = 2 * floor( (4-1)/3 ) = 2 * 1  = 2
Loop: XXX YY X      

Configuration 4:

PPP(X)=11, x=3, y=2, PPP(Y) = 2 * floor( (11-1)/3 )  = 2 * 3 = 6
Loop: XXX YY XXX YY XXX YY XX        

Configuration 5:

PPP(X)=12, x=3, y=2, PPP(Y) = 2 * floor( (12-1)/3 ) = 2 * 3 = 6
Loop: XXX YY XXX YY XXX YY XXX      

Configuration 6:

PPP(X)=13, x=3, y=2, PPP(Y) = 2 * floor( (13-1)/3 ) = 2 * 4 = 8 
Loop: XXX YY XXX YY XXX YY XXX YY X     

Stratégie:

Essayons de trouver un moyen d'injecter les articles Ydans la boucle de Xname__, sans modifier directement les fichiers de modèle.

Nous voulons nous associer à l'action loop_start pour la requête principale du type de message Xet récupérer les articles PPP(Y) de type Yname__.

Ensuite, nous voulons utiliser le hook the_post pour afficher:

get_template_part( 'content', 'y' );

Nous pouvons utiliser par exemple les propriétés current_post et posts_per_page de l'objet $wp_query principal pour contrôler la logique d'injection.

Je pense qu'il est plus facile d'appeler WP_Query() pour chaque injection, mais nous nous contentons de l'appeler seulement une fois avant la boucle principale.

La mise en oeuvre:

Créez un fichier pièce modèle dans le répertoire de votre thème actif, par exemple content-page.php, contenant:

<article>
    <header class="entry-header">
        <h2 class="entry-title"><?php the_title(); ?></h2>
    </header>
    <div class="entry-content">
        <?php the_content(); ?>
    </div>
</article>

Ensuite, vous pouvez essayer ce qui suit:

add_action( 'wp', function(){

    // We want the injection only on the home page:
    if( ! is_home() ) return;

    // Start the injection:
    $inject = new WPSE_Inject( array( 
        'items_before_each_inject' => 3, 
        'cpt_items_per_inject'     => 2, 
        'cpt'                      => 'page',
        'template_part'            => 'content-page',
        'paged'                    => ( $pgd = get_query_var( 'paged' ) ) ? $pgd : 1,       
    ) );
    $inject->init();
});

et le modifier à vos besoins.

La classe WPSE_Inject est définie comme suit:

/**
 * class WPSE_Inject
 *
 * Inject custom posts into the main loop, through hooks, 
 * with only a single WP_Query() call
 *
 * @link http://wordpress.stackexchange.com/a/141612/26350
 *
 * Definitions:
 *      Posts per page: PPP
 *      Custom post type: Y
 *      Main query post type: X
 *      How many Y posts to inject: y
 *      How many X posts to display before injecting the Y posts: x
 *
 * Formula:
 *      PPP(Y) = y * floor( ( PPP(X) -1 ) / x ) 
 *          where PPP(X), x and y are positive
 */

class WPSE_Inject
{   
    protected $results       = NULL;
    protected $query         = NULL;
    protected $nr            = 0;
    protected $inject_mode   = FALSE;
    protected $args          = array();

    public function __construct( $args = array() )
    {
        $defaults = array( 
            'items_before_each_inject' => 5, 
            'cpt_items_per_inject'     => 1, 
            'cpt'                      => 'post', 
            'paged'                    => 1, 
            'template_part'            => 'content-post'
        );
        $this->args = wp_parse_args( $args, $defaults );
    }

    public function init()
    {
        add_action( 'loop_start', array( $this, 'loop_start' ) );
        add_action( 'loop_end',   array( $this, 'loop_end'   ) );
    }

    public function cpt_items_on_this_page( WP_Query $query )
    {
        $count =  $this->args['cpt_items_per_inject'] * floor( ( $query->get( 'posts_per_page' ) -1 ) / $this->args['items_before_each_inject'] );
        return ( $count > 0 ) ? $count : 1;
    }

    public function loop_start( WP_Query $query )
    {
        $this->query = $query;

        if( $query->is_main_query() )
        {               
            $args = array( 
                'post_type'        => $this->args['cpt'], 
                'posts_per_page'   => $this->cpt_items_on_this_page( $query ), 
                'paged'            => $this->args['paged'], 
                'suppress_filters' => TRUE, 
            );
            $this->results = new WP_Query( $args );
            add_action( 'the_post', array( $this, 'the_post' ) );
        }
    }

    public function loop_end( WP_Query $query )
    {
        if( $query->is_main_query() )
            remove_action( 'the_post', array( $this, 'the_post' ) );
    }

    public function the_post()
    {           
        if( ! $this->inject_mode        
            && 0 < $this->nr 
            && 0 === $this->nr % $this->args['items_before_each_inject'] )
        {    
            $this->inject_mode = TRUE;          
            $this->results->rewind_posts();
            $this->results->current_post = ( absint( $this->nr / $this->args['items_before_each_inject'] ) -1 ) * $this->args['cpt_items_per_inject'] - 1;
            $j = 1;
            if ( $this->results->have_posts() ) :
                while ( $this->results->have_posts() ) :
                    $this->results->the_post();
                    get_template_part(  $this->args['template_part'] );
                    if( $this->args['cpt_items_per_inject'] < ++$j )
                        break;

                endwhile;
                wp_reset_postdata();
            endif;
            $this->inject_mode = FALSE;
        }

        if( ! $this->inject_mode )
            $this->nr++;

    }
}

J'ai testé cela sur le thème par défaut, où j'ai injecté le contenu pagedans la boucle principale postname__. La pagination semblait également fonctionner.

Cela peut être affiné davantage, mais j'espère que c'est un point de départ pour vous.

10
birgire