<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;DkYMQ3k7cSp7ImA9WhRaFEk.&quot;"><id>tag:blogger.com,1999:blog-6915823</id><updated>2012-02-16T18:03:02.709-08:00</updated><category term="web" /><category term="penguin" /><category term="Apple" /><category term="RIA" /><category term="religious" /><category term="soda" /><category term="viral video" /><category term="cup" /><category term="Flash" /><category term="peru" /><category term="iPod" /><category term="Safari" /><category term="href" /><category term="Flex" /><category term="illustrations" /><category term="iOS" /><category term="myspace" /><category term="xhtml" /><category term="Adobe" /><category term="facebook" /><category term="mastercard" /><category term="unobtrusive javascript" /><category term="TV" /><category term="Rich Internet Apps." /><category term="CSS" /><category term="linked in" /><category term="Rails" /><category term="bakery" /><category term="battery" /><category term="cascading stylesheets" /><category term="geek" /><category term="links" /><category term="pizza" /><category term="Filipino" /><category term="IIc" /><category term="social networks" /><category term="Firefox" /><category term="iPhone" /><category term="larry king" /><category term="snoop dogg" /><category term="wig" /><category term="fake" /><category term="Danny Boyle" /><category term="flickr" /><category term="Speciality's" /><category term="sunshine" /><category term="IE8" /><category term="html" /><category term="stumblepon" /><category term="sweet" /><category term="Internet Explorer" /><category term="chicken" /><category term="cat" /><category term="JavaScript" /><category term="waffles" /><category term="MacBook" /><category term="lighter" /><category term="Microsoft" /><category term="beach" /><category term="box" /><category term="ebay" /><category term="Heroes" /><category term="ActionScript" /><category term="AJAX" /><category term="Pauly Shore" /><category term="environment" /><category term="youtube" /><category term="photos" /><category term="tan" /><category term="qunit" /><category term="surf" /><category term="sushi" /><category term="bread" /><category term="Grey's Anatomy" /><category term="CS3" /><category term="Android" /><category term="Digg" /><category term="IM" /><category term="pizdaus" /><category term="cookies" /><category term="programming" /><category term="tattoo" /><category term="lang" /><category term="smoker" /><category term="Trainspotting" /><category term="Prototype" /><category term="Sinatra" /><category term="reddit" /><category term="priceless" /><category term="The Browser Highlighter" /><category term="jquery" /><category term="SEO" /><category term="Ruby" /><category term="hacks" /><category term="food" /><category term="Linux" /><category term="San Francisco" /><category term="siren" /><category term="health" /><category term="fat" /><category term="solar" /><category term="T-Mobile" /><title>Skuunk</title><subtitle type="html">Movie reviews, food reviews, TV reviews, Tech reviews, Internet Memes and comments.</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://www.skuunk.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://www.skuunk.com/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/6915823/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>Anthony B</name><uri>http://www.blogger.com/profile/10041594734097301869</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>85</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/Skuunk" /><feedburner:info uri="skuunk" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><feedburner:browserFriendly></feedburner:browserFriendly><entry gd:etag="W/&quot;C0UASXY4fCp7ImA9WhdQF04.&quot;"><id>tag:blogger.com,1999:blog-6915823.post-3766676719309087380</id><published>2011-08-18T22:12:00.000-07:00</published><updated>2011-08-18T22:20:48.834-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-08-18T22:20:48.834-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript" /><category scheme="http://www.blogger.com/atom/ns#" term="AJAX" /><category scheme="http://www.blogger.com/atom/ns#" term="jquery" /><category scheme="http://www.blogger.com/atom/ns#" term="qunit" /><title>Stubbing out AJAX methods</title><content type="html">I have always had trouble with the standard way of testing out AJAX calls with QUnit.
&lt;br /&gt;
&lt;br /&gt;There are a number of problems with it.
&lt;br /&gt;
&lt;br /&gt;1) You have to stop and start the tests while waiting for an AJAX response
&lt;br /&gt;2) If you don't give a large enough gap, then your test may fail while waiting for an AJAX response. 
&lt;br /&gt;3) If you have too large a gap, it slows down your tests
&lt;br /&gt;
&lt;br /&gt;However, today I found this cool method of dealing with it.
&lt;br /&gt;
&lt;br /&gt;http://lostechies.com/johnteague/2009/02/10/another-way-to-test-ajax-methods/
&lt;br /&gt;
&lt;br /&gt;Essentially, you stub out jQuery's $.ajax() method with your own for your tests (as for unit testing, you really just want to test your code around the ajax method, not test jQuery's ajax method).
&lt;br /&gt;
&lt;br /&gt;In my own case, I was using $.ajax and not $.getJSON. It took me a little while to work out I had to create a trigger for the success() function rather then callback() as mentioned in the article.
&lt;br /&gt;
&lt;br /&gt;&lt;pre&gt;
&lt;br /&gt;
&lt;br /&gt;var stubbedAjax = function(settings){
&lt;br /&gt; settings.beforeSend();
&lt;br /&gt; // so I can check error cases
&lt;br /&gt; if (settings.url == 'error'){
&lt;br /&gt;  settings.error();
&lt;br /&gt; } else {
&lt;br /&gt;  settings.success({data: "data"});
&lt;br /&gt; }
&lt;br /&gt;}
&lt;br /&gt;var originalAjax = jQuery.ajax;
&lt;br /&gt;module("WESTFIELD Product Index Aggregator",{setup:function(){jQuery.ajax = stubbedAjax}, teardown:function(){jQuery.ajax = originalAjax}});
&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;http://www.skuunk.com&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6915823-3766676719309087380?l=www.skuunk.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.skuunk.com/feeds/3766676719309087380/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6915823&amp;postID=3766676719309087380" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6915823/posts/default/3766676719309087380?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6915823/posts/default/3766676719309087380?v=2" /><link rel="alternate" type="text/html" href="http://www.skuunk.com/2011/08/stubbing-out-ajax-methods.html" title="Stubbing out AJAX methods" /><author><name>Anthony B</name><uri>http://www.blogger.com/profile/10041594734097301869</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;DkUBSX48eip7ImA9WhdTGUQ.&quot;"><id>tag:blogger.com,1999:blog-6915823.post-253902750621790583</id><published>2011-07-18T05:52:00.000-07:00</published><updated>2011-07-18T06:04:18.072-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-07-18T06:04:18.072-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript" /><category scheme="http://www.blogger.com/atom/ns#" term="jquery" /><category scheme="http://www.blogger.com/atom/ns#" term="Rails" /><title>Patterns</title><content type="html">Just a couple of links today (more details to follow).&lt;br /&gt;&lt;br /&gt;I found a great reference for JavaScript and jQuery Design Patterns here:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://addyosmani.com/resources/essentialjsdesignpatterns/book/"&gt;http://addyosmani.com/resources/essentialjsdesignpatterns/book/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Also, I learned about the Presenter pattern today. We were having a discussion at work about what to do with presentation logic in Rails. On the one hand you don't want it in the controller because you want to keep your controllers thin, on the other hand you don't want it in the models either because it's presentational. You can't put it in the erb because they shouldn't contain logic. Enter the Presenter Pattern:&lt;br /&gt;&lt;br /&gt;&lt;a href="http://donttrustthisguy.com/2008/05/29/using-presenters-in-rails-3/"&gt;http://donttrustthisguy.com/2008/05/29/using-presenters-in-rails-3/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;a href="http://blog.jayfields.com/2007/03/rails-presenter-pattern.html"&gt;http://blog.jayfields.com/2007/03/rails-presenter-pattern.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Enjoy your homework!&lt;div class="blogger-post-footer"&gt;http://www.skuunk.com&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6915823-253902750621790583?l=www.skuunk.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.skuunk.com/feeds/253902750621790583/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6915823&amp;postID=253902750621790583" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6915823/posts/default/253902750621790583?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6915823/posts/default/253902750621790583?v=2" /><link rel="alternate" type="text/html" href="http://www.skuunk.com/2011/07/patterns.html" title="Patterns" /><author><name>Anthony B</name><uri>http://www.blogger.com/profile/10041594734097301869</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;AkcAQ3ozcCp7ImA9WhZaGUk.&quot;"><id>tag:blogger.com,1999:blog-6915823.post-4364037867403649460</id><published>2011-07-06T03:06:00.000-07:00</published><updated>2011-07-06T03:27:22.488-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-07-06T03:27:22.488-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="CSS" /><title>What is !important?</title><content type="html">In CSS, you can override a style on a class simply by declaring a new style further down the page&lt;br /&gt;&lt;br /&gt;i.e.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;p {&lt;br /&gt;    padding-top:5px;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;p.custom {&lt;br /&gt;    padding:10px;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Basically the above code sets the padding-top on all paragraphs to 5px, but sets the padding to 10px on paragraphs with the "custom" class. So we are overriding padding on our custom class.&lt;br /&gt;&lt;br /&gt;However, you can actually prevent an attribute's style from being overridden if for some reason you really really don't want the padding to change in your design. Perhaps you are working with multiple people and you really don't want someone to accidentally override your design. Perhaps you just want to ensure your padding-top is always 5px even if padding is reset somewhere else.&lt;br /&gt;&lt;br /&gt;In order to do this we use !important.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;p {&lt;br /&gt;    padding-top:5px !important;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;p.custom {&lt;br /&gt;    padding:10px;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;In this case, the padding-top on a paragraph will always stay at 5px regardless of whether or not it has a "custom" class. It will also stay at 5px if you do the following...&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;p {&lt;br /&gt;    padding-top:5px !important;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;p.custom {&lt;br /&gt;    padding:10px;&lt;br /&gt;    padding-top:10px;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;However all is not lost. Let's say you have imported someone else's CSS library and you want to tweak it but you find that they have used !important on the one style you want to update? Just use !important yourself...&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;p {&lt;br /&gt;    padding-top:5px !important;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;p.custom {&lt;br /&gt;    padding:10px !important;&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Yay! You can play in God mode too!&lt;br /&gt;&lt;br /&gt;Of course in general it's best to avoid !important in every day situations. It's not really best practice, but it's there should you need it...&lt;div class="blogger-post-footer"&gt;http://www.skuunk.com&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6915823-4364037867403649460?l=www.skuunk.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.skuunk.com/feeds/4364037867403649460/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6915823&amp;postID=4364037867403649460" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6915823/posts/default/4364037867403649460?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6915823/posts/default/4364037867403649460?v=2" /><link rel="alternate" type="text/html" href="http://www.skuunk.com/2011/07/what-is-important.html" title="What is !important?" /><author><name>Anthony B</name><uri>http://www.blogger.com/profile/10041594734097301869</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;D0QAQHk9eyp7ImA9WhZWFU0.&quot;"><id>tag:blogger.com,1999:blog-6915823.post-6254974176654435737</id><published>2011-05-15T17:06:00.000-07:00</published><updated>2011-05-15T17:22:21.763-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-05-15T17:22:21.763-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Android" /><category scheme="http://www.blogger.com/atom/ns#" term="iOS" /><category scheme="http://www.blogger.com/atom/ns#" term="Flash" /><title>The REAL reason you need Flash in a mobile device...</title><content type="html">People keep going on about how you don't need Flash on a mobile device because most video sites like YouTube provide HTML 5 flash free versions. Therefore the limitation of no Flash on an iPhone isn't really a limitation (if you have been drinking Steve Jobs' Apple juice/kool aid).&lt;br /&gt;&lt;br /&gt;Anyways, last Saturday I found out the REAL reason you need Flash on a mobile device and it has nothing to do with video.&lt;br /&gt;&lt;br /&gt;It has to do with restaurant sites.&lt;br /&gt;&lt;br /&gt;For some reason at least 80% of restaurants out there have Flash only websites. If you need to make a reservation and you can't find the phone number in Yelp or UrbanSpoon then you have a problem.&lt;br /&gt;&lt;br /&gt;In any case, I was trying to find the number for a restaurant and Google gave me a link to their website. Unfortunately, their website is in Flash. Fortunately for me though, my phone is an Android phone and I was able to look up their phone number and address in spite of the limitation.&lt;br /&gt;&lt;br /&gt;In general though, having Flash on a restaurant website is annoying. All I want is the address, phone number, a copy of the menu and a few pictures of the interior and the food. The ability to make reservations online is also a plus (not to mention online ordering if it's a take out restaurant).&lt;br /&gt;&lt;br /&gt;PS In spite of their lousy Flash only website, I do really recommend the food at Anong Thai in Potts Point, Sydney. It is excellent!&lt;br /&gt;&lt;a href="http://www.anongthai.com.au/"&gt;http://www.anongthai.com.au/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;http://www.skuunk.com&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6915823-6254974176654435737?l=www.skuunk.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.skuunk.com/feeds/6254974176654435737/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6915823&amp;postID=6254974176654435737" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6915823/posts/default/6254974176654435737?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6915823/posts/default/6254974176654435737?v=2" /><link rel="alternate" type="text/html" href="http://www.skuunk.com/2011/05/real-reason-you-need-flash-in-mobile.html" title="The REAL reason you need Flash in a mobile device..." /><author><name>Anthony B</name><uri>http://www.blogger.com/profile/10041594734097301869</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;CEIGQHs8fCp7ImA9WhZWEE8.&quot;"><id>tag:blogger.com,1999:blog-6915823.post-7628294069280985769</id><published>2011-05-10T03:04:00.000-07:00</published><updated>2011-05-10T03:15:21.574-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-05-10T03:15:21.574-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="CSS" /><title>CSS Back to basics: Here comes TRBL</title><content type="html">So I guess CSS is not obvious to everyone. One of my coworkers asked today why you sometimes had 1 value after a "padding" attribute and sometimes you had 2 or 4 values.&lt;br /&gt;&lt;br /&gt;Basically, &lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;padding: 5px;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Puts a 5 pixel padding on an element.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;padding: 5px 3px;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Means you have 5 pixels of padding on the top and bottom and 3 pixels on the sides&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;padding: 3px 4px 5px 10px;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Means you have 3 pixels of padding on top, 4 on the right, 5 on the bottom and 10 on the left.&lt;br /&gt;&lt;br /&gt;A good way to remember this is the acronym TRBL (like "trouble").&lt;br /&gt;&lt;br /&gt;The same applies to "margin".&lt;br /&gt;&lt;br /&gt;As well as this, you also have extra attributes which can specify the top, bottom, right and left paddings on their own&lt;br /&gt;&lt;br /&gt;i.e.&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;padding-left: 10px;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;Sometimes, if only one side is unique, it's better to refer to it in the following way (for readability).&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;padding:5px;&lt;br /&gt;padding-left: 10px;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The "padding-left" of 10px will override the "padding" of 5px, but only on the left side of the element.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;padding: 5px 5px 5px 10px;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;The above does the same, but is less readable in my opinion.&lt;div class="blogger-post-footer"&gt;http://www.skuunk.com&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6915823-7628294069280985769?l=www.skuunk.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.skuunk.com/feeds/7628294069280985769/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6915823&amp;postID=7628294069280985769" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6915823/posts/default/7628294069280985769?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6915823/posts/default/7628294069280985769?v=2" /><link rel="alternate" type="text/html" href="http://www.skuunk.com/2011/05/css-back-to-basics-here-comes-trbl.html" title="CSS Back to basics: Here comes TRBL" /><author><name>Anthony B</name><uri>http://www.blogger.com/profile/10041594734097301869</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;D0IGRHczfip7ImA9WhZXEE4.&quot;"><id>tag:blogger.com,1999:blog-6915823.post-3396299156209318662</id><published>2011-04-28T16:50:00.000-07:00</published><updated>2011-04-28T17:05:25.986-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-28T17:05:25.986-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Ruby" /><category scheme="http://www.blogger.com/atom/ns#" term="Rails" /><title>Rails file uploads: Limiting a user's uploads by space available</title><content type="html">Let's say that you want to allow people to upload files to your server. Let's also say that we want to make sure any particular user does not hog up all the space available. Let's also say you want to give each user a variable limit as to how much they can upload (i.e. for tiered services). How would you go about doing that?&lt;br /&gt;&lt;br /&gt;Well, from a pseudo code perspective you would do the following.&lt;br /&gt;&lt;br /&gt;1) Create a folder for each user based on the user id&lt;br /&gt;2) Make sure all the user's uploads go to that folder&lt;br /&gt;3) Before you do an upload, check against the user's settings to see how much space s/he is allowed&lt;br /&gt;4) Check their folder to see how much space has been used&lt;br /&gt;5) If they have no space left, message the user&lt;br /&gt;&lt;br /&gt;So let's see how we do this in practice...&lt;br /&gt;&lt;br /&gt;I guess we really want to see how much space is used, so let's start there on the User. In this example the user has a UUID as well as a space_allowed attribute which is set to a default value (and which an admin can change).&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  def space_used&lt;br /&gt;    space = 0&lt;br /&gt;    directory = "#{Rails.root}/uploads/#{self.user.uuid}"&lt;br /&gt;    &lt;br /&gt;    if File.directory?(directory)&lt;br /&gt;      Find.find(directory) { |f| &lt;br /&gt;        space += File.size(f); &lt;br /&gt;      }&lt;br /&gt;    end&lt;br /&gt;    return space&lt;br /&gt;  end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;So space_used first sets the directory based on the user's uuid. It then checks to see if that directory exists, and if it does, it will loop through each file and total up the space variable (unfortunately, the Directory object does not have a size variable) to see how much space has been used.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;  def space_available?&lt;br /&gt;    if self.space_used &gt;= self.space_allowed&lt;br /&gt;      return false&lt;br /&gt;    end&lt;br /&gt;    return true&lt;br /&gt;  end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;space_available? checks the space used and compares it to the space_allowed to the user. So in the controller you just need to call space_available? on the user and handle it appropriately&lt;br /&gt;&lt;br /&gt;i.e.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;user = User.find(params[:id])&lt;br /&gt;if user.space_available?&lt;br /&gt;  ... handle upload ...&lt;br /&gt;else&lt;br /&gt;  ... handle error ...&lt;br /&gt;end&lt;br /&gt;&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;http://www.skuunk.com&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6915823-3396299156209318662?l=www.skuunk.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.skuunk.com/feeds/3396299156209318662/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6915823&amp;postID=3396299156209318662" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6915823/posts/default/3396299156209318662?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6915823/posts/default/3396299156209318662?v=2" /><link rel="alternate" type="text/html" href="http://www.skuunk.com/2011/04/rails-file-uploads-limiting-users.html" title="Rails file uploads: Limiting a user's uploads by space available" /><author><name>Anthony B</name><uri>http://www.blogger.com/profile/10041594734097301869</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;C0EGSXg8eCp7ImA9WhZXEE4.&quot;"><id>tag:blogger.com,1999:blog-6915823.post-6490305763769295868</id><published>2011-04-28T15:08:00.000-07:00</published><updated>2011-04-28T16:00:28.670-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-28T16:00:28.670-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript" /><category scheme="http://www.blogger.com/atom/ns#" term="Ruby" /><category scheme="http://www.blogger.com/atom/ns#" term="Sinatra" /><title>Reading AJAX XHR File Uploads in Sinatra</title><content type="html">So in my last post I talked about Drag and Drop file uploading with qq.FileUploader (&lt;a href="http://valums.com/ajax-upload/"&gt;http://valums.com/ajax-upload/&lt;/a&gt;).&lt;br /&gt;&lt;br /&gt;Anyways, I discovered that qq.FileUploader uses AJAX/XHR to post the file uploads. What I also discovered is that these file uploads need to be handled in a separate manner from a regular file upload form post.&lt;br /&gt;&lt;br /&gt;A normal form post (when File upload XHR requests are not available on the client like in Internet Explorer) passes in the following parameters&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;params: {"qqfile"=&gt;{:type=&gt;"image/png", :head=&gt;"Content-Disposition: form-data; name=\"qqfile\"; filename=\"bb2.png\"\r\nContent-Type: image/png\r\n", :tempfile=&gt;#&lt;File:/var/folders/lf/lfR+xuO7E+Glb0YcfwejqE+++TU/-Tmp-/RackMultipart20110429-33913-1vur7th-0&gt;, :name=&gt;"qqfile", :filename=&gt;"bb2.png"}, "upload_type"=&gt;"rec", "id"=&gt;"24db8cab-285a-abcb-cb47-4daceee977ca"}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Sinatra then reads the :tempfile and :filename parameters to write the file to the server&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;name = params[:qqfile][:filename]&lt;br /&gt;      &lt;br /&gt;# create the file path&lt;br /&gt;path = File.join(directory, name)&lt;br /&gt;# write the file&lt;br /&gt;File.open(path, "wb") { |f| f.write(params[:qqfile][:tempfile].read) }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;However, if you use a browser that supports XHR uploads, the parameters look a little different&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;params: {"qqfile"=&gt;"device1.jpg", "upload_type"=&gt;"invoice", "id"=&gt;"24db8cab-285a-abcb-cb47-4daceee977ca"}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So this had me stumped. There was an article I found on the internets (&lt;a href="http://onehub.com/blog/posts/designing-an-html5-drag-drop-file-uploader-using-sinatra-and-jquery-part-1/"&gt;http://onehub.com/blog/posts/designing-an-html5-drag-drop-file-uploader-using-sinatra-and-jquery-part-1/&lt;/a&gt;) which talked extensively on how to do the JavaScript side but then at the bottom conveniently left out how to handle the server side (saying it was easy to work out). Well, it wasn't! So that's why I am writing this post&lt;br /&gt;&lt;br /&gt;In any case, I won't keep you in suspense any longer...&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;name = env['HTTP_X_FILENAME']&lt;br /&gt;      &lt;br /&gt;string_io = request.body # will return a StringIO&lt;br /&gt;      &lt;br /&gt;data_bytes = string_io.read # read the stream as bytes&lt;br /&gt;      &lt;br /&gt;# create the file path&lt;br /&gt;path = File.join(directory, name)&lt;br /&gt;      &lt;br /&gt;# Write it to disk...&lt;br /&gt;File.open(path, 'w') {|f| f.write(data_bytes) }&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;The final part is that qq.FileUploader does not give you the option to specify which action to post to depending on the type of upload (XHR vs normal) so I had to put in a fork in the server code to figure out how to handle the request. I am basically checking to see if qqfile is of type String, in which case I handle it as an XHR upload, otherwise I handle it as a normal file upload.&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;# if qqfile is a string, we are using XHR upload, else use regular upload&lt;br /&gt;    if params[:qqfile].class == String&lt;br /&gt;      name = params[:qqfile]&lt;br /&gt;      &lt;br /&gt;      string_io = request.body # will return a StringIO&lt;br /&gt;      &lt;br /&gt;      data_bytes = string_io.read # read the stream as bytes&lt;br /&gt;      &lt;br /&gt;      # create the file path&lt;br /&gt;      path = File.join(directory, name)&lt;br /&gt;      &lt;br /&gt;      # Write it to disk...&lt;br /&gt;      File.open(path, 'w') {|f| f.write(data_bytes) }&lt;br /&gt;    else #regular file upload&lt;br /&gt;      name = params[:qqfile][:filename]&lt;br /&gt;      &lt;br /&gt;      # create the file path&lt;br /&gt;      path = File.join(directory, name)&lt;br /&gt;      # write the file&lt;br /&gt;      File.open(path, "wb") { |f| f.write(params[:qqfile][:tempfile].read) }&lt;br /&gt;    end&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;I haven't tried it in Rails yet, but I am sure it will be similar. I hope this helps...&lt;div class="blogger-post-footer"&gt;http://www.skuunk.com&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6915823-6490305763769295868?l=www.skuunk.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.skuunk.com/feeds/6490305763769295868/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6915823&amp;postID=6490305763769295868" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6915823/posts/default/6490305763769295868?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6915823/posts/default/6490305763769295868?v=2" /><link rel="alternate" type="text/html" href="http://www.skuunk.com/2011/04/reading-ajax-xhr-file-uploads-in.html" title="Reading AJAX XHR File Uploads in Sinatra" /><author><name>Anthony B</name><uri>http://www.blogger.com/profile/10041594734097301869</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>3</thr:total></entry><entry gd:etag="W/&quot;A04BQn45cCp7ImA9WhZQGEQ.&quot;"><id>tag:blogger.com,1999:blog-6915823.post-2619694755963912675</id><published>2011-04-27T03:14:00.000-07:00</published><updated>2011-04-27T03:25:53.028-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-27T03:25:53.028-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript" /><title>Ajax File Uploading</title><content type="html">You know that cool Drag and Drop file uploading they have in Gmail? You know, the one where you can drag a file from a folder onto a webpage and upload it?&lt;br /&gt;&lt;br /&gt;Have you looked at the code? Looks complicated huh?&lt;br /&gt;&lt;br /&gt;Well, thankfully, for any cool bit of JavaScript functionality out there, someone has created a plug in (most likely in jQuery, but not always...).&lt;br /&gt;&lt;br /&gt;&lt;a href="http://valums.com/ajax-upload/"&gt;http://valums.com/ajax-upload/&lt;/a&gt; is (as far as I can tell) a library agnostic JavaScript plug in which factors out all the hard work.&lt;br /&gt;&lt;br /&gt;All you have to do is put in a "dummy" element on to which to hook (never end a sentence in a preposition) and then put in a small snippet of code to turn it into a file upload element&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;div id="file-uploader"&gt;       &lt;br /&gt;    &amp;lt;noscript&gt;          &lt;br /&gt;        &amp;lt;p&gt;Please enable JavaScript to use file uploader.&amp;lt;/p&gt;&lt;br /&gt;    &amp;lt;/noscript&gt;         &lt;br /&gt;&amp;lt;/div&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;var uploader = new qq.FileUploader({&lt;br /&gt;    // pass the dom node (ex. $(selector)[0] for jQuery users)&lt;br /&gt;    element: document.getElementById('file-uploader'),&lt;br /&gt;    // path to server-side upload script&lt;br /&gt;    action: '/server/upload'&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;Obviously you need to include their library as well...&lt;br /&gt;&lt;br /&gt;It has some common backend code to handle uploads as well (php, perl, cgi, java) but no Ruby. Come on guys! Get with it already! Hopefully they will read this and provide...&lt;div class="blogger-post-footer"&gt;http://www.skuunk.com&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6915823-2619694755963912675?l=www.skuunk.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.skuunk.com/feeds/2619694755963912675/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6915823&amp;postID=2619694755963912675" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6915823/posts/default/2619694755963912675?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6915823/posts/default/2619694755963912675?v=2" /><link rel="alternate" type="text/html" href="http://www.skuunk.com/2011/04/ajax-file-uploading.html" title="Ajax File Uploading" /><author><name>Anthony B</name><uri>http://www.blogger.com/profile/10041594734097301869</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;C0EERH89cCp7ImA9WhZXEE4.&quot;"><id>tag:blogger.com,1999:blog-6915823.post-1392570093989851720</id><published>2011-04-26T03:46:00.000-07:00</published><updated>2011-04-28T16:00:05.168-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-28T16:00:05.168-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript" /><category scheme="http://www.blogger.com/atom/ns#" term="Ruby" /><title>Node.js</title><content type="html">I had a quick look at &lt;a href="http://nodejs.org/"&gt;Node.js&lt;/a&gt;. Looks very interesting (kind of like a JavaScript version of &lt;a href="http://www.sinatrarb.com/"&gt;Sinatra&lt;/a&gt;). Now all I need to do is find out if they have any frameworks...&lt;div class="blogger-post-footer"&gt;http://www.skuunk.com&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6915823-1392570093989851720?l=www.skuunk.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.skuunk.com/feeds/1392570093989851720/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6915823&amp;postID=1392570093989851720" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6915823/posts/default/1392570093989851720?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6915823/posts/default/1392570093989851720?v=2" /><link rel="alternate" type="text/html" href="http://www.skuunk.com/2011/04/nodejs.html" title="Node.js" /><author><name>Anthony B</name><uri>http://www.blogger.com/profile/10041594734097301869</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;CkEGSXs6eyp7ImA9WhZQGU0.&quot;"><id>tag:blogger.com,1999:blog-6915823.post-4886299317678518218</id><published>2011-04-20T21:50:00.000-07:00</published><updated>2011-04-27T03:37:08.513-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-27T03:37:08.513-07:00</app:edited><title>Show Off IO</title><content type="html">Just found a great new service called Show Off IO&lt;br /&gt;&lt;br /&gt;&lt;a href="https://showoff.io/"&gt;https://showoff.io/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;This is a godsend for Ruby contractors. Basically you port forward the web server on your laptop to showoff and they give you a URL which you can send to a client which allows him to see your website (for a limited time for the free version).&lt;br /&gt;&lt;br /&gt;Previous to this, you would have to wait until you had staged the site to show it to your clients.&lt;br /&gt;&lt;br /&gt;Good job guys!&lt;div class="blogger-post-footer"&gt;http://www.skuunk.com&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6915823-4886299317678518218?l=www.skuunk.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.skuunk.com/feeds/4886299317678518218/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6915823&amp;postID=4886299317678518218" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6915823/posts/default/4886299317678518218?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6915823/posts/default/4886299317678518218?v=2" /><link rel="alternate" type="text/html" href="http://www.skuunk.com/2011/04/show-off-io.html" title="Show Off IO" /><author><name>Anthony B</name><uri>http://www.blogger.com/profile/10041594734097301869</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>1</thr:total></entry><entry gd:etag="W/&quot;DEEMRXwyfyp7ImA9WhZQE0g.&quot;"><id>tag:blogger.com,1999:blog-6915823.post-2639348673311359279</id><published>2011-04-20T19:47:00.000-07:00</published><updated>2011-04-20T20:31:24.297-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-20T20:31:24.297-07:00</app:edited><title>RhoMobile - Ruby Development for Mobile</title><content type="html">RhoMobile (&lt;a href="http://rhomobile.com/"&gt;http://rhomobile.com/&lt;/a&gt;) offers an open source framework which allows Ruby developers to write mobile apps using web technologies.&lt;br /&gt;&lt;br /&gt;I have been using it for about a year now. You can find out the details of it on the website linked above, but I just wanted to go over some of the issues I have found and cover some of the pluses in minuses from a personal perspective to help you decide whether or not this is a technology you will want to exploit on your next project.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;So what is it?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;At a basic level, a Rhodes (&lt;a href="http://rhomobile.com/products/rhodes/"&gt;http://rhomobile.com/products/rhodes/&lt;/a&gt;) app comprises of a small Ruby web server/framework and an embedded browser. Server is a little bit of a misnomer because it lives on the client, but essentially it's like a small Rails server which is only used by one client (though in theory you can connect to it from another client if you so choose).&lt;br /&gt;&lt;br /&gt;Because the display is done in an embedded browser, you can mark it up in HTML and CSS and even (in some cases) use JavaScript to manipulate the display dynamically.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;So why use Rhodes instead of creating a mobile web app?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Well, for one, you can package a Rhodes app and sell it in the app store, android market or app world.&lt;br /&gt;&lt;br /&gt;It also (if you need it to) can sync with a sophisticated sync server known as RhoSync (&lt;a href="http://rhomobile.com/products/rhosync/"&gt;http://rhomobile.com/products/rhosync/&lt;/a&gt;). As of the time of writing, RhoSync is built upon Sinatra and Redis (it used to be Rails and MySQL). This means that a user can manage and manipulate his/her data on their phone without the need for a constant internet connection and that data can be periodically synced with the back end. RhoSync manages all the potential data conflicts and only syncs the differences. It can connect to practically any kind of data store (databases, REST APIs, etc...).&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;So what are some of the limitations of Rhodes?&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;So, unfortunately, nothing in life is perfect. One limitation is that because it relies on embedded browsers, if your app does any fancy JavaScript or CSS3 you will have to write another set of HTML only views for BlackBerry (though apparently the latest BlackBerry versions use a WebKit browser. I have yet to try this personally though).&lt;br /&gt;&lt;br /&gt;It also really is targeted at the high end smart phones. It is quite well optimised for iOS, but on slower Android devices (anything with less than a 600Mhz processor) it can be quite slow and sluggish.&lt;br /&gt;&lt;br /&gt;Another thing to get one's head around is that even though the framework is Rails-like, it is not exactly the same as Rails (it is quite stripped down). The RhoMobile team have been busy adding features however so its ecosystem is growing. When I started using it, there were no models (only controllers and views). Since then, Model support has been added as well as MSpec for testing.&lt;br /&gt;&lt;br /&gt;Once your product is done, adding it to the respective app markets is also quite a hassle. This is by no means the fault of RhoMobile or the Rhodes team, but it is something to consider when trying to decide between doing a web based app vs an installable one.&lt;br /&gt;&lt;br /&gt;The other limitation is because Rhodes is designed to work with most of the major smart phones on the market, you haven't got access to all the available features on a specific mobile phone. There is limited camera and calendar support, but currently no audio or video recording (it's in the road map, but not yet available). So you are not going to be able to write an app like Shazam or Google Maps using the framework...&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Conclusion&lt;/span&gt;&lt;br /&gt;If you like Ruby, web technologies AND mobile apps then it's definitely worth taking a look at RhoMobile. It's especially suited for Enterprise App development where you may not need the latest fancy UI enhancements, but you do want to deploy on all the platforms that your team is using with a single code base.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;More References&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;You can find more information on the app I developed at&lt;br /&gt;&lt;a href="http://rhologic.com/"&gt;http://rhologic.com/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;http://www.skuunk.com&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6915823-2639348673311359279?l=www.skuunk.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.skuunk.com/feeds/2639348673311359279/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6915823&amp;postID=2639348673311359279" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6915823/posts/default/2639348673311359279?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6915823/posts/default/2639348673311359279?v=2" /><link rel="alternate" type="text/html" href="http://www.skuunk.com/2011/04/rhomobile-ruby-development-for-mobile.html" title="RhoMobile - Ruby Development for Mobile" /><author><name>Anthony B</name><uri>http://www.blogger.com/profile/10041594734097301869</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>3</thr:total></entry><entry gd:etag="W/&quot;CE4DR308fip7ImA9WhZQE0g.&quot;"><id>tag:blogger.com,1999:blog-6915823.post-6648545353636239021</id><published>2011-04-20T16:12:00.000-07:00</published><updated>2011-04-20T19:29:36.376-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2011-04-20T19:29:36.376-07:00</app:edited><title>Responsive Web Design</title><content type="html">I wanted to go over Responsive Web Design using CSS.&lt;br /&gt;&lt;br /&gt;In the old days of web development, we had to code to common screen sizes (i.e. 800 X 600, 1024 X 768) and we patiently waited for people to upgrade their computers to have a decent amount of screen real estate so we could design things the way we really wanted. We also took on semi stretchy web layouts etc to expand and contract appropriately.&lt;br /&gt;&lt;br /&gt;Then about 2 or 3 years ago, Apple released this little device called an iPhone with a 320 X 480 resolution which took the world by storm and suddenly a lot of people were viewing your website on a tiny screen again...&lt;br /&gt;&lt;br /&gt;Anyways, as it can be difficult to design a site which looks good on 320 X 480 AND 1680 X 1050, we need to come up with some kind of solution.&lt;br /&gt;&lt;br /&gt;One way is to sniff the client and then use an appropriate stylesheet, but then you are mixing CSS with either JavaScript or server side programming and also potentially maintaining a list of appropriate clients and stylesheets. Also, you can miss out new devices/clients as they come along.&lt;br /&gt;&lt;br /&gt;The other way is to use the media queries and detect the screen size using CSS.&lt;br /&gt;&lt;br /&gt;i.e.&lt;br /&gt;&lt;br /&gt;@media screen and (max-device-width: 480px), screen and (max-width: 480px) {&lt;br /&gt;  ...&lt;br /&gt;  appropriate iPhone/Android CSS rules go here&lt;br /&gt;  ...&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;You can also "detect" for iPad by using 768 instead of 480.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Things to look out for&lt;/span&gt;&lt;br /&gt;I found that although it is possible to move elements around using CSS, there are some limitations with regards to content flow. In one design that I was given by my designer, the logo was to move from the middle to the top of the page depending on the device. What I ended up doing was creating 2 logos and hid/showed them appropriately.&lt;br /&gt;&lt;br /&gt;It also helps to break the page down to standard elements (main content, header, footer, etc...) and focus on designing/laying out these elements appropriately. Once you are done with that, you are 80% of the way there and you might only need to do some minor tweaking of the main content section thereafter (i.e. moving form labels from the side to the top for example).&lt;br /&gt;&lt;br /&gt;It is important to know your audience as well. In my case, this time around, I am working on a site which is an adjunct to a phone app and it is important for our audience to be able to view the site well on a phone as well as a full size computer. This does involve extra work so there may not be any business to justify it in your case.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Further links&lt;/span&gt;&lt;br /&gt;&lt;a href="http://www.alistapart.com/articles/responsive-web-design/"&gt;http://www.alistapart.com/articles/responsive-web-design/&lt;/a&gt;&lt;br /&gt;&lt;a href="http://mediaqueri.es"&gt;http://mediaqueri.es&lt;/a&gt;/&lt;div class="blogger-post-footer"&gt;http://www.skuunk.com&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6915823-6648545353636239021?l=www.skuunk.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.skuunk.com/feeds/6648545353636239021/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6915823&amp;postID=6648545353636239021" title="11 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6915823/posts/default/6648545353636239021?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6915823/posts/default/6648545353636239021?v=2" /><link rel="alternate" type="text/html" href="http://www.skuunk.com/2011/04/responsive-web-design.html" title="Responsive Web Design" /><author><name>Anthony B</name><uri>http://www.blogger.com/profile/10041594734097301869</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>11</thr:total></entry><entry gd:etag="W/&quot;CE4EQng_fyp7ImA9Wx9SF0o.&quot;"><id>tag:blogger.com,1999:blog-6915823.post-4201516886437571441</id><published>2010-12-07T17:34:00.000-08:00</published><updated>2010-12-07T17:48:23.647-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-12-07T17:48:23.647-08:00</app:edited><title>The importance of transitions...</title><content type="html">I was just having a look at github's new tree slider.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;a href="https://github.com/blog/760-the-tree-slider"&gt;https://github.com/blog/760-the-tree-slider&lt;/a&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;In any case, it got me interested in the importance of transitions. Back in the old, pre-ajax, pre-broadband days, we would click on a link, go get a cup of coffee and then come back to a new screen. In the meantime the little "loading" icon would spin which would let us know that something was happening.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Nowadays, not only is it possible to change part of a page without reloading the whole page (thanks to AJAX), but with our new browsers and broadband connections, this could change so fast that we don't even notice.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I will be the first to admit that early versions of JavaScript transitions were not only buggy, but they seemed to be a luxury. For a start, the fades and slides were slow and jittery and led to a bad user experience. The extra JS libraries also added to page load. At the end of the day, who cares how we got where we were going as long as we got there.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Now however, they seem a bit more of a necessity. They let the user know what happened on the page and where.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Going forward, it would be nice to see some conventions appear as well. Fade in for dialogs, slide left for new page, slide right for old, etc...&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;http://www.skuunk.com&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6915823-4201516886437571441?l=www.skuunk.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.skuunk.com/feeds/4201516886437571441/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6915823&amp;postID=4201516886437571441" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6915823/posts/default/4201516886437571441?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6915823/posts/default/4201516886437571441?v=2" /><link rel="alternate" type="text/html" href="http://www.skuunk.com/2010/12/importance-of-transitions.html" title="The importance of transitions..." /><author><name>Anthony B</name><uri>http://www.blogger.com/profile/10041594734097301869</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;CUAASXg_fip7ImA9WxJUGEs.&quot;"><id>tag:blogger.com,1999:blog-6915823.post-2878037040573836350</id><published>2009-07-17T12:31:00.000-07:00</published><updated>2009-07-17T13:49:08.646-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-17T13:49:08.646-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript" /><category scheme="http://www.blogger.com/atom/ns#" term="The Browser Highlighter" /><category scheme="http://www.blogger.com/atom/ns#" term="Firefox" /><title>Browser Highlighter Firefox extension / plug in</title><content type="html">On my site we noticed that some of our users had some JavaScript problems which was affecting content editing. After a bit of nosing around we found the problem was a Firefox extension called The Browser Highlighter.&lt;br /&gt;&lt;br /&gt;This extension was created by eBay and it injects some JavaScript into the page which can affect the JS in your site. You can view this JavaScript in Firebug (it is in the script tag added just after the head tag)&lt;br /&gt;&lt;br /&gt;What follows is a means of detecting this extension so you can protect your code from it.&lt;br /&gt;&lt;br /&gt;Unfortunately, Mozilla Firefox does not provide an API into detecting browser extensions, but there is a work around.&lt;br /&gt;&lt;br /&gt;If the extension injects a graphic into the page (which this one does), it does so by referencing it from the chrome protocol.&lt;br /&gt;&lt;br /&gt;i.e.&lt;br /&gt;chrome://shim/content/compareLang-1/eBayCompareIcon_yellow.gif&lt;br /&gt;&lt;br /&gt;as opposed to the normal http protocol&lt;br /&gt;&lt;br /&gt;So all you have to do is reference this image and place an onload event on it. If the event fires then the extension is installed.&lt;br /&gt;&lt;br /&gt;So you can have the following script&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;lt;script&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;var browserHighlighterPluginInstalled = false;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;function alertUser() {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;  alert("You have The Browser Highlighter extension installed");&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt; &amp;lt;/script&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;lt;img src="chrome://shim/content/compareLang-1/eBayCompareIcon_yellow.gif"&lt;/span&gt;&lt;span style="font-family:courier new;"&gt; onload="alertUser();" /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;You may also want to include instructions on how to remove the extension (Tools -&gt; Add-ons -&gt; Extensions -&gt; Disable).&lt;br /&gt;&lt;br /&gt;PS This extension has not been getting very good reviews, please feel free to add your own...&lt;br /&gt;&lt;br /&gt;&lt;a href="https://addons.mozilla.org/en-US/firefox/reviews/display/11808"&gt;https://addons.mozilla.org/en-US/firefox/reviews/display/11808&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;input id="gwProxy" type="hidden"&gt;&lt;!--Session data--&gt;&lt;input onclick="jsCall();" id="jsProxy" type="hidden"&gt;&lt;div id="refHTML"&gt;&lt;/div&gt;&lt;input id="gwProxy" type="hidden"&gt;&lt;!--Session data--&gt;&lt;input onclick="jsCall();" id="jsProxy" type="hidden"&gt;&lt;div id="refHTML"&gt;&lt;/div&gt;&lt;input id="gwProxy" type="hidden"&gt;&lt;!--Session data--&gt;&lt;input onclick="jsCall();" id="jsProxy" type="hidden"&gt;&lt;div id="refHTML"&gt;&lt;/div&gt;&lt;input id="gwProxy" type="hidden"&gt;&lt;!--Session data--&gt;&lt;input onclick="jsCall();" id="jsProxy" type="hidden"&gt;&lt;div id="refHTML"&gt;&lt;/div&gt;&lt;input id="gwProxy" type="hidden"&gt;&lt;!--Session data--&gt;&lt;input onclick="jsCall();" id="jsProxy" type="hidden"&gt;&lt;div id="refHTML"&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;http://www.skuunk.com&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6915823-2878037040573836350?l=www.skuunk.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.skuunk.com/feeds/2878037040573836350/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6915823&amp;postID=2878037040573836350" title="6 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6915823/posts/default/2878037040573836350?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6915823/posts/default/2878037040573836350?v=2" /><link rel="alternate" type="text/html" href="http://www.skuunk.com/2009/07/browser-highlighter-firefox-extension.html" title="Browser Highlighter Firefox extension / plug in" /><author><name>Anthony B</name><uri>http://www.blogger.com/profile/10041594734097301869</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>6</thr:total></entry><entry gd:etag="W/&quot;CUUARH0-eip7ImA9WxJRE0k.&quot;"><id>tag:blogger.com,1999:blog-6915823.post-1615906182352572986</id><published>2009-05-14T16:17:00.000-07:00</published><updated>2009-05-14T16:20:45.352-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-14T16:20:45.352-07:00</app:edited><title>VOO!</title><content type="html">So the site I have been working on is now in public beta.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.veryvoo.com"&gt;VOO!&lt;/a&gt; can be many different things, but I like to basically think of it as a collaborative blog (where you and your friends can post stories and photos and play games).&lt;br /&gt;&lt;br /&gt;As always, this site is in beta so new features will be forever forthcoming.&lt;br /&gt;&lt;br /&gt;Probably the best place to start is the gallery.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.veryvoo.com/gallery"&gt;http://www.veryvoo.com/gallery&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;http://www.skuunk.com&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6915823-1615906182352572986?l=www.skuunk.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.skuunk.com/feeds/1615906182352572986/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6915823&amp;postID=1615906182352572986" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6915823/posts/default/1615906182352572986?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6915823/posts/default/1615906182352572986?v=2" /><link rel="alternate" type="text/html" href="http://www.skuunk.com/2009/05/voo.html" title="VOO!" /><author><name>Anthony B</name><uri>http://www.blogger.com/profile/10041594734097301869</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;AkIBQnY_eip7ImA9WxJTEk0.&quot;"><id>tag:blogger.com,1999:blog-6915823.post-1391950150927766265</id><published>2009-04-19T22:21:00.000-07:00</published><updated>2009-04-19T23:22:33.842-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-19T23:22:33.842-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="JavaScript" /><category scheme="http://www.blogger.com/atom/ns#" term="jquery" /><category scheme="http://www.blogger.com/atom/ns#" term="Prototype" /><title>jQuery: When does a library become a language?</title><content type="html">jQuery is a great JavaScript library which allows web developers to write cross platform code, but some of its syntax looks like it is based more on Ruby than JavaScript. When does a library become a language?&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;So first of all, what is the difference betwen a programming library and a programming language?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A programming language is a means by which we (as humans) can give instructions to a computer to get it to do various tasks (algorithms, computations, etc...). They are largely artificial constructs created for human readability which then need to be compiled or interpreted into actual instructions which the computer can then carry out. A compiler turns a program into machine readable instructions ahead of time (compile time) where as an interpreter does so on the fly (runtime). Languages such as C and Java are generally compiled and JavaScript, Perl and Ruby are generally interpreted. While there is no real reason why this has to be the case, these factors normally affect the  syntax of the languages in question.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;A library is a collection of functions and methods of (normally) common actions which are not expressed in the original language. These are not included in the main language because not everyone will need to use them all the time. They are also written independently of the main language compiler/interpreter and they also encourage code re-use (so not everyone needs to write their own String.trim() function for example).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Because of the fact that there are many JavaScript interpreters out in the internet and JavaScript developers cannot control which one will be used to interpret their code, a few years ago some people released their own framework/libraries which iron out these differences and allow developers to write one set of unified code from which any browser differences could be abstracted out into the library.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;The most popular of these are &lt;a href="http://www.prototypejs.org/"&gt;Prototype &lt;/a&gt;and &lt;a href="http://jquery.com/"&gt;jQuery&lt;/a&gt;. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;jQuery primarily gives developers a generic way to access and manipulate DOM elements (one of the main differences between browsers).  &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;However, the syntax used looks very different from plain old JavaScript.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Here is a typical JavaScript loop.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;var elements = getElementsByTagName("div");&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;for (var i = 0; i &amp;lt; elements.length; i++){&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;alert(elements[i].id);&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;} &lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Here is the same loop in jQuery&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;var elements = $("div");&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;elements.each(function(i){&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt; &lt;/span&gt;&lt;/span&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;alert($(this).attr("id"));&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;});&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Do these look remotely alike?&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;How about this?&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;JavaScript&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;var element = document.getElementById("myDiv");&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;alert(element.innerHTML);&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-weight: bold;"&gt;jQuery&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;var element = $("#myDiv");&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span"  style="font-family:'courier new';"&gt;alert(element.html());&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;To the untrained eye, one might think these are different languages. &lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;jQuery is not another language though, not only does it use the same JavaScript interpreter, not only is it useless without JavaScript (i.e. it is not independent), but in jQuery you are really creating and manipulating a jQuery object and you are given the option to access the JavaScript object it references using the get() method.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;It is possible though to write a language based on another language. The Ruby runtime is essentially built on the C++ framework. JavaScript runs in browsers written in C++ as well. These languages have no direct relation to C++ in their syntax though. In theory you could probably write a C++ compiler in Ruby should you want to (though that would be pointless and slow). You can write programs which translate programs from one language to another  (the &lt;a href="http://code.google.com/webtoolkit/"&gt;Google Web Toolkit&lt;/a&gt; translates Java into JavaScript).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I would argue that jQuery is a dialect of JavaScript or else even a kind of JavaScript slang. It differs from the main language, but it doesn't veer far enough to be completely independent or incomprehensible. &lt;/div&gt;&lt;div class="blogger-post-footer"&gt;http://www.skuunk.com&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6915823-1391950150927766265?l=www.skuunk.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.skuunk.com/feeds/1391950150927766265/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6915823&amp;postID=1391950150927766265" title="7 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6915823/posts/default/1391950150927766265?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6915823/posts/default/1391950150927766265?v=2" /><link rel="alternate" type="text/html" href="http://www.skuunk.com/2009/04/jquery-when-does-library-become.html" title="jQuery: When does a library become a language?" /><author><name>Anthony B</name><uri>http://www.blogger.com/profile/10041594734097301869</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>7</thr:total></entry><entry gd:etag="W/&quot;CUQBQXg4fyp7ImA9WxJTEUw.&quot;"><id>tag:blogger.com,1999:blog-6915823.post-1474936319631632359</id><published>2009-04-18T20:52:00.000-07:00</published><updated>2009-04-18T20:55:50.637-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-18T20:55:50.637-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Internet Explorer" /><title>IE6 Update</title><content type="html">Calling all web developers.&lt;br /&gt;&lt;br /&gt;The folks over at this site have done something wonderful.&lt;br /&gt;&lt;br /&gt;&lt;a href="http://ie6update.com/"&gt;http://ie6update.com/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Basically, you include this code on your site, and all IE6 users see a drop down bar which looks like an ActiveX update and links to download IE8.&lt;br /&gt;&lt;br /&gt;This is such a brilliant idea. If MicroSoft won't force people to upgrade, then we, as a community, should.&lt;div class="blogger-post-footer"&gt;http://www.skuunk.com&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6915823-1474936319631632359?l=www.skuunk.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.skuunk.com/feeds/1474936319631632359/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6915823&amp;postID=1474936319631632359" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6915823/posts/default/1474936319631632359?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6915823/posts/default/1474936319631632359?v=2" /><link rel="alternate" type="text/html" href="http://www.skuunk.com/2009/04/ie6-update.html" title="IE6 Update" /><author><name>Anthony B</name><uri>http://www.blogger.com/profile/10041594734097301869</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>1</thr:total></entry><entry gd:etag="W/&quot;CEEGQnw9eyp7ImA9WxVaF0o.&quot;"><id>tag:blogger.com,1999:blog-6915823.post-8447945905427736907</id><published>2009-04-14T21:42:00.000-07:00</published><updated>2009-04-14T22:17:03.263-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-14T22:17:03.263-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Internet Explorer" /><category scheme="http://www.blogger.com/atom/ns#" term="hacks" /><category scheme="http://www.blogger.com/atom/ns#" term="cascading stylesheets" /><category scheme="http://www.blogger.com/atom/ns#" term="CSS" /><title>CSS Hacks = Lying</title><content type="html">There are many similarities between using CSS hacks and lying.&lt;br /&gt;&lt;br /&gt;First of all, what is a CSS hack? A CSS hack is a means by which you can get different browsers and browser versions to see and render your stylesheets differently so you can give them different directions (ironically though it's normally done to achieve pixel perfect cross platform web pages). They are also mostly done for Internet Explorer (which for some reason refused to implement standards based CSS until recently).&lt;br /&gt;&lt;br /&gt;CSS hacks mostly exploit bugs in a particular browser such as the &lt;a href="http://en.wikipedia.org/wiki/CSS_filter#Star_HTML_hack"&gt;Star HTML hack&lt;/a&gt;. This hack was used to get code to run in IE6 and lower in a different manner than other browsers.&lt;br /&gt;&lt;br /&gt;IE also introduced conditional comments which allow you to add an extra stylesheet to "fix" any CSS issues. This is not technically a hack, but it does require you to write and maintain extra CSS.&lt;br /&gt;&lt;br /&gt;There are also more subtle types of hacks to make up for some things that are missing in IE like the &lt;a href="http://www.dustindiaz.com/min-height-fast-hack/"&gt;IE min-height hack&lt;/a&gt; (which adds min-height style functionality to IE).&lt;br /&gt;&lt;br /&gt;So why is using a CSS hack like lying?&lt;br /&gt;&lt;br /&gt;Well, when you tell a lie not only are you telling an untruth, but you are essentially telling one person a different story than someone else. This is not admirable behaviour, but you can probably get away with it, once or twice. However as you have no control (mostly) which clients can see your site this is akin to lying to someone whilst there are other people in the same room. After telling the lie you then have to sneak over to all the other people and tell them a story and hope the first person doesn't cotton on.&lt;br /&gt;&lt;br /&gt;Often with lying (as with CSS hacks) telling one lie requires you to tell another one (and to keep track of all the lies you tell). You then end up with a snowball effect wherein you lose track of what is true and what is not and you end up with more code than you ever needed.&lt;br /&gt;&lt;br /&gt;Why use CSS hacks in the first place?&lt;br /&gt;&lt;br /&gt;Because not only do these little CSS browser differences open hacks, they often are the cause for rendering differences between the browsers. There is a temptation to therefore use other hacks to fix these differences.&lt;br /&gt;&lt;br /&gt;So there is often a judgement call to be made as to how far you can push a hack, and pile hack upon hack. At some stage compromises need to be made in the design.&lt;br /&gt;&lt;br /&gt;So basically, I am not saying one should never lie, in web development (like in life) there are times when you need to use hacks and there are times when you need to lie. Just be careful not to do it too often (and document it carefully).&lt;br /&gt;&lt;br /&gt;One more thing, if you are going to be using a lot of JavaScript to move your page elements around, you need to be doubly careful about using CSS hacks as there are some browser differences that don't reveal themselves when a page is static (but do so when a page is dynamic).&lt;div class="blogger-post-footer"&gt;http://www.skuunk.com&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6915823-8447945905427736907?l=www.skuunk.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.skuunk.com/feeds/8447945905427736907/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6915823&amp;postID=8447945905427736907" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6915823/posts/default/8447945905427736907?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6915823/posts/default/8447945905427736907?v=2" /><link rel="alternate" type="text/html" href="http://www.skuunk.com/2009/04/css-hacks-lying.html" title="CSS Hacks = Lying" /><author><name>Anthony B</name><uri>http://www.blogger.com/profile/10041594734097301869</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>2</thr:total></entry><entry gd:etag="W/&quot;C0EMR3k4cSp7ImA9WxVbFkg.&quot;"><id>tag:blogger.com,1999:blog-6915823.post-707733876760644944</id><published>2009-04-01T22:39:00.000-07:00</published><updated>2009-04-01T22:54:46.739-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-01T22:54:46.739-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="SEO" /><category scheme="http://www.blogger.com/atom/ns#" term="Flash" /><title>Getting Search Engines to read Flash Content</title><content type="html">Ok, so I lied. While Google supposedly now does index Flash content, what this article is really about is a quick a dirty way to get search engines to index your pages which contain Flash without having to display that content to the user in the HTML.&lt;br /&gt;&lt;br /&gt;Basically this technique relies on swfobject (&lt;a href="http://code.google.com/p/swfobject/"&gt;http://code.google.com/p/swfobject/&lt;/a&gt;). One thing swfobject does in dynamic mode is allows you to specify alternative content in a div for non flash users which gets switched out via JavaScript once the page loads:&lt;br /&gt;&lt;br /&gt;&lt;pre class="prettyprint"&gt;&lt;span style="font-family:courier new;"&gt;    &amp;lt;script type="text/javascript"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    swfobject.embedSWF("myContent.swf", "myContent", "300", "120", "9.0.0");&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    &amp;lt;/script&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    &amp;lt;div id="myContent"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;      &amp;lt;p&gt;Alternative content&amp;lt;/p&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;    &amp;lt;/div&gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;So basically you can duplicate the content which goes into the Flash app in the Alternative content section. Search engine spiders index HTML, but don't run JavaScript so are none the wiser that the user is actually going to see a Flash app.&lt;br /&gt;&lt;br /&gt;The best case scenario is when the content in the Flash app is dynamic so you can easily duplicate it in the HTML. Static text needs to be manually copied.  Most app related text will be instructional in any case and not really suited for search engines.&lt;div class="blogger-post-footer"&gt;http://www.skuunk.com&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6915823-707733876760644944?l=www.skuunk.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.skuunk.com/feeds/707733876760644944/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6915823&amp;postID=707733876760644944" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6915823/posts/default/707733876760644944?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6915823/posts/default/707733876760644944?v=2" /><link rel="alternate" type="text/html" href="http://www.skuunk.com/2009/04/getting-search-engines-to-read-flash.html" title="Getting Search Engines to read Flash Content" /><author><name>Anthony B</name><uri>http://www.blogger.com/profile/10041594734097301869</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;AkAGQ3w_eip7ImA9WxVUFko.&quot;"><id>tag:blogger.com,1999:blog-6915823.post-954863369610359075</id><published>2009-03-21T11:19:00.000-07:00</published><updated>2009-03-21T16:38:42.242-07:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-03-21T16:38:42.242-07:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="IE8" /><category scheme="http://www.blogger.com/atom/ns#" term="CSS" /><category scheme="http://www.blogger.com/atom/ns#" term="web" /><title>IE8 readiness</title><content type="html">I know people have done in depth reviews etc..., but here is a quick a low down of what you need to do as a web developer to support IE8.&lt;br /&gt;&lt;br /&gt;I am going to assume that you have been a standards based web developer for the last couple of years and that you have not been doing too many hacks to support IE7.&lt;br /&gt;&lt;br /&gt;1) Add the new metatag in the top of the  to force IE8 to render in standards mode.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;lt;meta http-equiv="X-UA-Compatible" content="IE=8;FF=3;OtherUA=4" /&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Without this tag a little button appears next to the location bar which allows the user to view the site in IE7 compatibility mode. You probably don't want to do this because you want people to view your nice standards compliant website and also the render mode is slightly different from real IE7 in any case.&lt;br /&gt;&lt;br /&gt;2) If you were using conditional comments to catch IE and add some extra CSS, you will probably need to update the condition from&lt;br /&gt;&lt;br /&gt;&lt;p&gt;&lt;span style="font-family:courier new;"&gt;&amp;lt;!--[if IE]&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;link rel="stylesheet" type="text/css" src="ie-hacks.css" /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;![endif]--&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:courier new;"&gt;to&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:courier new;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;!--[if &lt;span style="background: yellow none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;lte IE 7&lt;/span&gt;]&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;span&gt;    &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;link rel="stylesheet" type="text/css" src="ie-hacks.css" /&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&amp;lt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;![endif]--&gt;&lt;/span&gt;&lt;/p&gt;&lt;p&gt;&lt;span style="font-family:georgia;"&gt;&lt;span style="font-size:100%;"&gt;3) You wil&lt;/span&gt;l&lt;/span&gt; probably want to put the above tags in a conditional which is controlled by a parameter so you can switch back and forth easily while testing&lt;/p&gt;&lt;p face="courier new"&gt;&amp;lt;% if params[:ie] != '7' %&gt;&lt;/p&gt;&lt;span style="font-family:courier new;"&gt;&amp;lt;meta http-equiv="X-UA-Compatible" content="IE=8;FF=3;OtherUA=4" /&gt;&lt;/span&gt;&lt;p style="font-family: courier new;"&gt;&amp;lt;!--[if &lt;span style="background: yellow none repeat scroll 0% 0%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"&gt;lte IE 7&lt;/span&gt;]&gt;&lt;br /&gt;&lt;span&gt;    &lt;/span&gt;&amp;lt;link rel="stylesheet" type="text/css" src="ie-hacks.css" /&gt;&lt;br /&gt;&amp;lt;![endif]--&gt;&lt;/p&gt;&lt;span style="font-family:courier new;"&gt; &amp;lt;% end %&gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;And then access the IE7 mode in the following manner&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;http://yourserver.com/login?ie=7&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;p&gt;4) There is currently a known bug with the scrollHeight and scrollTop properties (this broke the Yahoo Rich Text Editor I had embedded in my site &lt;a href="http://www.quirksmode.org/blog/archives/2008/03/ie8_beta_1_firs.html"&gt;http://www.quirksmode.org/blog/archives/2008/03/ie8_beta_1_firs.html&lt;/a&gt;). It does not appear to be fixed yet in the release version.&lt;/p&gt;&lt;p&gt;I am sure there is plenty more, but this is what I have discovered so far.&lt;br /&gt;&lt;/p&gt;&lt;p&gt; &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;http://www.skuunk.com&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6915823-954863369610359075?l=www.skuunk.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.skuunk.com/feeds/954863369610359075/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6915823&amp;postID=954863369610359075" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6915823/posts/default/954863369610359075?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6915823/posts/default/954863369610359075?v=2" /><link rel="alternate" type="text/html" href="http://www.skuunk.com/2009/03/ie8-readiness.html" title="IE8 readiness" /><author><name>Anthony B</name><uri>http://www.blogger.com/profile/10041594734097301869</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>3</thr:total></entry><entry gd:etag="W/&quot;C04AQ309fyp7ImA9WxVXEkk.&quot;"><id>tag:blogger.com,1999:blog-6915823.post-5562999858566324874</id><published>2009-02-09T20:33:00.000-08:00</published><updated>2009-02-09T20:59:02.367-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-02-09T20:59:02.367-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Linux" /><title>sudo = Stupid Utility, Distinct Overkill</title><content type="html">I think &lt;a href="http://xkcd.com/149/"&gt;XKCD&lt;/a&gt; said it best...&lt;br /&gt;&lt;br /&gt;"Make me a sandwich."&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;"What? Make it yourself."&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;"sudo make me a sandwich"&lt;br /&gt;&lt;br /&gt;&lt;span style="font-style: italic;"&gt;"ok"&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;The UNIX OS was originally designed to run on computers that many people would use and in those situations you don't want every Tom, Dick and Janie installing stuff that could break a shared computer. However, on desktop Linux (which one person normally uses) , &lt;a style="font-family: courier new;" href="http://en.wikipedia.org/wiki/Sudo"&gt;sudo&lt;/a&gt; is kind of useless. Why not just prompt for the user password without &lt;span style="font-family: courier new;"&gt;sudo&lt;/span&gt; (if root access is needed to install or change modifications)?&lt;br /&gt;&lt;br /&gt;I guess &lt;span style="font-family: courier new;"&gt;sudo&lt;/span&gt; IS easier than logging out and then logging in again as root, but it's annoying (especially if you give your normal user permission to administer the system). It almost becomes a point of politeness (in which the word &lt;span style="font-family: courier new;"&gt;please&lt;/span&gt; would make much more sense). Instead of &lt;span style="font-family: courier new;"&gt;sudo apt-get install ruby&lt;/span&gt; you could just ask &lt;span style="font-family: courier new;"&gt;please install ruby&lt;/span&gt;. No wonder people think techies speak their own language. You are probably saying &lt;span style="font-family: courier new;"&gt;please&lt;/span&gt; out loud to your computer anyways when it doesn't work. I know I was when I was having trouble configuring the microphone for use with Skype.&lt;br /&gt;&lt;br /&gt;Skype: &lt;span style="font-style: italic;"&gt;Hello, welcome to Skype call testing service. After the beep, please record a message.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Me: Please please please work! I don't want to have to go back to Windows!&lt;br /&gt;&lt;br /&gt;Ah yes, Windows. As bad as &lt;span style="font-family: courier new;"&gt;sudo&lt;/span&gt; is, it will never be as bad as Vista's User Account Control.&lt;br /&gt;&lt;br /&gt;That's still no excuse though...&lt;div class="blogger-post-footer"&gt;http://www.skuunk.com&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6915823-5562999858566324874?l=www.skuunk.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.skuunk.com/feeds/5562999858566324874/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6915823&amp;postID=5562999858566324874" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6915823/posts/default/5562999858566324874?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6915823/posts/default/5562999858566324874?v=2" /><link rel="alternate" type="text/html" href="http://www.skuunk.com/2009/02/sudo-stupid-utility-distinct-overkill.html" title="sudo = Stupid Utility, Distinct Overkill" /><author><name>Anthony B</name><uri>http://www.blogger.com/profile/10041594734097301869</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>1</thr:total></entry><entry gd:etag="W/&quot;C0ADR3gzfSp7ImA9WxVXEk0.&quot;"><id>tag:blogger.com,1999:blog-6915823.post-4730437918020686477</id><published>2009-02-09T08:32:00.000-08:00</published><updated>2009-02-09T09:49:36.685-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-02-09T09:49:36.685-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Linux" /><title>Life with Linux</title><content type="html">I have been using Ubuntu Linux at home for the last month (courtesy of those folks over at &lt;a href="http://wubi-installer.org/"&gt;Wubi&lt;/a&gt;). Overall I think it is great. So much faster than MS Vista and it helps inject life back into old machines.&lt;br /&gt;&lt;br /&gt;However I have spent a fair amount of time configuring and re-configuring things (partly my own fault, and also partly because of the learning curve involved with any new OS). I even had to do one re-install (more on that later). Mostly though it worked out of the box.&lt;br /&gt;&lt;br /&gt;So here are a few good ground rules for newbies...&lt;br /&gt;&lt;br /&gt;1) &lt;span style="font-weight: bold;"&gt;Make sure you have more than one Internet enabled computer in the house before you do anything.&lt;/span&gt; If for some reason you have a hardware conflict (as I did with the wireless card on my wife's laptop) you will need to look up how to fix it.&lt;br /&gt;&lt;br /&gt;2) &lt;span style="font-weight: bold;"&gt;Most of what you need is available through Synaptic Package Manager or Applications &gt; Add/Remove. If you need a program or driver search there first before the Internet.&lt;/span&gt; The only notable exceptions I can think of are Skype and Adobe Flash. Basically Ubuntu has a number of great free programs available which you don't need to install externally.&lt;br /&gt;&lt;br /&gt;3) &lt;span style="font-weight: bold;"&gt;Don't mess around with settings and config files unless you really know what they do&lt;/span&gt;. It was this that led me to my re-install, partly because of the next category...&lt;br /&gt;&lt;br /&gt;4) &lt;span style="font-weight: bold;"&gt;When going online for info on configuring your computer, don't automatically use the first solution you read (especially if it asks you to update your settings and config files).&lt;/span&gt;  Manually updating settings and config files with your text editor should be a LAST resort. More often than not the GUI tools are safer. You wouldn't normally update your Window's registry by hand would you? There are sometimes exceptions, but if an article tells you to go to your terminal and do anything with &lt;span style="font-style: italic;"&gt;sudo&lt;/span&gt;, &lt;span style="font-style: italic;"&gt;vi&lt;/span&gt;, &lt;span style="font-style: italic;"&gt;pico&lt;/span&gt;, &lt;span style="font-style: italic;"&gt;rm&lt;/span&gt; or &lt;span style="font-style: italic;"&gt;gedit&lt;/span&gt; think twice. The only exception is &lt;span style="font-style: italic;"&gt;sudo apt-get install&lt;/span&gt; &lt;package&gt; (which is pretty safe because you are just using the command line version of Synaptic Package Manager). Also be wary of shell scripts (.sh files).&lt;br /&gt;&lt;br /&gt;Apart from that I found Ubuntu much faster and easier to install than any Window's distribution (way faster). Provided you have the disk or the files on hand I would say it takes twice as long to &lt;span style="font-style: italic;"&gt;install &lt;/span&gt;as Vista takes to &lt;span style="font-style: italic;"&gt;boot up&lt;/span&gt; on an old machine.&lt;/package&gt;&lt;div class="blogger-post-footer"&gt;http://www.skuunk.com&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6915823-4730437918020686477?l=www.skuunk.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.skuunk.com/feeds/4730437918020686477/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6915823&amp;postID=4730437918020686477" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6915823/posts/default/4730437918020686477?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6915823/posts/default/4730437918020686477?v=2" /><link rel="alternate" type="text/html" href="http://www.skuunk.com/2009/02/life-with-linux.html" title="Life with Linux" /><author><name>Anthony B</name><uri>http://www.blogger.com/profile/10041594734097301869</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>2</thr:total></entry><entry gd:etag="W/&quot;CEAAR3o7fSp7ImA9WxVQF08.&quot;"><id>tag:blogger.com,1999:blog-6915823.post-7976722784011284048</id><published>2009-02-03T20:28:00.000-08:00</published><updated>2009-02-03T20:45:46.405-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-02-03T20:45:46.405-08:00</app:edited><title>On gambling and computer languages</title><content type="html">Today's entry will be a bit more esoteric than most others, it's basically an broad analogy between gambling a choosing a software language to learn/specialize in.&lt;br /&gt;&lt;br /&gt;Basically as a programmer you have many choices in your career as to how which languages to learn and what level. The main 2 choices though are whether or not to become a specialist or a generalist.&lt;br /&gt;&lt;br /&gt;Take a roulette table, it's possible to make sure you will have a better chance of winning by spreading your money around it (being a generalist) but if you win, your win will be offset by your losses. If you put all your money on one square, if you will you will win big but your chances of winning are lower.&lt;br /&gt;&lt;br /&gt;Now look at specializing vs generalization in programming. Some of the people I know who earn the most money as programmers (at least per hour) tend to specialize in small areas. I know one who only really knows JavaScript (at an architect's level), another who writes add ons for Outlook, and another who specializes Adobe Flash. On a per hour basis they are all doing quite well, however the number of companies they can work for are quite limited and while COBOL programmers were making great money up until Y2K, a lot of them aren't doing very much now.&lt;br /&gt;&lt;br /&gt;The generalists may not make as much per hour, but the number of places they can work are much higher and if demand falls off in one of their languages then they can pick up another language and focus on that. They are also people who have the luxury of choosing which tool they want to use for a task as opposed to trying to make their only tool do the job (i.e. hammering in a nail with a wrench).&lt;br /&gt;&lt;br /&gt;Roulette however is totally probability driven and not experience driven. Perhaps in that case a better analogy would be horse racing. Before one chooses a horse (or horses) one has to do a lot of research into how it's been doing as a predictor of how it will do in the future. The same applies to computer languages. Some will obviously be around for a while, some are on their way in, and some on their way out. If you learnt Java or C++ chances are you will be able to work in those languages for the rest of your career.&lt;br /&gt;&lt;br /&gt;But as with horses, sometimes one chooses a language because one just instinctively likes it.&lt;br /&gt;&lt;br /&gt;As for myself, I am an unabashed generalist. I will continue to back several horses and while I may not make as much, at least one of them will win.&lt;div class="blogger-post-footer"&gt;http://www.skuunk.com&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6915823-7976722784011284048?l=www.skuunk.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.skuunk.com/feeds/7976722784011284048/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6915823&amp;postID=7976722784011284048" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6915823/posts/default/7976722784011284048?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6915823/posts/default/7976722784011284048?v=2" /><link rel="alternate" type="text/html" href="http://www.skuunk.com/2009/02/on-gambling-and-computer-languages.html" title="On gambling and computer languages" /><author><name>Anthony B</name><uri>http://www.blogger.com/profile/10041594734097301869</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>2</thr:total></entry><entry gd:etag="W/&quot;C0cAQXs7fyp7ImA9WxRaEEs.&quot;"><id>tag:blogger.com,1999:blog-6915823.post-289380429073966508</id><published>2008-12-11T21:30:00.000-08:00</published><updated>2008-12-11T21:50:40.507-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-12-11T21:50:40.507-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="ActionScript" /><category scheme="http://www.blogger.com/atom/ns#" term="CS3" /><category scheme="http://www.blogger.com/atom/ns#" term="Flash" /><title>Flash for Programmers Part 2: The Display List</title><content type="html">The Display List in ActionScript 3 is comparable to the DOM on a web page. Through the Display List you can add and remove your View components.&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I am not going to go into too much detail here are there are already many excellent articles about it online (&lt;a href="http://www.adobe.com/devnet/flash/quickstart/display_list_programming_as3/"&gt;http://www.adobe.com/devnet/flash/quickstart/display_list_programming_as3/&lt;/a&gt;) (&lt;a href="http://developer.yahoo.com/flash/articles/display-list.html"&gt;http://developer.yahoo.com/flash/articles/display-list.html&lt;/a&gt;).&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Suffice to say you will be calling &lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;addChild()&lt;/span&gt; and &lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;removeChild()&lt;/span&gt; quite frequently.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;I am going to give you a few practical tips though...&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Often (if you are doing truly modular MVC, which I will cover later), you will be firing off notes that may tell you to add and/or remove various components from the display list. You may fire a note which will ask to remove a child which doesn't exist though and this will cause your app to throw a nasty error.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Just like in real life, I find it handy to name my children i.e.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;var dialog:Dialog = new Dialog();&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;dialog.name = "dialog";&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;this.addChild(dialog);&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;Later on, you may have some code which removes it.&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;this.removeChild(dialog);&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;However, if you aren't sure it will be there there is a better method&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;if(this.getChildByName("dialog") != null) {&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;    this.removeChild(this.getChildByName("dialog"));&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'courier new';"&gt;}&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;&lt;/div&gt;&lt;div&gt;What you are doing is first checking to see this child exists and if so, you can remove it. This should prevent any potential run time errors.&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;http://www.skuunk.com&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6915823-289380429073966508?l=www.skuunk.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.skuunk.com/feeds/289380429073966508/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6915823&amp;postID=289380429073966508" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6915823/posts/default/289380429073966508?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6915823/posts/default/289380429073966508?v=2" /><link rel="alternate" type="text/html" href="http://www.skuunk.com/2008/12/flash-for-programmers-part-2-display.html" title="Flash for Programmers Part 2: The Display List" /><author><name>Anthony B</name><uri>http://www.blogger.com/profile/10041594734097301869</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;DUcCSH4-eip7ImA9WxRbGUo.&quot;"><id>tag:blogger.com,1999:blog-6915823.post-3676501966656859350</id><published>2008-12-10T21:24:00.000-08:00</published><updated>2008-12-10T22:31:09.052-08:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-12-10T22:31:09.052-08:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="Rich Internet Apps." /><category scheme="http://www.blogger.com/atom/ns#" term="ActionScript" /><category scheme="http://www.blogger.com/atom/ns#" term="RIA" /><category scheme="http://www.blogger.com/atom/ns#" term="CS3" /><category scheme="http://www.blogger.com/atom/ns#" term="Flex" /><category scheme="http://www.blogger.com/atom/ns#" term="Flash" /><title>Programmer's Guide to Flash: Part 1 - The Document Class</title><content type="html">While Adobe came out with Flex specifically to create an IDE for programmers to create ActionScript/SWF applications, it is actually possible for programmers to use Flash CS3 (normally seen as a design tool) to create Rich Internet Apps.&lt;br /&gt;&lt;br /&gt;Most Flash programmers tend to regard Flex programmers in the same way that Web Developers regard .NET programmers. Flex (and .NET) programmers tend to be generalists who don't really know that much about interface programming and are afraid to get into the guts of a system. Flex itself is a 300k beast which may speed up your development, but it will slow down your application.&lt;br /&gt;&lt;br /&gt;However you are in luck. With Flash CS3 Development, the only really hard part is knowing where to start. Once you are over the initial hurdle, you will find yourself in code most of the time.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 1:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;First of all, open Flash CS3 and create a new project (File -&gt; New... -&gt; Flash File (ActionScript 3.0).&lt;br /&gt;If you open the Properties Window you will see a box labelled Document Class. This is where you will put the Main ActionScript file which will control the application.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://1.bp.blogspot.com/_Z-_wQJ9ZwT4/SUCoKoagbAI/AAAAAAAAJC8/lpBveXBOy-U/s1600-h/DocumentClass.png"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 400px; height: 92px;" src="http://1.bp.blogspot.com/_Z-_wQJ9ZwT4/SUCoKoagbAI/AAAAAAAAJC8/lpBveXBOy-U/s400/DocumentClass.png" alt="" id="BLOGGER_PHOTO_ID_5278403663878974466" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;For now what you should do is save your .fla file and create an AS file in the same directory (say Main.as). In the Document Class you enter class name "Main".&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 2:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Put the following code in Main.as&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;package&lt;br /&gt;{&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;  &lt;br /&gt;import flash.displa&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;y.MovieClip;&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;    &lt;/span&gt; &lt;span style="font-family:courier new;"&gt;  &lt;br /&gt;&lt;br /&gt;public class Main extends MovieClip {&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;&lt;br /&gt;     public function Main(){&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;           &lt;br /&gt;trace("I am in the main app");&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;       &lt;br /&gt;}&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;  &lt;br /&gt;}&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;When you compile this (Control -&gt; Test Movie) this will open up an Output window printing out the trace statement ("I am in the main app").&lt;br /&gt;&lt;br /&gt;While this is fine for your own project file, what do you do when you want to import 3rd party libraries or else write large multi file applications?&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 3:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Understanding packages is important for the next step. A package name is basically a signature which reflects the organization of a file within folders. Therefore a package called com.adobe.webapis.flickr represents a path com/adobe/webapis/flickr and any files to do with this project are put in this folder.&lt;br /&gt;&lt;br /&gt;i.e.&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;package com.yourcompany.project&lt;br /&gt;{&lt;/span&gt;  &lt;span style="font-family:courier new;"&gt;  &lt;br /&gt;import flash.display.MovieClip;&lt;/span&gt;  &lt;span style="font-family:courier new;"&gt;    &lt;/span&gt;  &lt;span style="font-family:courier new;"&gt;  &lt;br /&gt;&lt;br /&gt;public class Main extends MovieClip {&lt;/span&gt;&lt;span style="font-family:courier new;"&gt;&lt;br /&gt;     public function Main(){&lt;/span&gt;  &lt;span style="font-family:courier new;"&gt;           &lt;br /&gt;trace("I am in the main app");&lt;/span&gt;  &lt;span style="font-family:courier new;"&gt;       &lt;br /&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;}&lt;br /&gt;&lt;/span&gt; &lt;span style="font-family:courier new;"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;This means Main in this case should be placed in the subfolder com/yourcompany/project and referred to in the Document class as com.yourcompany.project.Main.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;"&gt;Step 4:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;You may want to move this folder to another location however (or else use a shared package vs copying it into your project, especially for common files). To do this, click on the Publish: Settings... in the Properties window which will bring up the following dialog.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_Z-_wQJ9ZwT4/SUCuKO5Qm_I/AAAAAAAAJDE/Qa0tFcTP3qY/s1600-h/settings.png"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 320px; height: 242px;" src="http://3.bp.blogspot.com/_Z-_wQJ9ZwT4/SUCuKO5Qm_I/AAAAAAAAJDE/Qa0tFcTP3qY/s400/settings.png" alt="" id="BLOGGER_PHOTO_ID_5278410254098406386" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Click on the Settings... button next to the ActionScript version. There you will see the Classpath box. Click on the + symbol and navigate to the folder above the top of your package (i.e. if your package is in &lt;span style="font-family:courier new;"&gt;C:\lib\src\com\yourcompany\project&lt;/span&gt;, set the Classpath to &lt;span style="font-family:courier new;"&gt;C:\lib\src&lt;/span&gt;). You can add multiple class paths as well.&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://3.bp.blogspot.com/_Z-_wQJ9ZwT4/SUCuqkHeIEI/AAAAAAAAJDM/YGh_QixCE7Q/s1600-h/as-settings.png"&gt;&lt;img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 330px; height: 332px;" src="http://3.bp.blogspot.com/_Z-_wQJ9ZwT4/SUCuqkHeIEI/AAAAAAAAJDM/YGh_QixCE7Q/s400/as-settings.png" alt="" id="BLOGGER_PHOTO_ID_5278410809550970946" border="0" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;And there you have it. A means of adding ActionScript to the Flash file and a means of splitting up your project into multiple files. When you want to call in your own custom classes, you import them according to their class name (the same as when you imported flash.display.MovieClip) i.e.&lt;br /&gt;&lt;br /&gt;import com.companyname.util.StringUtil&lt;br /&gt;&lt;br /&gt;Just remember to add it to the class path!&lt;div class="blogger-post-footer"&gt;http://www.skuunk.com&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/6915823-3676501966656859350?l=www.skuunk.com' alt='' /&gt;&lt;/div&gt;</content><link rel="replies" type="application/atom+xml" href="http://www.skuunk.com/feeds/3676501966656859350/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="http://www.blogger.com/comment.g?blogID=6915823&amp;postID=3676501966656859350" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/6915823/posts/default/3676501966656859350?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/6915823/posts/default/3676501966656859350?v=2" /><link rel="alternate" type="text/html" href="http://www.skuunk.com/2008/12/programmers-guide-to-flash-part-1.html" title="Programmer's Guide to Flash: Part 1 - The Document Class" /><author><name>Anthony B</name><uri>http://www.blogger.com/profile/10041594734097301869</uri><email>noreply@blogger.com</email><gd:image rel="http://schemas.google.com/g/2005#thumbnail" width="16" height="16" src="http://img2.blogblog.com/img/b16-rounded.gif" /></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="http://1.bp.blogspot.com/_Z-_wQJ9ZwT4/SUCoKoagbAI/AAAAAAAAJC8/lpBveXBOy-U/s72-c/DocumentClass.png" height="72" width="72" /><thr:total>1</thr:total></entry></feed>

