2

I have a div and inside I wish display by random a post from category-a or a product from category-b. I'm looking for a query to do that.

I tried this:

 <?php
        $args = array( 
        'post_type' => array('product', 'post'), 
        'posts_per_page' => 1, 
        'cat' => 1,2, 
        'orderby' => 'RAND' 
        );

        $loop = new WP_Query( $args );       

        while ( $loop->have_posts() ) : $loop->the_post(); global $product; ?>

            <article class="promo">  

                    <div class="image">
                    <?php if (is_singular('product')){
                        echo 'Product';

                    }else{
                        echo 'Post';
                    }?>
                    </div>  


                </article>
<?php endwhile; ?>

Someone knows how to do that ? thank you :)

EDIT CODE

    <?php
$args = [
    'post_type' => ['product','post'],
    'posts_per_page' => -1,
    'fields' => 'ids',
     'post_type' => ['product','post'],
'posts_per_page' => 2,
'fields' => 'ids',
'tax_query' => [

    'relation' => 'OR',
    'taxonomy' => 'category',
    'field' => 'slug',
    'terms' => ['promo-distributeur', 'actu-distrib'],
    'include_children' => false,

]
    ]
];
$posts_ids = get_posts($args); 
$total = count($posts_ids);


if ($total > 0) { 
    $rnd = mt_rand(0, $total);
    $pid = $posts_ids[$rnd];
    $post = get_post( $pid);



while ( $post->have_posts() ) : $post>the_post(); global $product; ?>

            <article class="promo">  

                    <div class="image">
                    <?php if (is_singular('product')){
                        echo 'Product';

                    }else{
                        echo 'Post';
                    }?>
                    </div>  


                </article>
<?php endwhile;
} ?>    
5
  • You can not limit the number of posts if you want to draw one of all posts. Change 2 to -1 in 'posts_per_page' => 2. if you want two random posts, execute this code twice $rnd = mt_rand(0, $total). – nmr Jul 28 '18 at 11:41
  • Should it show only posts from cat A and products from cat B? Or can it show products from cat A also? – Krzysiek Dróżdż Jul 28 '18 at 11:49
  • @nmr I change it but same error; "WP_Post::have_posts() in L:\wamp\www\tof_sof\wp-content\themes\inumedia\template-parts\home\promos\promos.php on line 41" the error seems to be here "while ( $post->have_posts() ) : $post>the_post(); global $product; ?>" – Lust Jul 28 '18 at 15:47
  • @Lust You can't use post as WP_Query and you try to do that... – Krzysiek Dróżdż Jul 28 '18 at 15:51
  • @Lust $post variable is you WP_Post object. You can check post type that way if ($post->post_type == 'product'), get title $post->post_title. Check here – nmr Jul 28 '18 at 16:03
1

The following code selects IDs of all posts type product and post, which belong to terms category-a or category-b, with taxonomy_01 and taxonomy_02, respectively.

$args = [
    'post_type' => ['product','post'],
    'posts_per_page' => -1,
    'fields' => 'ids',
    'tax_query' => [
        'relation' => 'OR',
        [
            'taxonomy' => 'taxonomy_01',
            'field' => 'slug',
            'terms' => 'category-a',
            'include_children' => false,
        ],
        [
            'taxonomy' => 'taxonomy_02',
            'field' => 'slug',
            'terms' => 'category-b',
            // OR by id
            //'field' => 'term_id', // default value
            //'terms' => 2,
            'include_children' => false,
        ],
    ]
];
$posts_ids = get_posts($args); 
$total = count($posts_ids);
if ($total > 0) { 
    $rnd = mt_rand(0, $total - 1);
    $pid = $posts_ids[$rnd];
    $my_post = get_post( $pid);
    // display post
}

I assume that the terms category-a, category-b belongs to different taxonomies. If not, then the tax_query should be:

'tax_query' => [
    [
        'taxonomy' => 'taxonomy_01',
        'field' => 'slug',
        'terms' => ['category-a', 'category-b'],
        'include_children' => false,
    ],
]

UPDATE
I changed variable in the above code from $post to my_post. Your code:

$args = [
    'post_type' => ['product','post'],
    'posts_per_page' => -1,
    'fields' => 'ids',
    'tax_query' => [
        'relation' => 'OR',
        [
            'taxonomy' => 'taxonomy_01',
            'field' => 'slug',
            'terms' => 'category-a',
            'include_children' => false,
        ],
        [
            'taxonomy' => 'taxonomy_02',
            'field' => 'slug',
            'terms' => 'category-b',
            // OR by id
            //'field' => 'term_id', // default value
            //'terms' => 2,
            'include_children' => false,
        ],
    ]
];
$posts_ids = get_posts($args); 
$total = count($posts_ids);
if ($total > 0) {
    // get random post_ID 
    $rnd = mt_rand(0, $total - 1);
    $pid = $posts_ids[$rnd];
    $my_post = get_post( $pid);

    // display post
    if ( !empty($my_post) ) : ?>

        <article class="promo">  
            <div class="image">
            <?php 
                if ( $my_post->post_type == 'product' )
                    echo 'Product';
                else
                    echo 'Post';
            ?>
           </div>  
       </article>
   <?php endif;
}
5
  • thank you this help a lot :) I just have an error "Call to undefined method WP_Post::have_posts()" I edit my first post with your solution to see what is wrong – Lust Jul 28 '18 at 11:11
  • Wow... You really want to select all posts and then randomize them in PHP? What if there will be many many posts? – Krzysiek Dróżdż Jul 28 '18 at 11:48
  • @KrzysiekDróżdż Only the ID (not all fields) of those assigned to the category-a or category-b, as indicated in the question. – nmr Jul 28 '18 at 11:58
  • @nmr that's not what I was asking... ;) Sorry, if my question wasn't clear enough. Should it select posts from category B and products from category A also? – Krzysiek Dróżdż Jul 28 '18 at 12:09
  • @ krysiek actually this section is just "temporary posts" my customer wil use it to display some promotions on his shop, it's ephemeral products until it's out of stock for example. so I will not have lot of products in this div may be 3 or 4 maximum at the same time – Lust Jul 28 '18 at 12:10
-1

you don't need global $product, and is_singular() is a template function, not usable in the loop, also if you pick only 1 post your orderby rand will not work since the subset of records is always the same 1 element

<div class="image">
   <?php 
    if ($post->post_type=='product'){
      echo 'Product';
       }
   else{
        echo 'Post';
        }?>
 </div> 
2
  • Sorry, but the second part of your answer (regarding orderby) is simply not true. The orderby is processed before limiting posts. That’s why you can get ten last posts using orderby date or 10 first posts in alphabetical order... – Krzysiek Dróżdż Jul 27 '18 at 22:33
  • @Krzysiek Dróżdż right. sorry it was a wrong flash thought – Andrea Somovigo Jul 28 '18 at 0:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.