{"id":533,"date":"2011-05-25T13:14:52","date_gmt":"2011-05-25T00:14:52","guid":{"rendered":"http:\/\/www.thunderguy.com\/semicolon\/?p=533"},"modified":"2013-04-02T15:22:20","modified_gmt":"2013-04-02T02:22:20","slug":"a-simple-twitter-widget","status":"publish","type":"post","link":"https:\/\/thunderguy.com\/semicolon\/2011\/05\/25\/a-simple-twitter-widget\/","title":{"rendered":"A simple Twitter widget"},"content":{"rendered":"<p>This blog&#8217;s sidebar displays my latest Twitter update. I did this manually instead of using a plugin because I couldn&#8217;t find a lightweight plugin that did what I want, and I thought it would be a quick and simple project. So here&#8217;s how I did it.<\/p>\n<p>My Twitter widget is written purely in HTML and JavaScript. This means that I can simply put the code into a WordPress Text widget. I don&#8217;t have to edit my theme or write a plugin.<\/p>\n<p>Initially I got the code for the widget straight from the Twitter website. There was a section where you could copy a little bit of HTML to paste into your site (or in a Text widget). This was great because the code was structured to be easily modifiable. They&#8217;ve changed to a more opaque implementation now, but they still serve the old scripts from their site. I&#8217;ve used these, plus an undocumented feature of the Twitter API, to make my own little Twitter widget.<\/p>\n<p>Here&#8217;s the code, with interesting bits highlighted:<\/p>\n<pre style=\"overflow-x:scroll\"><code>&lt;div id=\"twitter_div\"&gt;\r\n&lt;ul id=\"twitter_update_list\"&gt;&lt;\/ul&gt;\r\n&lt;div&gt;<strong style=\"color:red\">&lt;a href=\"http:\/\/www.twitter.com\/bnnt\"&gt;&lt;img alt=\"Follow bnnt on Twitter\" src=\"http:\/\/twitter-badges.s3.amazonaws.com\/follow_me-b.png\"&gt;&lt;\/a&gt;<\/strong>&lt;\/div&gt;\r\n&lt;\/div&gt;\r\n<strong style=\"color:red\">&lt;script type=\"text\/javascript\" src=\"http:\/\/twitter.com\/javascripts\/blogger.js\"&gt;&lt;\/script&gt;<\/strong>\r\n&lt;script type=\"text\/javascript\"&gt;\r\nfunction twitterCallback2_filtered(timeline) {\r\n\t\/\/ Try to select a non-reply\r\n\tvar select = 0, i;\r\n\tfor (i = 0; i &amp;lt; timeline.length; ++i) {\r\n\t\tif (timeline[i].text.charAt(0) != '@') {\r\n\t\t\tselect = i;\r\n\t\t\tbreak;\r\n\t\t}\r\n\t}\r\n\tvar status = timeline[select];\r\n\t\/\/ Edit the status\r\n\tstatus.text = status.text.replace(\/ #(?:yam|fb|in)\\b\/g, '');\r\n\ttwitterCallback2([status]);\r\n}\r\n&lt;\/script&gt;\r\n<strong style=\"color:red\">&lt;script type=\"text\/javascript\" src=\"http:\/\/api.twitter.com\/1\/statuses\/user_timeline.json?screen_name=bnnt&amp;amp;count=5&amp;amp;include_rts=true&amp;amp;callback=twitterCallback2_filtered\"&gt;&lt;\/script&gt;<\/strong><\/code><\/pre>\n<p>Here&#8217;s a breakdown of the code.<\/p>\n<p>The &#8220;Follow me on Twitter&#8221; button is taken straight from <a href=\"http:\/\/twitter.com\/about\/resources\/buttons\">Twitter&#8217;s Follow Buttons page<\/a>.<\/p>\n<pre><code>&lt;a href=\"http:\/\/www.twitter.com\/bnnt\"&gt;\r\n&lt;img alt=\"Follow bnnt on Twitter\" \r\nsrc=\"http:\/\/twitter-badges.s3.amazonaws.com\/follow_me-b.png\"&gt;\r\n&lt;\/a&gt;<\/code><\/pre>\n<p>Then the little formatting script Twitter have thoughtfully provided. It contains a function called <code>twitterCallback2<\/code>, which formats an array of tweets and writes them into a div with ID <code>twitter_update_list<\/code>.<\/p>\n<pre><code>&lt;script type=\"text\/javascript\" \r\nsrc=\"http:\/\/twitter.com\/javascripts\/blogger.js\"&gt;\r\n&lt;\/script&gt;<\/code><\/pre>\n<p>Twitter no longer seem to link to this script from their site, but it&#8217;s still there if you know where to look. I suppose thousands of sites will break if they ever remove this. It&#8217;s pretty simple &#8211; at some point I will write my own even simpler one and ditch theirs.<\/p>\n<p>At first I simply used the above script for my Twitter widget. But then I wanted to make a couple of changes. So I wrote a little filter which would tweak the returned tweets and then pass the result to the <code>twitterCallback2<\/code> function.<\/p>\n<pre><code>function twitterCallback2_filtered(timeline) {<\/code><\/pre>\n<p>First, I wanted to avoid displaying @replies, since they usually make no sense without context. For example: <a href=\"https:\/\/twitter.com\/bnnt\/status\/58740693497159680\">@DavidPlumpton &#8220;They also serve who only stand and look out of the window&#8221; (apologies to Milton)<\/a>. (Actually, that doesn&#8217;t make much sense even <em>with<\/em> the context.)<\/p>\n<p>To do this, I set the API call to fetch the last 5 tweets instead of the last one. Then I search through until I find one that isn&#8217;t an @reply. If they&#8217;re all @replies then I just give up and take the first one.<\/p>\n<pre><code>\t\/\/ Try to select a non-reply\r\n\tvar select = 0, i;\r\n\tfor (i = 0; i &amp;lt; timeline.length; ++i) {\r\n\t\tif (timeline[i].text.charAt(0) != '@') {\r\n\t\t\tselect = i;\r\n\t\t\tbreak;\r\n\t\t}\r\n\t}\r\n\tvar status = timeline[select];<\/code><\/pre>\n<p>I also wanted to filter out &#8220;control&#8221; hashtags that have nothing to do with the tweet. For example, the hashtag <code>#in<\/code> in a tweet will cross-post the tweet to my LinkedIn account. I don&#8217;t need this to show up in the widget. Likewise for <code>#fb<\/code> (Facebook) and <code>#yam<\/code> (Yammer).<\/p>\n<pre><code>\t\/\/ Edit the status\r\n\tstatus.text = status.text.replace(\/ #(?:yam|fb|in)\\b\/g, '');\r\n\ttwitterCallback2([status]);\r\n}<\/code><\/pre>\n<p>The last line of the function calls <code>twitterCallback2<\/code> to render the tweet.<\/p>\n<p>The last piece of the puzzle is the Twitter REST API call that actually fetches the tweets. I call <a href=\"http:\/\/dev.twitter.com\/doc\/get\/statuses\/user_timeline\">user_timeline<\/a> with the undocumented <code>callback<\/code> parameter to turn the response into <a href=\"http:\/\/en.wikipedia.org\/wiki\/JSONP\">JSONP<\/a> and call my <code>twitterCallback2_filtered<\/code> function. (To use the raw JSON result I would have to contend with the same-origin policy, which would complicate things considerably.)<\/p>\n<pre><code>&lt;script type=\"text\/javascript\" \r\nsrc=\"http:\/\/api.twitter.com\/1\/statuses\/user_timeline.json?\r\nscreen_name=bnnt&amp;amp;count=5&amp;amp;include_rts=true&amp;\r\namp;callback=twitterCallback2_filtered\"&gt;&lt;\/script&gt;<\/code><\/pre>\n<p>As I mentioned, the final step is to paste the code into a Text widget in my WordPress Admin screens. If you want to use this too, just change the two occurrences of &#8220;bnnt&#8221; to your own Twitter handle (unless you want to display my tweets on your blog).<\/p>\n<p><iframe allowtransparency=\"true\" frameborder=\"0\" scrolling=\"no\" src=\"http:\/\/platform.twitter.com\/widgets\/follow_button.html?screen_name=bnnt&#038;show_count=false\" style=\"width:300px; height:20px;\"><\/iframe><\/p>\n","protected":false},"excerpt":{"rendered":"<p>This blog&#8217;s sidebar displays my latest Twitter update. I did this manually instead of using a plugin because I couldn&#8217;t find a lightweight plugin that did what I want, and I thought it would be a quick and simple project. So here&#8217;s how I did it. My Twitter widget is written purely in HTML and [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[21,45,83],"class_list":["post-533","post","type-post","status-publish","format-standard","hentry","category-general","tag-javascript","tag-twitter","tag-wordpress"],"_links":{"self":[{"href":"https:\/\/thunderguy.com\/semicolon\/wp-json\/wp\/v2\/posts\/533","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/thunderguy.com\/semicolon\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/thunderguy.com\/semicolon\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/thunderguy.com\/semicolon\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/thunderguy.com\/semicolon\/wp-json\/wp\/v2\/comments?post=533"}],"version-history":[{"count":24,"href":"https:\/\/thunderguy.com\/semicolon\/wp-json\/wp\/v2\/posts\/533\/revisions"}],"predecessor-version":[{"id":549,"href":"https:\/\/thunderguy.com\/semicolon\/wp-json\/wp\/v2\/posts\/533\/revisions\/549"}],"wp:attachment":[{"href":"https:\/\/thunderguy.com\/semicolon\/wp-json\/wp\/v2\/media?parent=533"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/thunderguy.com\/semicolon\/wp-json\/wp\/v2\/categories?post=533"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/thunderguy.com\/semicolon\/wp-json\/wp\/v2\/tags?post=533"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}