4

How do I create a random post but it shouldnt be change when the page is refreshed

I want a random post that will last for a day and after 24 hours or a day, it will change randomly the post , will be that possible? or are there a plugin that exactly does that ,

actually what Im trying to create is like a "Random Tip For the Day", you know something like that

I hope someone understand my question

please help,any help will be appreciated.

4 Answers 4

4

Here is some code doing what you've asked and using the ideas others have highlighted:

<?php
if ( false === ( $totd_trans_post_id = get_transient( 'totd_trans_post_id' ) ) ) {
     $args = array('numberposts' => 1, 'orderby' => 'rand');
     $totd = get_posts($args);
     $midnight = strtotime('midnight +1 day');
     $timenow = time();
     $timetillmidnight = $midnight - $timenow;
     echo $midnight;
     echo ",".$timenow;
     set_transient('totd_trans_post_id', $totd[0]->ID, $timetillmidnight);
} else {
    $args = array('post__in' => array($totd_trans_post_id));
    $totd = get_posts($args);
}

foreach( $totd as $post ) : setup_postdata($post); ?>
    <div>
        <a href="<?php the_permalink(); ?>"><?php the_title(); ?></a>
        <?php the_content(); ?>
    </div>
<?php endforeach; ?>

get_posts() help Plus the way I have coded it should make the Tip of the Day post change at midnight every day.

This can be improved upon because we are showing random there is nothing stopping the same post showing twice in a row...

14
  • @Brady, Ive tried your code , but it doesnt show up any output? can you help me please..
    – nold
    Commented May 16, 2011 at 12:23
  • @user2210 - It wont show any output. You need to know make up the code that shows the post held in variable $totd use the examples found in the link in my answer.
    – Scott
    Commented May 16, 2011 at 12:54
  • this is what I do to output the code pastebin.com/stxDEPTX
    – nold
    Commented May 16, 2011 at 13:06
  • Im really noob sometimes at wordpress , can you confirm that my code is correct (see link above). Any hints? Im finding solutions for hours and still dont know how to solve this..any help will be appreciated man.
    – nold
    Commented May 16, 2011 at 13:16
  • @user2210 the code you have should work. Please hold while I hunt down why the code may not be working
    – Scott
    Commented May 16, 2011 at 13:26
5

A transient seems like a lot of extra effort. Instead, just use the fact that MySQL's RAND function can be seeded for reproducible random numbers.

Use a function like this:

function force_random_day_seed($orderby) {
    $seed = floor( time() / DAY_IN_SECONDS );
    $orderby=str_replace('RAND()', "RAND({$seed})", $orderby);
    return $orderby;
}

Then, around your WP_Query or get_posts or whatever it is that you have retrieving this single post, use this filter code:

add_filter('posts_orderby', 'force_random_day_seed');
$args = array('numberposts' => 1, 'orderby' => 'rand');
$totd = get_posts($args);
remove_filter('posts_orderby', 'force_random_day_seed');

This adds the filter, gets the post, then removes the filter.

By setting the seed to a number that changes once a day, then the random will produce the same answer every time for that day. Then it will give a different random number every DAY_IN_SECONDS goes by.

No transients, no need for storage of data.

Update for WordPress 4.5+

Ordering by random, containing a seed value, is now supported in WordPress 4.5+:

$rand = sprintf( 'RAND(%d)', floor( time() / DAY_IN_SECONDS ) );
$args = array( 'numberposts' => 1, 'orderby' => $rand );
$totd = get_posts($args);

See ticket #35692 for more information.

5
  • I couldn't get this script to work. I had success with the code from the accepted answer but this one looks so much cleaner. My problem is that the post randomizes every page load. I did specify a time in the function.
    – Tony Fire
    Commented Jan 21, 2014 at 0:39
  • This code works. I tested it when I wrote it.
    – Otto
    Commented Jan 21, 2014 at 2:29
  • Any idea why it keeps changing every page load? I assume that means problem on the function side. But I'm using the same code. Only difference is that I replaced DAY_IN_SECONDS with (60*60*24). Maybe I should post a new question instead?
    – Tony Fire
    Commented Jan 21, 2014 at 12:55
  • Is there any chance to get the same effect but "every 3 days"?
    – Peanuts
    Commented Sep 5, 2016 at 19:52
  • Also, would changing DAY_IN_SECONDS to WEEK_IN_SECONDS suffice to retrieve the random post weekly? Thanks for any clarification!
    – Peanuts
    Commented Sep 5, 2016 at 20:29
4

You can use the Transients API, as kaiser said. Just store a random post ID with a lifetime of 24h. To select a random post you can set the orderby argument of get_posts() to "rand".

Use case example:

function wpse17056_twentyfour_sticky_post()
{
    $transient = get_transient( 'twentyfour_sticky_post' );

    // set transient if none is present    
    if ( false === $transient ) 
    {
        $rand_post = get_posts( array( 'numberposts' => 1, 'orderby' => 'rand') ); 
        set_transient( 'twentyfour_sticky_post', $rand_post[0]->ID, DAY_IN_SECONDS );
    }
}
add_action( 'init', 'wpse17056_twentyfour_sticky_post', 0 );
2
  • 1
    i hope you don't mind that i extended your answer with an example. You just got below 2.000 rep points which are needed to edit Qs without moderators. I just try to help you reach the limit faster :) Feel free to further modify (I never used the transient API anywhere myself.) or revert it.
    – kaiser
    Commented May 12, 2011 at 16:11
  • @kaiser — I don't mind at all. Thank you!
    – Geert
    Commented May 12, 2011 at 16:21
1

Interact with the Transients API. You could attach something like "sticky" to it or a specific category or term.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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