WordPress Transients API – Practical examples

source:http://www.catswhocode.com/blog/wordpress-transients-api-practical-examples

The WordPress Transients API is a very useful tool which allow developers to cache data such as the result of a query for future uses. In this article, I've compiled a list of useful practical example to div into the power of WordPress Transients API.


What is the transients API, and why it’s useful

Most developers who worked with WordPress in the past probably ever heard of the Options API, which allow you to save, update and delete custom values. The Transients API is pretty similar to the Options API, but with the feature of an expiration time, which simplifies the process of using the wp_options database table to store cached information.

After you read the practical example I’ve listed on this post, I suggest you to read the Transients API page on WordPress Codex.

List sites from your network

Let’s start with an interesting snippet for those who run networks of many blogs. The code below display a general menu of all sites from your networks. In this case, transients are used to store the data for a defined time (which can be set using the $expires variable on line 1) so you’ll not make huge database calls each time your menu have to be displayed.

To use this snippet, first you have to paste the function into your functions.php file.

function wp_list_sites( $expires = 7200 ) {
   if( !is_multisite() ) return false;

   // Because the get_blog_list() function is currently flagged as deprecated
   // due to the potential for high consumption of resources, we'll use
   // $wpdb to roll out our own SQL query instead. Because the query can be
   // memory-intensive, we'll store the results using the Transients API
   if ( false === ( $site_list = get_transient( 'multisite_site_list' ) ) ) {
      global $wpdb;
      $site_list = $wpdb->get_results( $wpdb->prepare('SELECT * FROM wp_blogs ORDER BY blog_id') );
      // Set the Transient cache to expire every two hours
      set_site_transient( 'multisite_site_list', $site_list, $expires );
   }

   $current_site_url = get_site_url( get_current_blog_id() );

   $html = '
<ul id="network-menu">' . "\n";

   foreach ( $site_list as $site ) {
      switch_to_blog( $site->blog_id );
      $class = ( home_url() == $current_site_url ) ? ' class="current-site-item"' : '';
      $html .= "\t" . '
<li id="site-' . $site->blog_id . '" '="" .="" $class=""><a href="' . home_url() . '">' . get_bloginfo('name') . '</a></li>

' . "\n";
      restore_current_blog();
   }

   $html .= '</ul>

<!--// end #network-menu -->' . "\n\n";

   return $html;
}

Once done, the following code will display all sites from your network. Simply paste it on any of theme files, where you want the list to be displayed.

<?php
// Multisite Network Menu
$network_menu = wp_list_sites();
if( $network_menu ):
?>
<div id="network-menu">
   <?php echo $network_menu; ?>
</div>

<!--// end #network-menu -->
<?php endif; ?>

→ Source: http://wp.smashingmagazine.com/2011/11/17/wordpress…/

Twitter followers count using WordPress transients

Many blogs, including this one, are displaying how many people are following them on Twitter. It’s quite easy to grab some json data, but it takes a significant amount of time. Using transients allow you to grab the json data from Twitter once a day, and store it in your database for future uses.

Simply paste the function below into your functions.php file:

function my_followers_count($screen_name = 'kovshenin'){
	$key = 'my_followers_count_' . $screen_name;

	// Let's see if we have a cached version
	$followers_count = get_transient($key);
	if ($followers_count !== false)
		return $followers_count;
	else
	{
		// If there's no cached version we ask Twitter
		$response = wp_remote_get("http://api.twitter.com/1/users/show.json?screen_name={$screen_name}");
		if (is_wp_error($response))
		{
			// In case Twitter is down we return the last successful count
			return get_option($key);
		}
		else
		{
			// If everything's okay, parse the body and json_decode it
			$json = json_decode(wp_remote_retrieve_body($response));
			$count = $json->followers_count;

			// Store the result in a transient, expires after 1 day
			// Also store it as the last successful using update_option
			set_transient($key, $count, 60*60*24);
			update_option($key, $count);
			return $count;
		}
	}
}

echo "I have " . my_followers_count('kovshenin') . " followers";

→ Source: http://kovshenin.com/2010/05/twitter-followers-count-snippet-for-wordpress-2253/

RSS subscribers count using WordPress transients

Using exactly the same technique as demonstrated above, we can grab RSS subscribers and store the result in WordPress database. Don’t forget to update the code with your own feedburner url on line 2. Then, paste the code where you’d like to display how many RSS feed readers you have.

function feed_subscribers(){
        $feed_url = 'http://feeds.feedburner.com/yourname';
        $count = get_transient('feed_count');
        if ($count != false) return $count;
	$count = 0;
        $data  = wp_remote_get('http://feedburner.google.com/api/awareness/1.0/GetFeedData?uri='.$feed_url.'');
   if (is_wp_error($data)) {
        return 'error';
   }else{
	$body = wp_remote_retrieve_body($data);
	$xml = new SimpleXMLElement($body);
	$status = $xml->attributes();
	if ($status == 'ok') {
		$count = $xml->feed->entry->attributes()->circulation;
	} else {
		$count = 300; // fallback number
	}
   }
	set_transient('feed_count', $count, 60*60*24); // 24 hour cache
	echo $count;
}

→ Source: https://wpsnipp.com/index.php/functions-php/get-feedburner-count-using-get_transient-and-wp_remote_get/

Cached navigation menu

Introduced in WordPress 3.0, the new menu system is definitely an improvement to WordPress. But using transients, we can even do something better, a menu with the same functionality but without the huge database requests.

<?php
/**
 * Wrapper function around wp_nav_menu() that will cache the wp_nav_menu for all tag/category
 * pages used in the nav menus
 * @see http://lookup.hitchhackerguide.com/wp_nav_menu for $args
 * @author tott
 */ 
function hh_cached_nav_menu( $args = array(), $prime_cache = false ) {
	global $wp_query;
	
	$queried_object_id = empty( $wp_query->queried_object_id ) ? 0 : (int) $wp_query->queried_object_id;
	
	// If design of navigation menus differs per queried object use the key below
	// $nav_menu_key = md5( serialize( $args ) . '-' . $queried_object_id );
	
	// Otherwise
	$nav_menu_key = md5( serialize( $args ) );
	
	$my_args = wp_parse_args( $args );
	$my_args = apply_filters( 'wp_nav_menu_args', $my_args );
	$my_args = (object) $my_args;
	
	if ( ( isset( $my_args->echo ) && true === $my_args->echo ) || !isset( $my_args->echo ) ) {
		$echo = true;
	} else {
		$echo = false;
	}
	
	$skip_cache = false;
	$use_cache = ( true === $prime_cache ) ? false : true;
	
	// If design of navigation menus differs per queried object comment out this section
	//*
	if ( is_singular() ) {
		$skip_cache = true;
	} else if ( !in_array( $queried_object_id, hh_get_nav_menu_cache_objects( $use_cache ) ) ) {
		$skip_cache = true;
	}
	//*/
	
	if ( true === $skip_cache || true === $prime_cache || false === ( $nav_menu = get_transient( $nav_menu_key ) ) ) {
		if ( false === $echo ) {
			$nav_menu = wp_nav_menu( $args );
		} else {
			ob_start();
			wp_nav_menu( $args );
			$nav_menu = ob_get_clean();
		}
		if ( false === $skip_cache )
			set_transient( $nav_menu_key, $nav_menu );
	} 
	if ( true === $echo )
		echo $nav_menu;
	else
		return $nav_menu;
}




/**
 * Invalidate navigation menu when an update occurs
 */
function hh_update_nav_menu_objects( $menu_id = null, $menu_data = null ) {
	hh_cached_nav_menu( array( 'echo' => false ), $prime_cache = true );
}
add_action( 'wp_update_nav_menu', 'hh_update_nav_menu_objects' );




/** 
 * Helper function that returns the object_ids we'd like to cache
 */
function hh_get_nav_menu_cache_objects( $use_cache = true ) {
	$object_ids = get_transient( 'hh_nav_menu_cache_object_ids' );
	if ( true === $use_cache && !empty( $object_ids ) ) {
		return $object_ids;
	}




	$object_ids = $objects = array();
	
	$menus = wp_get_nav_menus();
	foreach ( $menus as $menu_maybe ) {
		if ( $menu_items = wp_get_nav_menu_items( $menu_maybe->term_id ) ) {
			foreach( $menu_items as $menu_item ) {
				if ( preg_match( "#.*/category/([^/]+)/?$#", $menu_item->url, $match ) )
					$objects['category'][] = $match[1];
				if ( preg_match( "#.*/tag/([^/]+)/?$#", $menu_item->url, $match ) )
					$objects['post_tag'][] = $match[1];
			}
		}
	}
	if ( !empty( $objects ) ) {
		foreach( $objects as $taxonomy => $term_names ) {
			foreach( $term_names as $term_name ) {
				$term = get_term_by( 'slug', $term_name, $taxonomy );
				if ( $term )
					$object_ids[] = $term->term_id;
			}
		}
	}
	
	$object_ids[] = 0; // that's for the homepage
	
	set_transient( 'hh_nav_menu_cache_object_ids', $object_ids );
	return $object_ids;
}

→ Source: http://hitchhackerguide.com/2011/10/07/caching-wordpress-navigation-menus-wp_nav_menu-wrapper/

Cached Tag cloud

Thanks to WordPress transients API, caching almost anything is definitely. The following example shows how to cache the good old tag cloud. Simply paste this code wherever you want you tag cloud to be displayed.

$tag_cloud = get_transient( 'tag_cloud' );
if ( false === $tag_cloud || '' === $tag_cloud ){
	$args = array('echo' => false);
	$tag_cloud = wp_tag_cloud( $args );
	set_transient( 'tag_cloud', $tag_cloud, 60*60*12 );
}
echo $tag_cloud;

→ Source: http://wpengineer.com/2148/simple-cache-with-the-wordpress-transient-api/

Caching any custom query using transients

Is your theme using custom queries? If yes, you should definitely use the transients API to cache the queries. The following code shows how to cache a custom query. As you can see, there’s nothing complicated at all.

<?php
// Get any existing copy of our transient data
if ( false === ( $special_query_results = get_transient( 'special_query_results' ) ) ) {
    // It wasn't there, so regenerate the data and save the transient
     $special_query_results = new WP_Query( 'cat=5&order=random&tag=tech&post_meta_key=thumbnail' );
     set_transient( 'special_query_results', $special_query_results );
}

// Use the data like you would have normally...
?>

→ Source: http://codex.wordpress.org/Transients_API

  • I recently built one plugin using transient api. It is really awesome. i have searched a lot for this but the functions that you have listed are most useful as per my opinion.

  • It’s nice to see some more real examples. Thanks JBJ.

    For those who are interested in more examples and a bit more background, I’d like to recommend Andy Killen’s article on SpeckBoy from a couple weeks back.

    http://speckyboy.com/2011/12/14/website-speed-part-3-caching-wordpress/

    While not about transients, Parts 1 and 2 of Andy’s series are worth a go as well. Good stuff!

    Moi? The idea of transients is very intriguing. It seems to me that much of what WP does in terms of calls to the DB is often reinventing the same wheel over and over. That is, nothing has changed but the DB/server is taxed with the request. In fact, per the menu example above, it would seem to me that the WP core should make more liberal use of transients. It just makes sense, yes?

    I’d also like to suggest that with a simple function, using options can be supplemented with transients. In other words, anytime you’re using the Options API transients can be placed “in front” of that request. If the transient request comes back false/empty then fall back to the option and from there update the transients. My gawd, if you have 6 plugins and each is using options in various ways, cutting out a number of those requests would be a significant savings. (Note: I have this idea in my head but haven’t had the time to hack the code. Seems like a function of a dozen or so lines, eh?)

    But again, it would seem such functionality could be part of the WP core. That is, options and transients could be combined into a either a single API or a third API. I’m not quite sure which would be best. Or perhaps my idea is crazy? It wouldn’t be the first time I’ve been accused of such things

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值