Browse through dozens of job offers for web professionals including design jobs and tech jobs
Introduction
Twitter has added a new feature a while ago that I believe a lot of twitter users have been waiting for - Image Attachment. Also, not too long ago, I wrote a tutorial called Create a Dead Simple Twitter Feed with jQuery, one of the readers (Jamie Graham) asked about twitter media entities, well honestly, when I was building the script for the tutorial, I did not paid attention on the JSON data returned, I just grab what I need. I sat down and did a little bit of research, and I believe it'd be something fun to do so I made a second part of the twitter feed with jQuery.
This time, it will be a little bit more interesting, I modified my previous script and added some cool plugins, everything was done less than an hour, and it looks pretty good! I used my favourite modal window - FancyBox and masonry plugin in this tutorial. This is how it looks like:
UPDATE: I forgot to mention one thing! Twitter has rate limits. You can only call this API 150 times per hour per IP. The best way to solve this is using cache. So, instead of calling the API in $.ajax call, you get it from your server. A PHP is scheduled (a href="http://adminschoice.com/crontab-quick-reference">CRON Job to retrieve updated twitter feed in certain time and create the cache file once it's loaded. Don't worry, nettuts just released a tutorial about it :) How to Create An Advanced Twitter Widget
UPDATE: We have written an updated version of Twitter API tutorial based on Twitter Newest API 1.1. - Easiest Way to Retrieve Twitter Timeline and Hashtags
HTML
The following is the HTML generate by Javascript, there are two different layout, one with image and one without. You can tweak the layout in twitter.js
<div id="jstwitter"> <div class="tweet"> Tweet Text here <div class="time"> relative date here </div> </div> <div class="tweet"> <a href="http://url" class="fancy"><img data-src="image path" alt="" width="150"></a> Tweet Text here <div class="time"> relative date here </div> </div> ...... ...... ...... </div>
CSS
Just a simple and clean CSS style to accomodate jQuery Masonry. It will be a 150px fixed width blocks.
#jstwitter { width: 80%; font-family: arial; font-size: 15px; color: #333333; padding: 10px; margin:0 auto; } #jstwitter .tweet { width: 150px; margin:5px; padding: 5px; float:left; background:#f1f1f1; border:3px solid #ddd; } #jstwitter .tweet a { text-decoration: none; color: #13c9d0; } #jstwitter .tweet a:hover { text-decoration: underline; } #jstwitter .tweet .time { font-size: 10px; font-style: italic; color: #666666; }
Twitter JSON Data
Something you need to know about the JSON data returned by Twitter API:
- Media contains array of objects, if you have more than one images attached in the tweet, the first image will be media[0], media[1] and so on. You probably need to use for loop to loop through it. In this tutorial we will grab the first image only.
- This tutorial uses media_url, you also can use the https version called media_url_https.
- 4 different image sizes: large, medium, small and thumbnail.
- To retrieve different image size, for example, thumbnail, you need to use either media_url or media_url_https and append a colon plus the size
eg: http://p.twimg.com/AQ9JtQsCEAA7dEN.jpg:thumbnail
eg: http://p.twimg.com/AQ9JtQsCEAA7dEN.jpg:large
You can test it on your browser.
"text": "#Photos on Twitter: taking flight http://t.co/qbJx26r", "entities": { "media": [ { "id": 76360760611180544, "id_str": "76360760611180544", "media_url": "http://p.twimg.com/AQ9JtQsCEAA7dEN.jpg", "media_url_https": "https://p.twimg.com/AQ9JtQsCEAA7dEN.jpg", "url": "http://t.co/qbJx26r", "display_url": "pic.twitter.com/qbJx26r", "expanded_url": "http://twitter.com/twitter/status/76360760606986241/photo/1", "sizes": { "large": { "w": 700, "resize": "fit", "h": 466 }, "medium": { "w": 600, "resize": "fit", "h": 399 }, "small": { "w": 340, "resize": "fit", "h": 226 }, "thumb": { "w": 150, "resize": "crop", "h": 150 } }, "type": "photo", "indices": [ 34, 53 ] } ], "urls": [ ], "user_mentions": [ ], "hashtags": [ ] }
Javascript
You will need to refer to my previous tutorial, Create a Dead Simple Twitter Feed with jQuery to understand hows everything work together.
We will integrate jQuery Masonry and Fancy box in this tutorial. Both of them will be activated once data are fully loaded.
JQTWEET = { // Set twitter username, number of tweets & id/class to append tweets user: 'quenesstestacc', numTweets: 20, appendTo: '#jstwitter', // core function of jqtweet loadTweets: function() { $.ajax({ url: 'http://api.twitter.com/1/statuses/user_timeline.json/', type: 'GET', dataType: 'jsonp', data: { screen_name: JQTWEET.user, include_rts: true, count: JQTWEET.numTweets, include_entities: true }, success: function(data, textStatus, xhr) { var html = '<div class="tweet">IMG_TAG TWEET_TEXT<div class="time">AGO</div>'; var img; // append tweets into page for (var i = 0; i < data.length; i++) { //this is where we grab the image, only generate the HTML code if media entities were found in the JSON data try { if (data[i].entities.media) { img = '<a href="' + data[i].entities.media[0].media_url + ':large" class="fancy">'; img += '<img data-src="' + data[i].entities.media[0].media_url + ':thumb" alt="" width="150" />'; img += '</a>'; } else { img = ''; } } catch (e) { //e } $(JQTWEET.appendTo).append( html.replace('IMG_TAG', img) .replace('TWEET_TEXT', JQTWEET.ify.clean(data[i].text, img) ) .replace(/USER/g, data[i].user.screen_name) .replace('AGO', JQTWEET.timeAgo(data[i].created_at) ) .replace(/ID/g, data[i].id_str) ); } //trigger jQuery Masonry once all data are loaded var $container = $('#jstwitter'); $container.imagesLoaded(function(){ $container.masonry({ itemSelector : '.tweet', columnWidth : 0, isAnimated: true }); }); //the last step, activate fancybox $("a.fancy").fancybox({ 'overlayShow' : false, 'transitionIn' : 'elastic', 'transitionOut' : 'elastic', 'overlayShow' : true }); } }); }, /** * relative time calculator FROM TWITTER * @param {string} twitter date string returned from Twitter API * @return {string} relative time like "2 minutes ago" */ timeAgo: function(dateString) { ...... ...... ...... }, // timeAgo() /** * The Twitalinkahashifyer! * http://www.dustindiaz.com/basement/ify.html * Eg: * ify.clean('your tweet text'); */ ify: { //the purpose of hasIMG parameter is to remove all the unnessary links if there is images, //otherwise, parse link as usual link: function(tweet, hasIMG) { return tweet.replace(/\b(((https*\:\/\/)|www\.)[^\"\']+?)(([!?,.\)]+)?(\s|$))/g, function(link, m1, m2, m3, m4) { var http = m2.match(/w/) ? 'http://' : ''; if (hasIMG) return ''; else return '<a class="twtr-hyperlink" target="_blank" href="' + http + m1 + '">' + ((m1.length > 25) ? m1.substr(0, 24) + '...' : m1) + '</a>' + m4; }); }, ...... ...... ...... //added hasIMG parameter clean: function(tweet , hasIMG) { return this.hash(this.at(this.list(this.link(tweet, hasIMG)))); } } // ify }; // start jqtweet! JQTWEET.loadTweets();
Conclusion
That's all. This is how it's done - display tweet with images. With jQuery and all the plugins out there, it really saves heaps of times to create something really simple but fancy in short time. Well, you need to know what you want to achieve first and understand how to use those plugins. We used Twitalinkahashifyer, relative time, fancybox and Masonry in this tutorial.
I hope you pick up something in this tutorial, hopefully able to help you in your upcoming project. Queness will continue to look for interesting and practical jQuery tutorials! Please help me to spread this tutorial to express your gratitude! :)
Comments will be moderated and
rel="nofollow"
will be added to all links. You can wrap your coding with[code][/code]
to make use of built-in syntax highlighter.