web-dev-qa-db-fra.com

Passer le message en boucle et mixer plus tard

Dans le blog, j'essaie d'éviter d'afficher successivement deux articles de la même catégorie. Donc, si les deux derniers articles appartiennent à la catégorie 1, je veux sauter le second, prendre l’article 3 d’abord (s’il ne fait pas partie de la catégorie 21 non plus), puis mélanger l’article ignoré avant d’afficher le numéro 4.

Donc ce que j'ai est

while (have_posts()) : the_post();

    //get category of post
    $categories = get_the_category();
    $category_id = $categories[0]->cat_ID; 

    //set flag to know, when there was a post form category 1
    if ($flag == true && ($category_id == 1)) {

        //store post to use later
        ....

        continue;
    }

    if ($category_id == 1)
        $flag = true;
    else
        $flag = false;

}

Quelqu'un a une idée?

5
sinini

Qu'en est-il d'une approche comme celle-ci:

$first_category_args = array(
    // category id
    'cat'                 => 123,
    // get all from cat
    'posts_per_page'       => -1,
    // don't prepend sticky
    'ignore_sticky_posts' => 1,
    // only return ids
    'fields'              => 'ids'
);
// array of ids
$first_category_query = new WP_Query(
    $first_category_args
);
$first_category_ids = $first_category_query->posts;

$second_category_args = array(
    // category id
    'cat'                 => 456,
    // get all from cat
    'posts_per_page'       => -1,
    // don't prepend sticky
    'ignore_sticky_posts' => 1,
    // only return ids
    'fields'              => 'ids'
);
// array of ids
$second_category_query = new WP_Query(
    $second_category_args
);
$second_category_ids = $second_category_query->posts;

// count    
$first_category_ids_count  = count( $first_category_ids );
$second_category_ids_count = count( $second_category_ids );

// set count to the greater one    
if ( $first_category_ids_count > $second_category_ids_count ) {
    $count = $first_category_ids_count;
} else {
    $count = $second_category_ids_count;
}

$combined_alternating_category_ids = array();

// create combined alternating array of ids
for ( $c = 0; $c < $count; $c++ ) {
    if ( isset( $first_category_ids[ $c ] ) ) {
        $combined_alternating_category_ids[] = $first_category_ids[ $c ];
    }
    if ( isset( $second_category_ids[ $c ] ) ) {
        $combined_alternating_category_ids[] = $second_category_ids[ $c ];
    }
}

// now do a query with the combined result
$combined_category_args = array(
    // get post by created alternating ids array
    'post__in' => $combined_alternating_category_ids,
    // we're ordering by the order the ids have in the array
    'orderby'  => 'post__in'
);
$combined_query = new WP_Query(
    $combined_category_args
);

// proceed with a loop
if ( $combined_query->have_posts() ) {
    while ( $combined_query->have_posts() ) {
        $combined_query->the_post();
        // show post code
    }
} else {
    // no post code
}

wp_reset_postdata();

Juste comme une idée, n'ont pas testé cela, lui a donné un test rapide, fonctionne comme prévu.


Pour modifier la requête principale, vous pouvez faire:

function wpse163419_alternate_order_array() {
    $first_category_args = array(
        // category id
        'cat'                 => 1,
        // get all from cat
        'posts_per_page'       => -1,
        // only return ids
        'fields'              => 'ids'
    );
    // array of ids
    $first_category_query = new WP_Query(
        $first_category_args
    );
    $first_category_ids = $first_category_query->posts;

    $second_category_args = array(
        // category id
        'cat'                 => 3,
        // get all from cat
        'posts_per_page'       => -1,
        // only return ids
        'fields'              => 'ids'
    );
    // array of ids
    $second_category_query = new WP_Query(
        $second_category_args
    );
    $second_category_ids = $second_category_query->posts;

    // count    
    $first_category_ids_count  = count( $first_category_ids );
    $second_category_ids_count = count( $second_category_ids );

    // set count to the greater one    
    if ( $first_category_ids_count > $second_category_ids_count ) {
        $count = $first_category_ids_count;
    } else {
        $count = $second_category_ids_count;
    }

    $combined_alternating_category_ids = array();

    // create combined alternating array of ids
    for ( $c = 0; $c < $count; $c++ ) {
        if ( isset( $first_category_ids[ $c ] ) ) {
            $combined_alternating_category_ids[] = $first_category_ids[ $c ];
        }
        if ( isset( $second_category_ids[ $c ] ) ) {
            $combined_alternating_category_ids[] = $second_category_ids[ $c ];
        }
    }

    return $combined_alternating_category_ids;
}

add_action( 'pre_get_posts', 'wpse163419_cat_alternate_order' );
function wpse163419_cat_alternate_order( $query ) {
    // avoid infinite loop
    remove_action( 'pre_get_posts', __FUNCTION__ );
    // get ids
    $combined_alternating_category_ids = wpse163419_alternate_order_array();
    // set query parameter
    if ( ! is_admin() && $query->is_main_query() ) {
        $query->set( 'post__in', $combined_alternating_category_ids );
        $query->set( 'orderby', 'post__in' );
        $query->set( 'posts_per_page', '-1' );
    }
}
2
Nicolai

Ceci stocke une variable pour vérifier si le dernier post affiché était dans la catégorie 1. Si le prochain post est également dans la catégorie 1, il l’ajoute à un tableau de posts stockés.

Cela vous permet de stocker plusieurs messages au cas où vous auriez plusieurs messages de catégorie 1 à la suite.

Enfin, il crache toutes les publications stockées si vous avez atteint le dernier élément de la boucle.

    $prev_cat1 = '';
    $count = 0;
    $stored_posts = array();

    while (have_posts()) : the_post();

        // Starting counting posts so we know if we reach the end of the loop
        $count++;

        // Check if post is in category 1
        $categories = wp_get_post_categories();
        if(in_array('1', $categories)){
            $cat1 = true;
        }else{
            $cat1 = false;
        }

        //check if previous post category is the same
        if ($cat1 && $prev_cat1) {

            // Store the post ID and category in an array for later use (must use array in case there are multiple posts in a row with same category)
            $stored_posts[] = get_the_ID();

        }else{

            // YOUR POST CONTENT

            // Specify whether or not this post was in category 1
            if($cat1) $prev_cat1 = true;
            else $prev_cat1 = false;

        }

        // Check if there is a stored post AND that the previous displayed post was not in category 1
        if(!empty($stored_posts) && !$prev_cat1){

             // YOUR POST CONTENT
             // make sure to specify the post ID since you're not using the current post in the loop, eg. echo get_the_title($postID);

            // Remove that post from the stored posts array
            array_shift($stored_posts);

            // Specify that last printed post was in category 1
            $prev_cat1 = true;

        }

        // If this was the last post in the loop, just output the remaining stored posts
        if($count == sizeof($posts)){
            foreach($stored_posts as $post){

                // YOUR POST CONTENT (same note as above about specifying the post ID)

            }
        }
    }
1
jetlej

En fin de compte, j'ai fait deux requêtes, la première pour obtenir les identifiants des publications et la seconde pour restituer les publications dans le type de tri souhaité:

$flag = false;

//arguments for first query
$args = array(
        'post_type' => 'post',
        'posts_per_page' => 500,
);

$query = new WP_Query($args);

//make first query only to get the ids
while ($query->have_posts()) : $query->the_post();

    //get category of post
    $categories = get_the_category();
    $category_id = $categories[0]->cat_ID;          

     if (($category_id == 1)) {

        //if it is second appearence of cat1 post
        $postToSave[] = $post->ID;
        $flag = true;

    } else if ($flag == true && ($category_id != 1)) {

        //if flag is true, mixin from array
        $defaultPost[] = $post->ID;

        if (!empty($postToSave)) {
            $idSavedPosts = array_shift($postToSave);
            $defaultPost[] = $idSavedPosts;
            $flag = true;
        }

    } else if ($flag == false && ($category_id != 1)) {

        // flag is false, just add no normal array
        $defaultPost[] = $post->ID;
        $flag = false;

        if (!empty($postToSave)) {
            $idSavedPosts = array_shift($postToSave);
            $defaultPost[] = $idSavedPosts;
        }
    }

endwhile;

et le second avec ces arguments:

$args2 = array(
        'post_type' => 'post',
        'posts_per_page' => 12,
        'paged' => ( get_query_var('paged') ? get_query_var('paged') : 1),
        'post__in' => $defaultPost,
        'orderby' =>'post__in'
);

Merci de votre aide! M'a amené dans la bonne direction

1
sinini