For quite some time now I've had a sidebar widget that displays an excerpt of my Twitter feed on my blog. It uses the standard Twitter JSON/P interface for loading the tweets and then a Twitter-provided script (http://twitter.com/javascripts/blogger.js) for rendering them on the page. Unfortunately the default installation instructions would have you set up something like this:
<ul id="twitter_update_list"></ul> <script type="text/javascript" src="http://twitter.com/javascripts/blogger.js"></script> <script type="text/javascript" src="http://twitter.com/statuses/user_timeline/barneyb.json?callback=twitterCallback2&count=5"></script>
That works, but it puts the JSON/P call (the second SCRIPT tag) into the main page flow, so anything after the call won't render until the script load is complete. When Twitter is slow/down it can cause problems, but even when it's fast you still get a brief hang with a partial page before the rest snaps into view. Fortunately, the solution is simple: do the call on DOMLoaded instead of inline. I'm using jQuery, but the principle is the same regardless of what framework you use (or none at all):
<ul id="twitter_update_list"><li class="load-ind"><img src="http://www.barneyb.com/s/loading_indicator.gif" /></li></ul> <script type="text/javascript"> jQuery(function() { jQuery("body").append( '<sc'+'ript type="text/javascript" src="http://twitter.com/javascripts/blogger.js"></sc'+'ript>' + '<sc'+'ript type="text/javascript" src="http://twitter.com/statuses/user_timeline/barneyb.json?callback=twitterCallback2&count=5"></sc'+'ript>' ); }); </script>
Now the SCRIPT tags will be written on DOMReady, allowing the full page to render before the calls to Twitter are dispatched. This gives a faster user experience, though you do get a reflow of the sidebar when the statuses load. This has become so prevalent on modern websites, however, that I don't think it's worth caring about, but if you're concerned, you could specify a height to the loading indicator LI that is approximately what the rendered tweet list will be to mitigate the effect. It won't avoid the reflow, but it'll make things move less because the space will be reserved up front.
I've also added a simple "loading" image to the UL that the JS will place the tweets in. The way blogger.js is written, any content within the UL will be removed (i.e. the tweets overwrite the content; they're not appended to the content), so no need to explicitly remove the image or it's container LI.
Wonderful! I am going to try this out. That lag has been bugging me.
Was there a reason to split up script into sc + ript? just curious
@grace,
The open script tags don't matter so much, but the closing script tags will break your HTML if they're intact, so you need to do something. To put that more succinctly, a literal "</script>" tag will terminate a SCRIPT block, regardless of whether it's inside a JavaScript string, because it's the HTML engine that parses the SCRIPT block (which has no idea about JavaScript syntax). I always break both open and closing tags for symmetry, even though only the closing tag is really essential.
Hi Barney,
Thanks for posting this! Very useful to know. :)
I have a question–not sure if you'd be able to answer. With Twitter's new ReTweet feature via its web interface, it seems like RTing will display nothing when using the original json code. Might you have a solution for this? Even to skip these new RTs would work for me too. Would you have any suggestions or ideas?
Thank you so much, and thanks again for sharing your code! :)
-Estella
@Estella,
You don't have to use the blogger.js that Twitter provides, you can roll your own custom handler for the JSON data that does whatever you want (hiding RTs, styling @replies differently, alternating background colors, etc.). If you take a look at blogger.js, you'll see it's really simple. Just copy it to your server, change your reference to use your copy, and you can start hacking it up to suit your purposes. And then cackle maniacally.
As an example, check out http://www.barneyb.com/s/blogger.js, which adds a 'odd' or 'even' class to the LIs generated, allowing me to put alternating background colors on my tweets (using CSS).
Ahh! That's true. (I know, imma js n00b~)
Thanks for the friendly suggestion and advice! I'll definitely look into that. :)
I'm no javascript whiz by any means and though I understand how this works, I can't really recreate it for the twitter widget they provide.
Is there a simple way of using this technique with that? The particular widget is: http://twitter.com/goodies/widget_list
Thanks!
-Sam
Sam,
They provide all the JavaScript you need. Just a matter of pasting the two SCRIPT tags into your page.
Yeah, but the json is still the second piece of javascript to load, and the method above doesn't seem to work for it. That was my point I suppose.
Sam,
It looks like if you set 'live = false' in the features block of the config you might get what you want. I didn't try it, just took a cursory look at the code and it seemed a likely solution.
I've been pulling my hair out trying to exclude @replies from this. I've got the standard JSON script hosted locally on a site. I've seen a few examples, but they either haven't worked or involved setting a high number of returns (in the case of someone who replies often). Any ideas? I'm a HTML / CSS / PHP guy by trade, knowing just enough javascript to be dangerous.
Norcross,
There three primary approaches I can envision for excluding @replies.
1) pull your standard five tweets and cull the replies (leaving you with somewhere between zero and five tweets to display).
2) pull a large number of tweets and then cherrypick the first five non-replies. You have to pull enough to ensure you get five non-replies (which, as you say, might be quite large).
3) start with an empty list of non-replies. Pull five tweets and extract the non-replies. Repeat until you have five non-replies to display.
The first is the easiest, of course. The second is the sledgehammer approach. The third is the surgeon's approach. I'd probably recommend doing option #1 except pull 10 tweets. You'll end up with between zero and 10 non-replies, of which you can ignore anything beyond the fifth. It seems that having fewer than five tweets is no big deal for this sort of twitter status widget, so it doesn't seem worth the extra overhead to do paging or pulling a huge set just to ignore most of it.
I'm implemented @reply hiding in my blogger.js: http://www.barneyb.com/s/blogger.js
It will iterate over all the returned tweets and display the first five non-replies, and then abort. You'll need to increase the 'count' parameter on the SCRIPT tag that points to Twitter's JSON/P service so that you get 10 or whatever, to increase the odds of having five tweets to display.
Thank you for posting this, Barney. I have been creating my art portfolio and the JSON tutorial greatly helped because the call to Twitter was making the thumbnails un-viewable till it loaded. With your method, and a different, smaller loading .gif file I was able to get the exact functionality that I wanted. I really appreciate your effort.
Take a look at http://peteippel.com.
All my best,
Pete
Thanks fot the info on this page. Why, is the max of the number tweets without @reply 5?
How can I increase that number?
Sandro,
On line three, find "c<5″ in the 'for' loop. That stops looking after it finds five non-reply tweets. Set it to whatever you want, just make sure you also increase the 'count' parameter to the JSON/P call so you have enough tweets available to scan through.
Ok, I found it ;-) Thanks!
cheers for the script will improve using the .json loads
Am using it with the following – http://www.mclelun.com/lab/jqtwitter/ as the .json seriously hangs the site i am developing, however using the script you provided it conflicts with the auto refreshing of the tweets… any help!?
I have just implemented the twitter widget into a website and the lag was obvious. Great and simple little snippet that works perfectly. Thanks for sharing.
Thanks for sharing! Even though I always have the original twitter snippet in the footer, I was still seeing some lag with other jquery effects. Your clever solution solved the delay. Much appreciated!
Barney
Been looking for this solution for a while our twitter widget in word press hangs whilst blogger.js is loaded sometimes up to 5 seconds so will implement this shortly
Cheers for posting
Wayne Austin
[...] found some code on BarneyB's blog that is a modification of Twitter's original code. He mentions in the comments that he's removing replies in his code. I just took his code and stop [...]
Hi Barney,
Been tearing my hair out trying to get @replies removed from a client's twitter feed upon their request. I've implemented your custom 'blogger.js' and its working great!
I've credited you in the script of course!
Thanks
Mark
Hey Barney,
Is it possible to show newschool Retweets as well? Because in my implementation those don't show up.
This is fantastic, thanks! I could see in firebug WHY my page was lagging, but I didn't know I could dynamically write script tags in to solve that!
Thank you thank you thank you! Always bugged me that the old .json stuff didn't work, to the point that the only way to include the Twitter part of our site was right at the bottom of the .css stack to avoid it hitching up. This has helped immensely for the site re-design I'm currently working on.
I owe you a pint!
As a tip to others, you can take out the as long as you have a to replace it – I already had a and the was messing up the formating of the page.
Dear all,
since this weekend our tweets won't load anymore with Internet Explorer 9.
The other browsers are working perfect.
Does anyone have the same problem or knows what to to do to fix this problem?
Yes i have the same issue. The script works perfectly in all browseres exept IE9.
This must be a microsoft bug in a recent IE9 update.
I havent had chance to try and fix this yet but hopefully I should get some time to look at it over the weekend.
Does anyone else have a solution to this problem yet?
Hi Barney, Thank you for sharing your knowledge!
There is an issue when I use your modified blogger.js – the links to the tweets on twitter.com do not function (I get a "Sorry, that page doesn’t exist!" message on twitter.com).
Do you have a solution for that?
Murk,
It appears to be a precision issue in JS engines. I've changed the script at http://www.barneyb.com/s/blogger.js to use id_str (a string) instead of id (a number) to avoid the issue.
Hello Barney,
Thanks for finding a solution for this issue and again thanks a lot for this very usefull script!
I will use your scripts and offcourse I will put your credits in the script.
Could it be made possible to get feeds with particular hashtag by this script?
Thank you so much for this…. was really bugging me because I have a JS image loader and it was hanging badly displaying all the images in a big row until the twitter loaded….
Now it works great…
YOURE THE MAN
thank you
I have the following code as the twitter feed is a widget within my footer on wordpress, how should I adapt the following code to conform with this method:
Thanks very much
Tom
Tom, I assume you're returning an HTML string containing the container and script tags? If so, you just need to invoke that function on DOMReady, rather than in the page flow.
@barneyb
I'm really sorry but I'm not suite sure what I need to do, I have the following code which calls the feed from my tweet widget which is:
function tz_twitter_js($tz_twitter_username, $tz_twitter_postcount) {
return '[script type="text/javascript" src="http://twitter.com/javascripts/blogger.js"][/script]
[script type="text/javascript" src="http://twitter.com/statuses/user_timeline/'.$tz_twitter_username.'.json?callback=twitterCallback2&count='.$tz_twitter_postcount.'"][/script]';
}
————————–
and then I have the following in my php to call the widget:
[!-- BEGIN .widget-section --]
[div class="widget-section"]
[?php /* Widgetised Area */ if ( !function_exists( 'dynamic_sidebar' ) || !dynamic_sidebar( 'Footer Two' ) ) ?]
[!-- END .widget-section --]
[/div]
——————————–
Obviously i have replaced the arrowed parenthesis with square [] so it shows in the comments here.
Thanks for any help in advance.
Tom, the result of the 'tz_twitter_js' function is equivalent to the first code snippet in my post. You should change it to look like the second (i.e., don't return the twitter SCRIPT tags directly, return an inline SCRIPT tag which will use JS to write the twitter SCRIPT tags). My example uses jQuery. If you already have jQuery on your page, you're set. If not, you'll need to adapt it to either use a JS framework available to your pages, or do the listening manually. I haven't tested, but a simple setTimeout might work also if you don't have jQuery.
Hey, just used your page to exclude @replies from my tweets. MAJORLY helpful man, thanks!
One more thing I wanted to add though – in my case I just wanted to pull the one latest tweet. In the case where the latest tweet was a reply, this would mean nothing was returned. So what I did was make a slight modification – I added an else case and a break at the end of the loop. This means that it will search for the latest non-reply tweet and then break out of the loop like so:
Is it alright to place part of this on my web site if I submit a reference point to this website?
Of course. Use any or all of it, and no need to link back (though if you want to do that, I won't complain).
Is there any way that I can edit what you have posted?
I would like to see the 3 not-mentions tweets at all time. Not just the not-mention tweets of my last three (which is how this works now?)
Thank you