Video icon 64
Learning to code? Skill up faster with our practical video courses. Start your free trial today.
Advertisement

How to Create an Advanced Twitter Widget

by

As of March 2011, the current average number of "Tweets" the world sends per day is 140 million. This tutorial demonstrates how to create a custom Twitter widget from scratch that uses the Twitter API, Web Intents and @Anywhere. Using the Twitter platform to create a fun, interactive tool for your website can be beneficial both in the learning and promotion departments!


A Few Pros and Cons

Pros:

  • Greater Customization than the default Twitter widget.
  • Cache file prevents problems with Twitter API Rate Limiting and over capacity issues

Cons:

  • Requires Twitter oAuth if you want to incorporate the advanced functionality of @Anywhere
  • Setting up a Cron Job can be tricky (there are many web hosting server configurations and control panels)

Now, lets get started!


Step 1. Markup and Styling

This tutorial assumes that you have some CSS and HTML knowledge, and starts out with the basic markup and styling for the widget. Note that the content of the widget is located in <div id="tweet"></div> and is created using jQuery, Twitter API and PHP.

The HTML

<!-- Begin Content -->
<div id="content">

<!-- Begin Twitter Feed Area  -->
<div class="twitterfeed">

<img src="images/twitter_bird.png" width="99" height="75" alt="Follow Nettuts+ and Tuts+ on Twitter" />

<h3>Follow <a href="http://twitter.com/envatowebdev">Nettuts+</a> and <a href="http://twitter.com/tutsplus">Tuts+</a> on Twitter</h3>

<div id="tweet"></div>

</div>
<!-- End Twitter Feed Area  -->

</div>
<!-- End Content -->

The CSS

#content .twitterfeed { 
  float: left;
  background-color: #fff;
  width: 385px;
  margin: 10px 0px 30px 10px;
  border: 1px solid #d8d8d8; 
  padding: 5px 5px 15px 5px;
}

#content img  {
  margin: 5px 0px 0px 10px;
}

#content h3 {
  float: right;
  color: #000;
  background-color: #f2f2f2;
  font-size: 18px;
  font-weight: bold;
  width: 235px;
  padding: 10px 5px 10px 10px;
  margin: 10px 10px 25px 0px;
  text-shadow: 0 1px 0 #fff;
  border: 1px solid #d8d8d8; 
}

#content h3 a {
  text-decoration: none;
}

#content hr {
  width: 90%;
  height: 1px;
  background: #dfdfdf;
  display: block;
  border: none;
  margin: 20px 0px 20px 18px;
}

#tweet  {
  float: none;
  clear: both;
}

#tweet p {
  margin: 15px 15px 10px 15px;
}

#web_intent {
  margin: 0px 0px 0px 15px;
}

#web_intent a:link, #web_intent a:visited, #web_intent a:active {
  margin: 0px 10px 0px 0px;
}

#web_intent img {
  margin: 0px 3px 0px 0px;
  position: relative;
  top: 2px;
}

#web_intent .time {
  margin: 0px 10px 0px 0px;
}

#follow-envatowebdev  {
  margin: 0px 10px 0px 75px;
}

.log-button {
  margin: 10px 10px 0px 115px;
}

The #content ID may need to be changed based on your theme and placement of the widget (Ex. #content, #sidebar, #footer)


Step 2. PHP "Cache File" Script

As of this writing, the Twitter limit for Unauthenticated API calls is 150 requests per hour. OAuth calls are permitted at 350 requests per hour and are measured against the oauth_token used in the request.

To ensure that our custom Twitter widget does not run into problems with Twitter API rate limiting, a PHP "cache file" script needs to be created. This script retreives the Twitter API "GET statuses/user_timeline" information and stores it in a "TXT" file located in the cache directory on your server.

If you do not already have a cache directory, you will need to create one. You will also need to create a directory on your server for the PHP cache file script.

Create a PHP file that contains the following code.

<?php

$cache = dirname(__FILE__) . '/../cache/twitter-json.txt';

$data = file_get_contents('http://api.twitter.com/1/statuses/user_timeline/twitter_screen_name.json?count=3&include_rts=true&include_entities=true'); 

$cachefile = fopen($cache, 'wb');
fwrite($cachefile,utf8_encode($data));
fclose($cachefile);

?>

The "count=3" portion of the code controls how many "tweets" will be displayed in your Twitter widget. If you want to display only one tweet, then change the code to "count=1".

Note that the "&include_rts=true" needs to be included if you want your Twitter widget to display "retweets". Visit the Twitter API doumentation "GET statuses/user_timeline" for more information and available options.


Step 3. Set Up Cron Job

Next, a Cron job needs to be created that executes the PHP script at a set number of times per hour. How the Cron job is set up depends on your web hosting control panel. Please refer to "Scheduling Tasks with Cron Jobs" for an in depth tutorial.

Below is an example of Cron tab settings for a Plesk control panel that runs a Cron job (4) times per hour (every fifteen minutes), every day.

  • Minute = */15
  • Hour = *
  • Day of the Month = *
  • Month = *
  • Day of the Week = *
  • Command = /usr/bin/curl -s http://your_domain.com/twitter-widget/twitter-cron.php > /dev/null

Step 4. Add jQuery and Twitter Web Intents Script Tags

We need to make sure that our web page references the jQuery library. For this tutorial, the jQuery library is included through the use of the jQuery CDN.

Between the head tags of your web page add

<script src="http://code.jquery.com/jquery-1.6.2.min.js"></script>

In addition to using the Twitter API, the Twitter widget uses Twitter Web Intents to add "Retweet", "Reply" and "Favorite" functionality.

Just below the jQuery script tag, add

<script src="http://platform.twitter.com/widgets.js"></script>

Step 5. The jQuery Code

An external JavaScript file, "twitter-widget.js," needs to be created. This JavaScript file contains the jQuery code that generates the "content" of the Twitter widget. The jQuery code retreives the Twitter API information from the cache file that was created by the PHP script in Step two.

In the JS file, add the following jQuery code.

// Display Latest Tweet

$(document).ready(function(){

$.getJSON('cache/twitter-json.txt', function(data){
        $.each(data, function(index, item){
                $('#tweet').append('<div><p>' + item.text.linkify() + '</p></div>' + '<div id="web_intent">' + '<span class="time">' + relative_time(item.created_at) + '</span>' + '<img src="images/retweet_mini.png" width="16" height="16" alt="Retweet">' + '<a href="http://twitter.com/intent/retweet?tweet_id=' + item.id_str + '">' + 'Retweet</a>' + '<img src="images/reply_mini.png" width="16" height="16" alt="Reply">' + '<a href="http://twitter.com/intent/tweet?in_reply_to=' + item.id_str + '">' + 'Reply</a>' + '<img src="images/favorite_mini.png" width="16" height="16" alt="Favorite">' + '<a href="http://twitter.com/intent/favorite?tweet_id=' + item.id_str + '">' + 'Favorite</a>' + '</div>' + '<hr />');
    });
});

jQuery .getJSON() is used to load the JSON-encoded data from the cache TXT File. Using jQuery .append(), the content is displayed through the <div id="tweet"></div> of the XHTML markup. Each Twitter API item is prefixed with "item.". The Twitter API items used in the jQuery code are:

  • text (item.text) - The text of each tweet
  • created_at (item.created_at) - The date each tweet was posted
  • id_str (item.id_str) - The unique ID number of each tweet

Editor's Note: If you'd prefer to get that muddy HTML out of your JavaScript, consider using the jQuery templating plugin.


Step 6. Converting Twitter Time Stamp to Relative Time (Time Ago)

The data that is retrieved using the Twitter API is "raw" data and needs to be fixed up for the Twitter widget.

In the twitter-widget.js file, below the jQuery code, add the following JavaScript code.

// Convert Twitter API Timestamp to "Time Ago"

function relative_time(time_value) {
  var values = time_value.split(" ");
  time_value = values[1] + " " + values[2] + ", " + values[5] + " " + values[3];
  var parsed_date = Date.parse(time_value);
  var relative_to = (arguments.length > 1) ? arguments[1] : new Date();
  var delta = parseInt((relative_to.getTime() - parsed_date) / 1000);
  delta = delta + (relative_to.getTimezoneOffset() * 60);

  var r = '';
  if (delta < 60) {
        r = 'a minute ago';
  } else if(delta < 120) {
        r = 'couple of minutes ago';
  } else if(delta < (45*60)) {
        r = (parseInt(delta / 60)).toString() + ' minutes ago';
  } else if(delta < (90*60)) {
        r = 'an hour ago';
  } else if(delta < (24*60*60)) {
        r = '' + (parseInt(delta / 3600)).toString() + ' hours ago';
  } else if(delta < (48*60*60)) {
        r = '1 day ago';
  } else {
        r = (parseInt(delta / 86400)).toString() + ' days ago';
  }

      return r;
  }

});

This code converts the Twitter Time stamp to relative time, such as "3 hours ago."


Step 7. Creating Workable Anchor Links

In the twitter-widget.js file, below the convert timestamp code, add the following JavaScript code.

// Create Usable Links
String.prototype.linkify = function() {
       return this.replace(/[A-Za-z]+:\/\/[A-Za-z0-9-_]+\.[A-Za-z0-9-_:%&\?\/.=]+/, function(m) {
              return m.link(m);
      });
};

When using the Twitter API, the links contained in Twitter posts are displayed in text format only, not workable anchor links. The above code converts standard URL text only links into workable anchor links.


Step 8. Adding Advanced Features Using Twitter @Anywhere

We have now created a rather neat, custom Twitter widget that includes some basic user interactivity. But what if we want to add really cool, advanced functionality to our Twitter widget? Thanks to the Twitter @Anywhere Service, we can accomplish this fairly easily.

Sign up for the Twitter @Anywhere Service at https://dev.twitter.com/apps/new.

Create a New "App" and complete the steps of the online registration process. Visit this article for detailed help on completing the registration process.

"The callback URL property (Set in your @Anywhere account) of your application must match both the subdomain and domain of the web application utilizing @Anywhere. "

The next few steps of this tutorial explain how to add Twitter @Anywhere advanced functionality.


Step 9. Add @Anywhere Script Tag

As close to the top of the web page as possible, add the @Anywhere script Tag:

<script src="http://platform.twitter.com/anywhere.js?id=Your_Consumer_Key&v=1"></script>

Note that your Twitter oAuth Consumer Key needs to be added to the script tag.


Step 10. User Login and Authorization

Certain features of the Twitter @Anywhere service do not require the user to be logged into Twitter. Hover Cards and Auto-linkification of Twitter usernames as examples. However, most @Anywhere features DO require the user to login and authorize your site for access. The "Connect with Twitter" button allows users to authenticate securely with Twitter.

Below <div id="tweet"></div>, add the following code.

<div class="log-button">
<span id="login-logout"></span>
<script src="js/twitter-login.js"></script>
</div>

Now, create an external JavaScript file "twitter-login.js" containing the following code.

<script>
      jQuery(function () {
        twttr.anywhere(function (T) {
          if (T.isConnected()) {
            $("#login-logout").append('<button id="signout" type="button">Sign out of Twitter</button>');
            $("#signout").bind("click", function () {
              twttr.anywhere.signOut();
          });
        }
          else {
            T("#login-logout").connectButton();
          }
        });
      });
</script>

Step 11. Determining the Connected State

@Anywhere provides several ways of determining whether a user is already logged into Twitter and has already granted your application authorization for access. For this tutorial, we are going to use authComplete and signOut events.

Just below the web page <body> tag, add the following:

<script>
    twttr.anywhere(function (T) {
       T.bind("authComplete", function (e, user) {
          // triggered when auth completed successfully
        });

     T.bind("signOut", function (e) {
          // triggered when user logs out
        });
     });
</script>

By adding the above code, the authComplete and signOut events are now triggered by ANY @Anywhere functionality.


Step 12. Adding Hovercard Functionality

A Hovercard displays data about a Twitter user in a tooltip and also includes a follow/unfollow button.

To add a hovercard that is "expanded" by default, add the following code below the authComplete and signOut code, just below the web page <body> tag:

<script type="text/javascript">
    twttr.anywhere(function (T) {
     T("#tweet").hovercards({ expanded: true });
     });
</script>

Note that if you add Hovercard functionality, the Auto-linkification of Twitter usernames is also added by default. This makes adding the "T.linkifyUsers()" function to your webpage unnecessary.


Step 13. Adding a Follow Button

To add a Twitter follow button to the widget, below <div id="tweet"></div>, add the following code.

<span id="follow-twitter_screen_name"></span>
<script type="text/javascript">
   twttr.anywhere(function (T) {
       T('#follow-twitter_screen_name').followButton("twitter_screen_name");
     });
</script>

Note that you need to add your Twitter screen name to the above code.


Step 14. Adding a Tweet Box

If you would like to add a Tweet Box instead of a follow button, below <div id="tweet"></div> add the following code.

<div id="tbox"></div>
<script type="text/javascript">
   twttr.anywhere(function (T) {
      T("#tbox").tweetBox({
          height: 90,
          width: 350,
        });
     });
</script>

All Done!

View the completed demo. Creating a Twitter driven widget from scratch that uses the Twitter API, Web Intents and @Anywhere takes a bit of work. However, you can create something interactive and fun for visitors of your website!

Please note that the JavaScript codes for Relative Time and Creating Workable Anchor Links are thanks to this article.

For those of you who would rather create a basic Twitter driven widget without using Twitter oAuth and @Anywhere, there are basic demos included in the source files zip. There are also two demos that display Twitter profile images next to each tweet.

If you have any questions about this tutorial, please ask them using the "Add a Comment Box" below.

Advertisement