This tutorial will show you how to create a rotating twitter feed – it will show one tweet at a time in intervals of time that we set in a JavaScript file, from newest to oldest. It is one method of placing your tweets on your site. Another, is the twitter widget. While it is a lot easier to implement, I found the styling cumbersome and restrained. You can check out my post on this topic here: How To Style The Twitter Widget For Your Web Site. While being a bit more complicated to implement, the method described below gives us complete control on how the status updates are displayed. The files need to do this are
- jquery.min.js – the latest version of jQuery
- rotate.js- the file we use to animate our feed
- tweets.css – the file used to style our feed
- tweets.js – contains the JavaScript used to retrieve our twitter updates
- index.php – a blank PHP or HTML page
How It Works
We will start with a blank PHP page and some basic CSS. Then we will add div elements that will contain our twitter feed. We will connect to a remote JSON page to retrieve user specified status updates, and JavaScript to build the feed. Then we will create a separate JavaScript file to create a rotating fade-effect using jQuery. Let’s start by creating a new directory on your local server for the project files then create an index.php with the following code within the body:
<body>
<div class="full-width">
<div class="container">
<div class="content">
<p>
Just the good ol' boys, never
meanin' no harm. Beats all you've
ever saw, been in trouble with
the law since the day they was born.
</p>
<!-- end .content --></div>
<!-- end .container --></div>
<!-- end .full-width --></div>
</body>
Then create and link to a CSS doc for some basic style(includes a CSS reset):
@charset "utf-8";
/************************************************************************/
/************************************************************************/
/************************************************************************/
/* css reset */
html, body, div, span, applet, object, iframe,
h1, h2, h3, h4, h5, h6, p, blockquote, pre,
a, abbr, acronym, address, big, cite, code,
del, dfn, em, img, ins, kbd, q, s, samp,
small, strike, strong, sub, sup, tt, var,
b, u, i, center,
dl, dt, dd, ol, ul, li,
fieldset, form, label, legend,
table, caption, tbody, tfoot, thead, tr, th, td,
article, aside, canvas, details, embed,
figure, figcaption, footer, header, hgroup,
menu, nav, output, ruby, section, summary,
time, mark, audio, video {
background-color: transparent;
margin: 0;
padding: 0;
border: 0;
font-size: 100%;
font: inherit;
vertical-align: baseline;
}
/* HTML5 display-role reset for older browsers */
article, aside, details, figcaption, figure,
footer, header, hgroup, menu, nav, section {
display: block;
}
body {
line-height: 1;
}
a {
text-decoration: none;
}
ol, ul {
list-style: none;
}
blockquote, q {
quotes: none;
}
blockquote:before, blockquote:after,
q:before, q:after {
content: '';
content: none;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
/* end css reset */
/************************************************************************/
/************************************************************************/
/************************************************************************/
body {
font: 100%/1.4 Verdana, Arial, Helvetica, sans-serif;
background: #FFFFFF;
margin: 0;
padding: 0;
color: #000;
}
h1, h2, h3, h4, h5, h6, p {
font-family: Tahoma;
font-weight: lighter;
margin-top: 0;
padding-left: 15px;
padding-right: 15px;
}
a:link {
color: #09c;
text-decoration: none;
}
a:visited {
color: #6E6C64;
text-decoration: underline;
}
a:hover, a:active, a:focus {
text-decoration: none;
color: #09f;
}
/************************************************************************/
div.full-width {
margin: 0 auto;
width: 960px;
}
/************************************************************************/
.container {
background: none repeat scroll 0 0 #EEEEEE;
border: 1px solid #CCCCCC;
border-radius: 3px 3px 3px 3px;
margin: 0 auto 25px;
position: relative;
top: 100px;
width: 960px;
float: left;
}
/************************************************************************/
.content {
border: 1px solid #FFFFFF;
border-radius: 3px 3px 3px 3px;
float: left;
padding: 30px;
width: 898px;
}
.content h1 {
color: #333333;
font-size: 20px;
text-shadow: 0 1px 0 #FFFFFF;
margin-bottom: 0;
}
.content p.description {
color: #666666;
font-size: 11px;
line-height: 25px;
padding: 5px 45px 25px;
text-shadow: 0 1px 0 #FFFFFF;
}
Then, from our index.php file, we need to reference a few more files. Place these lines as the last to be placed next to the closing body tag:
<!-- jQuery --> <script src="jquery.min.js"></script> <!-- rotate tweets --> <script src="rotate.js"></script> <!-- get and build the tweets --> <script src="tweets.js"></script> <!-- tweets username and count --> <script src="http://twitter.com/statuses/user_timeline/***username***.json?callback=twitterCallback&count=5" type="text/javascript"></script>
On the last script, which links back to twitter.com to get the tweets, is where you will set the username and the amount of feeds to be retrieved in the form of count=x. The JavaScript file tweets.js then grabs that information and builds our tweets with the data.
Now let’s create the elements that the feed will be placed in. Using the index.php template flow, let’s create another set of div elements with the classes of “container” and “content”. Within the content div, let’s add a div to hold all the elements used for the feed, a title for the feed, and a div to hold the list of feeds:
<div id="tweets"> <div id="twitter_container"> <h3> Latest Tweets </h3> </div> </div>
Now, under the title, let’s add the <ul> elements for an unordered list. We are not going to add any <li> elements here, for they are going to be created by our tweets.js file, as they will contain the data we retrieve from the tweets.
<div id="tweets">
<div id="twitter_container">
<h3> Latest Tweets </h3>
<ul id="twitter_update_list">
</ul>
</div>
</div>
Now we look at the JavaScript file which will use the parameters we set on the index.php page to create our status updates. Here I’m calling it tweets.js.
// tweets.js - get the feeds from username set on
// index.php and generate list items with the
// data(status updates, feed date, links)
function twitterCallback(twitters) {
var statusHTML = [];
for (var i=0; i<twitters.length; i++){
var username = twitters[i].user.screen_name;
var status = twitters[i].text.replace(/((https?|s?ftp|ssh)://[^"s<>]*[^.,;'">:s<>)]!])/g, function(url) {
return '<a href="'+url+'">'+url+'</a>';
}).replace(/B@([_a-z0-9]+)/ig, function(reply) {
return reply.charAt(0)+'<a href="http://twitter.com/'+reply.substring(1)+'">'+reply.substring(1)+'</a>';
});
statusHTML.push('<li><span>'+status+'</span> <a style="font-size:65%; color:#999;" href="http://twitter.com/'+username+'/statuses/'+twitters[i].id_str+'">'+relative_time(twitters[i].created_at)+'</a></li>');
}
document.getElementById('twitter_update_list').innerHTML = statusHTML.join('');
}
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);
if (delta < 60) {
return 'less than a minute ago';
} else if(delta < 120) {
return 'about a minute ago';
} else if(delta < (60*60)) {
return (parseInt(delta / 60)).toString() + ' minutes ago';
} else if(delta < (120*60)) {
return 'about an hour ago';
} else if(delta < (24*60*60)) {
return 'about ' + (parseInt(delta / 3600)).toString() + ' hours ago';
} else if(delta < (48*60*60)) {
return '1 day ago';
} else {
return (parseInt(delta / 86400)).toString() + ' days ago';
}
}
Now we take a look at the jQuery used to rotate the tweets. Essentially it is saying every four seconds set a variable for the current item and the next item(the items are the individual status updates). If we are at the end of the list(the last list-item element), then set the next item as the first list item, so that it goes around and around continuously. After checking the order, fade out the current item and fade in the last.
/* Tweet Scroller */
$('document').ready(function() {
setInterval("scrollTwt()", 4000);});
function scrollTwt() {
var oCurTwt = $('ul#twitter_update_list li.current');
var oNxtTwt = oCurTwt.next();
if (oNxtTwt.length == 0)
oNxtTwt = $('ul#twitter_update_list li:first');
oCurTwt.fadeOut('fast').removeClass('current');
oNxtTwt.fadeIn('slow').addClass('current');
}
Now we need to style the twitter feed. Below are the styles I used for the example. The only vital part is that the list-items in the <ul id=”twitter_update_list”> are positioned absolutely. It is also wise for the fade effect that I am using to give the list-items an opaque background. This is because letters fading in and out over top one another in not a very attractive effect. Since the list-items are sitting one on top of another, using a background color or image helps with our jQuery animation.
@charset "utf-8";
/* CSS Document */
#tweets {
margin: 0 auto;
width: 452px;
}
#tweets h3 {
color: #999999;
font-family: tahoma;
font-weight: lighter;
padding: 0;
text-shadow: 0 1px 0 #FFFFFF;
}
#tweets #twitter_container {}
#tweets ul#twitter_update_list {
background-color: #FFFFFF;
border: 1px solid #CCCCCC;
border-radius: 3px 3px 3px 3px;
bottom: 10px;
box-shadow: 0 10px 10px -10px #AAAAAA;
font-size: 10px;
height: 40px;
margin: 0 auto;
padding: 10px;
position: relative;
width: 430px;
}
#tweets ul#twitter_update_list li {
position: absolute;
list-style: none;
display: none;
background-color: #FFFFFF;
padding: 5px;
}
#tweets ul#twitter_update_list li.current {
display: block;
}
#tweets p a {
font-size: 10px;
}
#tweets a {}
p.follow {
padding: 0;
}