Shortcode to show thumbnail and link for 3 random posts
-
15-04-2021 - |
Question
I want to have a small header at the top of a page showing the featured images with a link to the related custom post type.
This is my code:
// Creates random image header within tax called(defaults to residential).
add_shortcode( 'rt-random-projects', 'rt_random_projects' );
function rt_random_projects($atts) {
$a = shortcode_atts( array(
'category' => 'residential',
),
$atts
);
$query = new WP_Query(
array(
'post_type' => 'jf_projects',
'posts_per_page' => '3',
'orderby' => 'RAND',
'tax_query' => array(
array(
'taxonomy' => 'project_types',
'field' => 'slug',
'terms' => $a['category'],
)
)
)
);
$count = $query->post_count;
$projects ='<div>';
while ( $query->have_posts() ) : $query->the_post();
$projects .= '<div class="projectheaderimg"><a href="'.get_the_permalink().'">'.get_the_post_thumbnail('','small').'</a></div>';
endwhile; //end while posts
$projects .='</div>';
wp_reset_postdata();
// Code
return $projects;
}
This brings up my images and links to the posts, but it isn't random. No matter what I do it still shows only the same 3 posts. How can I make it pull 3 random posts?
Solution
Starting from WordPress version 4.5, you can use RAND(seed)
with the orderby
parameter.
However, when the value is simply RAND
(i.e. the uppercase of rand
), WP_Query
ignores it and defaults to the default sorting (which is by the post date).
I've confirmed that by inspecting the $query->request
:
With
'orderby' => 'RAND'
, theORDER BY
clause isORDER BY wp_posts.post_date DESC
.With
'orderby' => 'rand'
, theORDER BY
clause isORDER BY RAND()
.
So the solution is simple: Always use rand
, unless you want to use a seed.
OTHER TIPS
More than likely this is a problem with your host. A lot of the big name managed WP hosting companies disable orderby random by default. If they are good (WPEngine) you can reach out to their support and get that enabled. If they suck (GoDaddy) you might have less luck with that request.
If that's the case then you will need to write a function to get all the posts, assign each a random number and then order those by that number and pick the top n posts that way. Which is exactly as slow and bad as it sounds.