Development

Display Likes, Tweets, Page Views, and Comment Counts in Posts

get-social-dataHere at WebDevStudios we do a bunch of heavy lifting for clients. It’s rare for us to install “XYZ plug-in” and call it a day. One client wanted to display likes, tweets, page views, and comment counts, via custom buttons, for about twenty posts on the homepage. Talk about some overhead! I needed to find a fast solution, fast.

Immediately I got to work investigating how to grab all of this social data. To my surprise, I could not find a single resource that spelled it out. I spent hours on Google and StackOverflow and I’m happy to share my findings – all in one place.

To meet the clients needs, I needed to:

  1. Query each respective social network’s API with the post permalink
  2. Bail if there is an error
  3. Receive results in either JSON or XML form
  4. Parse the results and extract our “total count”
  5. Store the total count in transient cache
  6. Finally, write the total count into our HTML

Get total number of Tweets

/**
 * Get tweet count from Twitter API (v1.1)
 */
function wds_post_tweet_count( $post_id ) {

  // Check for transient
  if ( ! ( $count = get_transient( 'wds_post_tweet_count' . $post_id ) ) ) {

    // Do API call
    $response = wp_remote_retrieve_body( wp_remote_get( 'https://cdn.api.twitter.com/1/urls/count.json?url=' . urlencode( get_permalink( $post_id ) ) ) );

    // If error in API call, stop and don't store transient
    if ( is_wp_error( $response ) )
      return 'error';

    // Decode JSON
    $json = json_decode( $response );

    // Set total count
    $count = absint( $json->count );

    // Set transient to expire every 30 minutes
    set_transient( 'wds_post_tweet_count' . $post_id, absint( $count ), 30 * MINUTE_IN_SECONDS );

  }

 return absint( $count );

}

The above function looks delightfully simple, because it is. I did all five steps in less than 30 lines of code.

Get total number of Facebook Likes, Shares, and FB Comments

/**
 * Get like count from Facebook FQL
 */
function wds_post_like_count( $post_id ) {

  // Check for transient
  if ( ! ( $count = get_transient( 'wds_post_like_count' . $post_id ) ) ) {

    // Setup query arguments based on post permalink
    $fql  = "SELECT url, ";
    //$fql .= "share_count, "; // total shares
    //$fql .= "like_count, "; // total likes
    //$fql .= "comment_count, "; // total comments
    $fql .= "total_count "; // summed total of shares, likes, and comments (fastest query)
    $fql .= "FROM link_stat WHERE url = '" . get_permalink( $post_id ) . "'";

    // Do API call
    $response = wp_remote_retrieve_body( wp_remote_get( 'https://api.facebook.com/method/fql.query?format=json&query=' . urlencode( $fql ) ) );

    // If error in API call, stop and don't store transient
    if ( is_wp_error( $response ) )
      return 'error';

    // Decode JSON
    $json = json_decode( $response );

    // Set total count
    $count = absint( $json[0]->total_count );

    // Set transient to expire every 30 minutes
    set_transient( 'wds_post_like_count' . $post_id, absint( $count ), 30 * MINUTE_IN_SECONDS );

  }

 return absint( $count );

}

The function above is almost exactly the same as the tweet function. We’re using Facebook Query Language (FQL) to extract granular data because Facebook’s Open Graph doesn’t allow you to extract individual counts based on post’s permalink. (Read more about getting “shares” data via Open Graph on StackOverflow).

Note: I left “share_count“, “like_count“, and “comment_count” in the example just in case you wanted to mix or match. Just know, “total_count” is a sum of the aforementioned totals.

Get total number of Pageviews from Jetpack

/**
 * Get post pageview count
 */
function wds_post_pageview_count( $post_id ) {

  // Check for transient
  if ( ! ( $count = get_transient( 'wds_post_pageview_count' . $post_id ) ) ) {

    // Verify we're running Jetpack
    if ( function_exists( 'stats_get_csv' ) ) {

      // Do API call
      $response = stats_get_csv( 'postviews', 'post_id='. $post_id .'&period=month&limit=1' );

      // Set total count
      $count = absint( $response[0]['views'] );

    // If not, stop and don't set transient
    } else {
      return 'Jetpack stats not active';
    }

      // Set transient to expire every 30 minutes
      set_transient( 'wds_post_pageview_count' . $post_id, absint( $count ), 30 * MINUTE_IN_SECONDS );

  }

 return absint( $count );

}

The above function will ask Jetpack to give us the total pageviews over 30 days for our post.

Get total number of Comments

/**
 * Get post comment count
 */
function wds_post_comment_count( $post_id ) {

  // Check for transient
  if ( ! ( $count = get_transient( 'wds_post_comment_count' . $post_id ) ) ) {

    // Verify comments are open
    if ( comments_open() ) {

      // Get comment count
      $count = absint( get_comments_number( $post_id ) );

    // If not, stop and don't set transient
    } else {
      return 'Comments closed';
    }

    // Set transient to expire every 30 minutes
    set_transient( 'wds_post_comment_count' . $post_id, absint( $count ), 30 * MINUTE_IN_SECONDS );

  }

 return absint( $count );

}

The function above requires no third-party API and works with Disqus.

Create social media icons function

/**
 * Markup for Social Media Icons
 */
function wds_social_media_icons() {
    
  // Get the post ID
  $post_id = get_the_ID(); ?>

  <div class="social-icons-wrap">
    <ul class="social-icons">
      <li class="social-icon twitter"><a href="https://twitter.com/share?&amp;url=<?php the_permalink(); ?>&amp;text=<?php the_title(); ?>&amp;via=XXXXXXXXXXXXX"><?php echo wds_post_tweet_count( $post_id ); ?></a></li>
      <li class="social-icon facebook"><a href="https://www.facebook.com/sharer/sharer.php?u=<?php the_permalink(); ?>&amp;appId=XXXXXXXXXXXXX"><?php echo wds_post_like_count( $post_id ); ?></a></li>
      <li class="social-icon pageviews"><p><?php echo wds_post_pageview_count( $post_id ); ?></p></li>
      <li class="social-icon comments"><a href="<?php comments_link(); ?>"><?php echo wds_post_comment_count( $post_id ); ?></a></li>
    </ul>
  </div><!-- .social-icons-wrap -->

<?php }

This function is what I used to create the HTML markup to display icons and total counts.

Use wds_social_media_icons(); in the loop

<div id="primary" class="content-area">
  <div id="content" class="site-content" role="main">

    <?php if ( have_posts() ) : ?>
 
      <?php /* The loop */ ?>
      <?php while ( have_posts() ) : the_post(); ?>
        <?php get_template_part( 'content', get_post_format() ); ?>
        <?php wds_social_media_icons(); ?>
      <?php endwhile; ?>
 
      <?php else : ?>
        <?php get_template_part( 'content', 'none' ); ?>
      <?php endif; ?>
 
  </div><!-- #content -->
</div><!-- #primary -->

Now, I can use the function: wds_social_media_icons(); anywhere inside the loop, and the counts will show up!

The functions are split into separate functions, so you can use all or none. Totally modular. I hope these examples help you with your next project, and to view the full output of this post, (with loop example) check out this Gist. Now you know how to display likes, tweets, page views, and comment counts…and ALL THE THINGS!

Comments

3 thoughts on “Display Likes, Tweets, Page Views, and Comment Counts in Posts

  1. $count = absint( $json[0]->total_count ); gives me Fatal error: Cannot use object of type stdClass as array in …….functions.php on line 512

  2. Hello and thanks for share this code. I have the same error than Joe Barret:

    $count = absint( $json[0]->total_count );
    Fatal error: “Cannot use object of type stdClass as array”

    Any idea?

Have a comment?

Your email address will not be published. Required fields are marked *

accessibilityadminaggregationanchorarrow-rightattach-iconbackupsblogbookmarksbuddypresscachingcalendarcaret-downcartunifiedcouponcrediblecredit-cardcustommigrationdesigndevecomfriendsgallerygoodgroupsgrowthhostingideasinternationalizationiphoneloyaltymailmaphealthmessagingArtboard 1migrationsmultiple-sourcesmultisitenewsnotificationsperformancephonepluginprofilesresearcharrowscalablescrapingsecuresecureseosharearrowarrowsourcestreamsupporttwitchunifiedupdatesvaultwebsitewordpress