Try Tuts+ Premium, Get Cash Back!
Working With Changing, Cacheable Data? WP-Transients Has Got Your Back!

Working With Changing, Cacheable Data? WP-Transients Has Got Your Back!

Tutorial Details
  • Program: WordPress
  • Difficulty: Easy
  • Estimated Completion Time: 40 minutes

Changing data is ever present in a WordPress-powered site. Be it a new post, an added comment, or an updated tweet for the front page, the status of a blog is constantly being altered. Since such data is often useful to a visitor, there comes a need to display it. This, however, is plagued by the fact that dynamic information—especially from external sources—results in slower, burdened sites. When it comes to these issues, the WordPress Transient API has you covered with its robust caching. The following screencast will demonstrate exactly how to take advantage of its features.


Screencast


Step 1 Get the Transient by Name

Access a transient by passing a name to the get_transient() function. Don’t worry; even though you haven’t created one yet, this is still the first step! For our example, we’ll be getting a Twitter follower count.

$transient = 'wptuts_twitter_follower_count';
$count = get_transient( $transient );

Step 2 Check if the Transient Has Expired

If the return value of get_transient() is false, the transient has either expired (based on the time parameter explained in step 3) or was never set in the first place:

if( false === $count )
{
    // transient has expired; proceed to step 3
}

Step 3 If Expired, Set the Transient

Expired

When a transient expires, it needs to be reset; in other words, the data needs to be refreshed. To accomplish this, first retrieve the new data. In this case, get the follower count via the Twitter API as per the video:

$data = @file_get_contents( 'http://api.twitter.com/1/users/lookup.json?screen_name=envatowp' );
$json = json_decode( $data );

if( $json && isset( $json[0] ) && isset( $json[0]->followers_count ) )
    $count = (int) $json[0]->followers_count;

Now store it by using the set_transient() function. Note that this requires a name, value, and expiry time in seconds as parameters. After this time has elapsed, get_transient() will return false and trigger this step again:

// expire in 1 day ( 60 seconds/minute * 60 minutes/hour * 24 hours/day = seconds/day )
set_transient( $transient, $count, 24 * 60 * 60 );

Step 4 Put it All Together

Together

Combining this into one function yields:

function twitter_follower_count()
{
    $transient = 'wptuts_twitter_follower_count';
    $count = get_transient( $transient );

    if( false === $count )
    {
        $data = @file_get_contents( 'http://api.twitter.com/1/users/lookup.json?screen_name=envatowp' );
        $json = json_decode( $data );

        if( $json && isset( $json[0] ) && isset( $json[0]->followers_count ) )
        {
            $count = (int) $json[0]->followers_count;
            set_transient( $transient, $count, 24 * 60 * 60 );
        }
    }

    return $count;
}

The follower count not only is available for use anywhere on your site, but it is also efficiently cached each day to curb load times.


Final Code From the Video

The final code from the screencast—with a few modifications—is included below:

class WPTuts_Transients
{

    public function WPTuts_Transients()
    {

    }

    public function twitter_follower_count()
    {
        return $this->process_transient( 'wptuts_twitter_follower_count', array( $this,
            'refresh_twitter_follower_count' ), 24 * 60 * 60 );
    }

    public function refresh_twitter_follower_count()
    {
        $data = @file_get_contents( 'http://api.twitter.com/1/users/lookup.json?screen_name=envatowp' );
        $json = json_decode( $data );

        $count = false;
        if( $json && isset( $json[0] ) && isset( $json[0]->followers_count ) )
            $count = (int) $json[0]->followers_count;

        return $count;
    }

    public function twitter_recent_tweets()
    {
        return $this->process_transient( 'wptuts_twitter_recent_tweets', array( $this,
            'refresh_twitter_recent_tweets' ), 24 * 60 * 60 );
    }

    public function refresh_twitter_recent_tweets()
    {
        $data = @file_get_contents( "http://api.twitter.com/1/statuses/user_timeline.json?screen_name=envatowp&count=5&trim_user=true&exclude_replies=true" );
        $json = json_decode( $data );

        $tweets = false;
        if( $json )
            $tweets = $json;

        return $tweets;
    }

    public function feedburner_subscriber_count()
    {
        return $this->process_transient( 'wptuts_feedburner_subscriber_count', array( $this,
            'refresh_feedburner_subscriber_count' ), 24 * 60 * 60 );
    }

    public function refresh_feedburner_subscriber_count()
    {
        $data = @file_get_contents( 'https://feedburner.google.com/api/awareness/1.0/GetFeedData?uri=wptuts' );

        $count = false;
        if( preg_match( '~circulation="(\d+)"~', $data, $matches )
                && isset( $matches[1] ) )
            $count = (int) $matches[1];

        return $count;
    }

    private function process_transient( $transient, $refresh, $time )
    {
        $data = get_transient( $transient );

        if( false === $data )
        {
            if( is_callable( $refresh ) )
            {
                $data = call_user_func( $refresh );
                set_transient( $transient, $data, $time );
            }
        }

        return $data;
    }

}

Thanks

I hope that this has been helpful tutorial on the WordPress Transient API. Please feel free to leave your comments below.

Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • Pingback: About | Growing Tomatoes In Containers

  • http://michaelbeckwith.me Michael Beckwith

    Wouldn’t have been the worst idea to use wp_remote_get() instead of file_get_contents(). Using built in WordPress functions is generally a pretty good idea.

  • http://kovshenin.com Konstantin Kovshenin

    Good tutorial, but I have one comment. WordPress has a very solid API for working with HTTP requests that are good wrappers around several available transports including Curl and PHP sockets and streams, so why are you using file_get_contents? Go for wp_remote_get, wp_remote_retrieve_body and always double-check with is_wp_error instead of suppressing errors using the @ prefix :)

    ~ Konstantin

  • http://www.obenlands.de/en/ Konstantin

    Hi Karthik,

    why don’t you use WordPress’ HTTP API?

  • http://davgothic.com David Hancock

    About time developers were made aware of the Transients API. Been using it in all my plugins that require data to be cached.

    Would like to reiterate @Konstantin comment though. Use HTTP API, WordPress has already took care of exceptions and various fallback transport protocols for you.

  • daanVOS

    great quality screencast! very helpful.

  • http://twitter.com/drale2k Drazen Mokic

    Please use at least 720p for screencasts :)

  • http://lowgravity.pl Kamil Grzegorczyk

    Very nice tutorial but why it is an object after all? Its nothing more than a static class.

  • http://lowgravity.pl Kamil Grzegorczyk

    And one more question, I forgot about this. What happens if transient expires, You are trying to get new data from remote service, but the service is unavailable (nothing uncommon in longer time range). Finally we end up with nothing?

    In my current plug-ins I’m using my own cache system which deletes stuff on expiry only when we new data exists because I think its better to show people old followers count (for example) than to show nothing until the remote service works again.

    With all said above I also thing that if its a WP plug-in then I should utilize WP built in stuff. How would You deal with such situations? Now I only think about some pre-expires checks. For example to set transient for two days but make cache refreshes on a daily manner.

    What do You think?

    • Mamod

      Good point +1, I may start making a plugin for this functionality

  • http://www.facebook.com/mittul.chauhan Mittul Chauhan

    very usefull in deed ..many thanks from India…