<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Carsonified &#187; Dev</title>
	<atom:link href="http://carsonified.com/blog/category/dev/feed/" rel="self" type="application/rss+xml" />
	<link>http://carsonified.com</link>
	<description></description>
	<lastBuildDate>Wed, 17 Mar 2010 10:17:01 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Getting Started with Yahoo! GeoPlanet Explorer</title>
		<link>http://carsonified.com/blog/dev/getting-started-with-yahoo-geoplanet-explorer/</link>
		<comments>http://carsonified.com/blog/dev/getting-started-with-yahoo-geoplanet-explorer/#comments</comments>
		<pubDate>Mon, 08 Mar 2010 14:00:04 +0000</pubDate>
		<dc:creator>Christian Heilmann</dc:creator>
				<category><![CDATA[Dev]]></category>

		<guid isPermaLink="false">http://carsonified.com/?p=4883</guid>
		<description><![CDATA[By <strong>Christian Heilmann</strong><br />
Where are you and what is around you?
Geolocation is a hot topic. Google just got the patent on geolocated advertising, mobile phones allow us to pinpoint ourselves on the planet and find things nearby and with augmented reality applications we can even find our way by filming our surrounding and finding hidden treasures by moving [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style=""><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fcarsonified.com%2Fblog%2Fdev%2Fgetting-started-with-yahoo-geoplanet-explorer%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcarsonified.com%2Fblog%2Fdev%2Fgetting-started-with-yahoo-geoplanet-explorer%2F" height="61" width="51" /></a></div><p><a href="http://carsonified.com/?administer_redirect_7=http://futureofwebapps.com/?utm_source=thinkvitamin&amp;utm_medium=banner&amp;utm_campaign=geoplanet"><img class=" alignnone" title="Future of Web Apps Dublin 2010" src="http://carsonified.com/wp-content/themes/carsonified/img/adverts/fowa_dublin_2010_side.jpg" alt="Future of Web Apps Dublin 2010" width="470" height="60" /></a></p>
<h3>Where are you and what is around you?</h3>
<p>Geolocation is a hot topic. Google just got the patent on geolocated advertising, mobile phones allow us to pinpoint ourselves on the planet and find things nearby and with augmented reality applications we can even find our way by filming our surrounding and finding hidden treasures by moving our mobile around. Using geolocation as a developer is quite easy, you can do a few things:</p>
<ul>
<li>If you are building something in a social network, you can get the geographical location from the user&#8217;s profile.</li>
<li>If you work on a certain mobile platform (Android, WebOS, iPhone) you get APIs to detect the current location.</li>
<li>If that is not an option you can use the W3C geo location API in browsers that support it.</li>
<li>If everything else fails you can guess the visitor&#8217;s location from their IP number.</li>
</ul>
<h3>That is the where, but how to know what is around me?</h3>
<p>Knowing the location is one thing, but what if you want to know more about the area? What about the geographical hierarchy? What part of the city/country are you in and which other geographical and administrative areas are nearby?</p>
<p>All of this has been available for you for quite a while. The <a href="http://developer.yahoo.com/geo/geoplanet/">GeoPlanet API</a> and <a href="http://developer.yahoo.com/geo/geoplanet/data/">dataset</a> released by Yahoo! has been out for a while but did not quite get the love from the mainstream developer crowd it deserves. The geo hackers, on the other hand already love it to bits and helped make it more accurate by providing feedback.</p>
<p>To make it a bit easier for you to understand what the GeoPlanet API allows you to do, I&#8217;ve put together the <a href="http://isithackday.com/geoplanet-explorer/">GeoPlanet Explorer</a> &#8211; a tool that lets you explore all the GeoPlanet data in an interactive way:</p>
<p><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="470" height="375" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/mL3oei5UhgM&amp;hl=en_US&amp;fs=1&amp;rel=0&amp;color1=0x234900&amp;color2=0x4e9e00" /><param name="allowfullscreen" value="true" /><embed type="application/x-shockwave-flash" width="470" height="375" src="http://www.youtube.com/v/mL3oei5UhgM&amp;hl=en_US&amp;fs=1&amp;rel=0&amp;color1=0x234900&amp;color2=0x4e9e00" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<p>The Geoplanet Explorer uses three tools: <a href="http://developer.yahoo.com/yql/">YQL</a> for accessing and filtering data, <a href="http://yuilibrary.com/projects/yui3/">YUI3</a> for the rich interaction and <a href="http://developer.yahoo.com/yui/grids/">CSS layout</a>, <a href="http://developer.yahoo.com/maps/ajax/">Yahoo Maps</a> for display and PHP to glue all of that together. You can get the <a href="http://github.com/codepo8/geoplanet-explorer">full source code on GitHub</a>.<span id="more-4883"></span></p>
<h3>Simplifying matters using woeid</h3>
<p>One big problem of geo location is ambiguity. If you have a location with latitude and longitude you can pinpoint it on the globe. You don&#8217;t know what it is though. The centre of a certain county, city and a point of interest could share the same latitude and longitude, but they are actually totally different things.</p>
<p>To fix this problem, Yahoo! a long time ago introduced the <a href="http://developer.yahoo.com/geo/geoplanet/guide/concepts.html">Where on Earth ID</a> (or short <tt>woeid</tt>) which is a number that defines a place with its geographical location and describes what it is. For example my neighbourhood in London has the <tt>woeid</tt> of <tt>36239</tt> and that means I can get the following information from it when querying the GeoPlanet API:</p>
<ul>
<li>Stoke Newington (Suburb):
<ul>
<li>Country: United Kingdom</li>
<li>WOEID: 36239</li>
<li>Administrative:
<ul>
<li>England (Country)</li>
<li>Greater London (County)</li>
</ul>
</li>
<li>Localities:
<ul>
<li>London (Town)</li>
<li>Stoke Newington (Suburb)</li>
</ul>
</li>
<li>Postal N16 (Postal Code)</li>
<li>Location (lat/lon): 51.561199, -0.082980</li>
<li>Bounding Box: NE 51.577190, -0.058070 SW 51.546692, -0.092380</li>
</ul>
</li>
</ul>
<p>The bounding box information is very useful for displaying this information on a map as it shows you which points need to be visible in order to see the whole place.</p>
<p>There is just something pretty about having a number instead of a lat/lon pair which is why <tt>woeid</tt> is rapidly becoming a standard. Flickr supported it for quite a while, Dopplr uses it under the hood, the Yahoo! Weather API understands it and soon Twitter will also use it for geolocating content in an unambiguous way (right now there is only support in the <a href="http://engineering.twitter.com/2010/02/woeids-in-twitters-trends.html">Twitter Trends API</a>).</p>
<h3>So how could you use this for your own products?</h3>
<p>There are a lot of ways you can use the geo tools by Yahoo! in your own solutions &#8211; by far the easiest is using YQL to access the data. This, for example allowed me to write the <a href="http://isithackday.com/hacks/geo/addmap.html">addmap.js</a> solution:</p>
<p><a href="http://isithackday.com/hacks/geo/addmap.html"><img src="http://farm5.static.flickr.com/4058/4408673432_e4f2cb178a.jpg" alt="Analyse text and add a map with its locations in pure JavaScript by  you." width="470" /></a></p>
<p>Using this you can can easily take the content of a page element with a certain ID and add a map of the locations it &#8220;talks about&#8221; to the document:</p>
<pre><code>&lt;script src="http://github.com/codepo8/geotoys/raw/master/addmap.js"&gt;&lt;/script&gt;
&lt;script&gt;
addmap.config.mapkey = 'YOUR_API_KEY';
addmap.analyse('content');
&lt;/script&gt;</code></pre>
<p>The API key is needed for the Google maps, not for YQL. YQL in this case under the hood uses <a href="http://developer.yahoo.com/geo/placemaker/">Placemaker</a> which is an API that finds geographical content in URLs or texts.</p>
<p>YQL and the geo tools offer you some other interesting options:</p>
<h3>Geographical locations in texts/urls/RSS feeds</h3>
<p>By using the Placemaker table in YQL you can extract geographical locations from a texts or a source on the web:</p>
<pre><code>select * from geo.placemaker where documentContent =
"Hi, I am Chris, I live in London but actually I am from Germany"
and documentType="text/plain" and appid=""</code></pre>
<p>This finds both &#8220;London&#8221; and &#8220;Germany&#8221; as geographical locations. You can see the result of this <a href="http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20geo.placemaker%20where%20documentContent%20%3D%20%0A%22Hi%2C%20I%20am%20Chris%2C%20I%20live%20in%20London%20but%20actually%20I%20am%20from%20Germany%22%20%0Aand%20documentType%3D%22text%2Fplain%22%20and%20appid%3D%22%22&amp;format=xml&amp;env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys">here as an XML file</a>. You will find places and references. Places are what has been found and references where it was found. The <tt>start</tt> and <tt>end</tt> elements describe the character location in the whole string.</p>
<p>Placemaker also takes feed and web site URIs and finds the locations in them for you. For example to see the locations mentioned in my portfolio page you can do the following:</p>
<pre><code>select * from geo.placemaker where documentURL =
"http://icant.co.uk" and documentType="text/html" and appid=""</code></pre>
<p>Again, you can check the <a href="http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20geo.placemaker%20where%20documentURL%20%3D%20%0A%22http%3A%2F%2Ficant.co.uk%22%20and%20documentType%3D%22text%2Fhtml%22%20and%20appid%3D%22%22&amp;format=xml&amp;env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys">result as an XML</a> file. As this is an HTML document there is no start and end but the references are reported as XPATHs.</p>
<p>Feeds are also supported, so if you want to get the locations in the BBC News feed you can use the following:</p>
<pre><code>select * from geo.placemaker where documentURL =
"http://newsrss.bbc.co.uk/rss/newsonline_uk_edition/front_page/rss.xml"
and documentType="text/rss" and appid=""</code></pre>
<p>Verify the <a href="http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20geo.placemaker%20where%20documentURL%20%3D%20%0A%22http%3A%2F%2Fnewsrss.bbc.co.uk%2Frss%2Fnewsonline_uk_edition%2Ffront_page%2Frss.xml%22%20%0Aand%20documentType%3D%22text%2Frss%22%20and%20appid%3D%22%22&amp;format=xml&amp;env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys">result as an XML</a> at your leisure &#8211; this time the XPATHs point to the RSS items.</p>
<p>The easiest way to see the power of Placemaker is using <a href="http://icant.co.uk/geomaker">GeoMaker</a> which gives you a simple interface to do turn a text or URL into a map or microformats to embed into your documents:</p>
<p><a href="http://icant.co.uk/geomaker"><img src="http://farm3.static.flickr.com/2559/3751595472_199877c7b2.jpg" alt="GeoMaker screenshot" width="470" /></a></p>
<h3>Location by IP</h3>
<p>Getting the geographical location of an IP is possible with the following YQL statement:</p>
<pre><code>select * from geo.places where woeid in (
  select place.woeid from flickr.places where (lat,lon) in (
    select Latitude,Longitude from ip.location where ip = "123.23.23.33"
  )
)</code></pre>
<p>You can <a href="http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20geo.places%20where%20woeid%20in%20(%0A%20%20select%20place.woeid%20from%20flickr.places%20where%20(lat%2Clon)%20in%20(%0A%20%20%20%20select%20Latitude%2CLongitude%20from%20ip.location%20where%20ip%20%3D%20%22123.23.23.33%22%0A%20%20)%0A)&amp;format=xml&amp;env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys">see this as an XML file here</a>.</p>
<p>What we&#8217;re doing here is using the <a href="http://www.ip2location.com/">IP2location API </a>,get the woeid from the latitude and longitude using the <a href="http://www.flickr.com/services/api/flickr.places.findByLatLon.html">Flickr <tt>findByLatLon</tt> method</a> and run the result through the <a href="http://developer.yahoo.com/geo/geoplanet/guide/api_docs.html">geo API</a> to get all the information &#8211; quite some work off your hands, isn&#8217;t it? Without YQL you&#8217;d have to sign up for all these APIs and understand their inner workings to get the same information.</p>
<p>Getting location by IP is an old trick in the book of advertisers &#8211; you probably will have encountered ads like &#8220;meet singles in <em>your city</em> now&#8221; and see them changing when you went to another place &#8211; this is what they use to get this information. The accuracy of IP location is not very high though. It also can feel a bit creepy.</p>
<h3>Location by Latitude and Longitude</h3>
<p>Therefore it is much better to use a system that allows people to opt-in to tell their geographical location. There are services for that but we also have a <a href="http://dev.w3.org/geo/api/spec-source.html">W3C API</a> built into browsers. Right now Firefox and Mobile Safari support it but it also cropped up in the latest <a href="http://www.wait-till-i.com/2010/03/04/google-chrome-getting-navigator-geolocation/">developer build of Chrome</a>.</p>
<p>Using the W3C location API is easy:</p>
<pre><code>&lt;script&gt;
if(navigator.geolocation){
  navigator.geolocation.getCurrentPosition(function(position){
    var lat = position.coords.latitude;
    var lon = position.coords.longitude;
    alert('you are at' + lat +','+lon);
  },function(error){
    alert('Couldn\'t get your location :(');
  });
}
&lt;/script&gt;</code></pre>
<p>You test if the browser supports <tt>navigator.geolocation</tt> and if it does you use the <tt>getCurrentPosition()</tt> method to retrieve the current position. This will cause the browser to ask the visitor if they want to share their information &#8211; normally in an information bar on top of the viewport as shown in this screenshot:</p>
<p><a title="Security popup triggered by navigator.geolocation by codepo8, on Flickr" href="http://www.flickr.com/photos/codepo8/4408578132/"><img style="border: 1px solid #999;" src="http://farm5.static.flickr.com/4068/4408578132_73bcb575c6.jpg" alt="Security popup triggered by navigator.geolocation" width="470" /></a></p>
<p>The <tt>getCurrentPosition()</tt> method takes two parameters which are function to call in the success and the failure case &#8211; meaning that the visitor allowed you to get their location or not &#8211; or that there was some other error.</p>
<p>You can then use YQL once more to get the location from latitude and longitude &#8211; this time using the Flickr API method as the first one:</p>
<pre><code>select * from geo.places where woeid in (
  select place.woeid from flickr.places where lat=51.5142271 and lon=-0.1289602
)</code></pre>
<p>See the <a href="http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20geo.places%20where%20woeid%20in%20(%0A%20%20select%20place.woeid%20from%20flickr.places%20where%20lat%3D51.5142271%20and%20lon%3D-0.1289602%0A)&amp;format=xml&amp;env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys">XML output here</a>.</p>
<h3>Putting it all together</h3>
<p>Let&#8217;s end with an example script how you can use this. We use the W3C geolocation API to get a visitor&#8217;s location and if it isn&#8217;t available we fall back to using the IP. In any case, we use YQL to get the location information and the areas around the current location. The solution uses JavaScript except for retrieving the IP which is done in this case by PHP. You can see the full <a href="http://isithackday.com/hacks/geo/geotest.php">demo in action here</a>. See the comments <tt>//</tt> for information about what is going on.</p>
<pre><code>&lt;script type="text/javascript" charset="utf-8"&gt;
&lt;?php
  if ($_SERVER['HTTP_X_FORWARD_FOR']) {
   $ip = $_SERVER['HTTP_X_FORWARD_FOR'];
  } else {
   $ip = $_SERVER['REMOTE_ADDR'];
  }
  if(preg_match('/^[\d+\.?]+$/',$ip)){
    echo 'var IP = "' . $ip . '"';
  }
?&gt;

// ^^
// This PHP block will get the current IP and assign it to a JavaScript
// variable - if it is the right format.

if(navigator.geolocation){
  navigator.geolocation.getCurrentPosition(
    function(position){
      getDataForLatLon(position.coords.latitude,
                       position.coords.longitude);
    },
    function(error){
      if(IP){
        getFromIP(IP);
      }
    });
} else{
  if(IP){
    getFromIP(IP);
  };
}

// ^^
// we test if the W3C location API is supported and if it is, we
// get the current lat and lon and call the appropriate method.
// if there was an error or the API is not available at all we call
// getFromIP.

function load(yql,cb){
  var src = 'http://query.yahooapis.com/v1/public/yql?q='+
            encodeURIComponent(yql) + '&amp;format=json&amp;callback=' + cb + '&amp;'+
            'env=store%3A%2F%2Fdatatables.org%2Falltableswithkeys';
  var head = document.getElementsByTagName('head')[0];
  var s = document.createElement('script');
  s.setAttribute('src',src);
  head.appendChild(s);
}

// ^^
// YQL is a web service that returns JSON. This allows us to create
// script nodes dynamically to get information from it. This function
// does that for us.

function getDataForLatLon(lat,lon){
  var yql = 'select * from geo.places where woeid in ('+
            'select place.woeid from flickr.places where lat='+
            lat + ' and  lon=' + lon + ')';
  load(yql,'foundLocation');
}
function foundLocation(o){
  if(o.query.results){
    var place = o.query.results.place
    var out = '&lt;p&gt;You are in ' + place.name + ' which is a '+
               place.placeTypeName.content + ' located at ('+
               place.centroid.latitude + ',' + place.centroid.longitude+
               ')&lt;/p&gt;';
    document.getElementById('location').innerHTML = out;
    getBelongTos(place.woeid);
  }
}

// ^^
// If we can get a lat and lon from the API, we put together the right
// YQL statement. If we are successful we call the foundLocation() method
// which writes out the right HTML to the document and calls the
// getBelongTos() method

function getFromIP(ip){
  var yql = 'select * from geo.places where woeid in ('+
            'select place.woeid from flickr.places where (lat,lon) in('+
            'select Latitude,Longitude from ip.location'+
            ' where ip="'+ip+'"))';
  load(yql,'foundLocation');
}

// ^^
// If there was no luck with the W3C geo API we call this function using
// the IP we got from PHP

function getBelongTos(woeid){
  var yql = 'select * from geo.places.belongtos(0) where '+
            'member_woeid='+woeid;
  load(yql,'foundBelongs');
}
function foundBelongs(o){
  if(o.query.results){
    var out = '&lt;p&gt;Your location belongs to: ';
    var place = o.query.results.place;
    var info = [];
    for(var i=0;i&lt;place.length;i++){
      var cur = place[i];
      info.push(cur.name + ' (' + cur.placeTypeName.content + ')');
    }
    var out = '&lt;p&gt;Your location belongs to: ' + info.join(', ') + '&lt;/p&gt;';
    document.getElementById('location').innerHTML += out;
  }
}

// ^^
// If we found a location, then we call the belongtos method of the
// GeoPlanet API to get all the areas the current location belongs to.

&lt;/script&gt;</code></pre>
<p>In my case the result from the W3C geo location is:</p>
<blockquote><p>You are in St. Giles&#8217;s which is a Suburb located at (51.516151,-0.125460)</p>
<p>Your location belongs to: WC1V 6 (Postal Code), London Borough of Camden (Local Administrative Area), 0207 London (Zone), Middlesex (Historical County), London (Town), Greater London (County), MMA London (MMA), South East England (Colloquial), DMA South East England (DMA), England (Country), England and Wales (Colloquial), Great Britain (Colloquial), United Kingdom (Country), Market United Kingdom and Ireland (Market), Europe/London (Time Zone), British Isles (Supername), Northern Europe (Supername), European Union (Supername), Western Europe (Supername), Europe (Continent), Eurasia (Supername), Earth (Supername)</p></blockquote>
<p>Only using IP I get:</p>
<blockquote><p>You are in Whitehall which is a Suburb located at (51.501831,-0.125760)</p>
<p>Your location belongs to: SW1A 2 (Postal Code), Westminster (Suburb), City of Westminster (Local Administrative Area), 0207 London (Zone), Middlesex (Historical County), London (Town), Greater London (County), MMA London (MMA), South East England (Colloquial), DMA South East England (DMA), England (Country), England and Wales (Colloquial), Great Britain (Colloquial), United Kingdom (Country), Market United Kingdom and Ireland (Market), Europe/London (Time Zone), British Isles (Supername), Northern Europe (Supername), European Union (Supername), Western Europe (Supername), Europe (Continent), Eurasia (Supername), Earth (Supername)</p></blockquote>
<p>Quite a lot of information using a few lines of code, isn&#8217;t it? Geographical location is a very interesting topic and allows us to show much more useful content to our visitors. Using YQL and GeoPlanet it is pretty easy for you to do so &#8211; give it a go!</p>
<img src="http://carsonified.com/?ak_action=api_record_view&id=4883&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://carsonified.com/blog/dev/getting-started-with-yahoo-geoplanet-explorer/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Future of Web Apps Highlights Video</title>
		<link>http://carsonified.com/blog/dev/future-of-web-apps-highlights-video/</link>
		<comments>http://carsonified.com/blog/dev/future-of-web-apps-highlights-video/#comments</comments>
		<pubDate>Mon, 08 Mar 2010 09:19:37 +0000</pubDate>
		<dc:creator>Keir Whitaker</dc:creator>
				<category><![CDATA[Dev]]></category>

		<guid isPermaLink="false">http://carsonified.com/?p=4900</guid>
		<description><![CDATA[By <strong>Keir Whitaker</strong><br />Our friends Jim and Nick at Doctype recently attended Future of Web Apps Miami along with their camera gear. They kindly put together a highlight reel of the day including interviews and clips from the main stage sessions. They will be releasing full length interviews over on their Facebook page shortly.
Just as a quick heads [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style=""><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fcarsonified.com%2Fblog%2Fdev%2Ffuture-of-web-apps-highlights-video%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcarsonified.com%2Fblog%2Fdev%2Ffuture-of-web-apps-highlights-video%2F" height="61" width="51" /></a></div><p>Our friends Jim and Nick at <a href="http://doctype.tv/">Doctype</a> recently attended Future of Web Apps Miami along with their camera gear. They kindly put together a highlight reel of the day including interviews and clips from the main stage sessions. They will be releasing full length interviews over on their <a href="http://facebook.com/doctype">Facebook</a> page shortly.</p>
<p>Just as a quick heads up the full length videos from the event will be made available shortly here on Think Vitamin.</p>
<p><object id="viddler_c59a9684" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="470" height="306" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowScriptAccess" value="always" /><param name="allowFullScreen" value="true" /><param name="src" value="http://www.viddler.com/player/c59a9684/" /><param name="name" value="viddler_c59a9684" /><param name="allowfullscreen" value="true" /><embed id="viddler_c59a9684" type="application/x-shockwave-flash" width="470" height="306" src="http://www.viddler.com/player/c59a9684/" name="viddler_c59a9684" allowfullscreen="true" allowscriptaccess="always"></embed></object></p>
<h3>Useful Links</h3>
<p>Doctype Future of Web Apps episode: <a href="http://doctype.tv/fowa">http://doctype.tv/fowa</a><br />
Twitter: <a href="http://twitter.com/doctypetv">http://twitter.com/doctypetv</a><br />
Facebook: <a href="http://facebook.com/doctype">http://facebook.com/doctype</a></p>
<img src="http://carsonified.com/?ak_action=api_record_view&id=4900&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://carsonified.com/blog/dev/future-of-web-apps-highlights-video/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>The Web as a Database</title>
		<link>http://carsonified.com/blog/dev/the-web-as-a-database/</link>
		<comments>http://carsonified.com/blog/dev/the-web-as-a-database/#comments</comments>
		<pubDate>Thu, 04 Mar 2010 14:54:23 +0000</pubDate>
		<dc:creator>Tom Hughes-Croucher</dc:creator>
				<category><![CDATA[Dev]]></category>

		<guid isPermaLink="false">http://carsonified.com/?p=4812</guid>
		<description><![CDATA[By <strong>Tom Hughes-Croucher</strong><br />One of the things that&#8217;s great about the Internet is that it&#8217;s open to everyone. There are a million sites, all different, and everyone is free to invent their own way of doing things. Of course, that has left us with a legacy of systems which don&#8217;t always work well together.
When you are using a [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style=""><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fcarsonified.com%2Fblog%2Fdev%2Fthe-web-as-a-database%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcarsonified.com%2Fblog%2Fdev%2Fthe-web-as-a-database%2F" height="61" width="51" /></a></div><p>One of the things that&#8217;s great about the Internet is that it&#8217;s open to everyone. There are a million sites, all different, and everyone is free to invent their own way of doing things. Of course, that has left us with a legacy of systems which don&#8217;t always work well together.</p>
<p>When you are using a web browser things mostly work because everyone adheres more or less to web standards, or at least the bits major browsers support. When you want to get data from the web to use in your app things aren&#8217;t quite as simple. Enter <a href="http://developer.yahoo.com/yql/">YQL (Yahoo Query Language)</a>.</p>
<p>Almost every developer knows about using SQL for getting data from databases. We wanted to do that for the Internet. YQL allows you to access all kinds of information from the internet in a very similar way to the way you would get data using SQL.</p>
<h3>A YQL Query</h3>
<p>A basic query in YQL is really easy:</p>
<p><code>select * from search.web where query = "javascript";</code></p>
<p>The thing we want to do is select all data (*) from Yahoo! search for web pages where the query is the term &#8220;javascript&#8221;. If you already know SQL it&#8217;s obvious, if you don&#8217;t it&#8217;s still pretty easy to read. In this case what&#8217;s happening under the hood is YQL is mapping the request to the search.web table to a pattern to call the <a href="http://developer.yahoo.com/search/boss/">Yahoo! BOSS</a> (search) web service. So we are actually making a request, on your behalf, to the url:</p>
<p><code>http://boss.yahooapis.com/ysearch/web/v1/javascript?format=xml&amp;start=0&amp;count=10<span id="more-4812"></span></code></p>
<h3>A Sample Result</h3>
<p>The data is returned in your choice of XML, JSON or JSONP. Like SQL most  YQL data tends to be organised as rows of results.</p>
<p>In the case of the above query it looks like this (NB: this is truncated to show one result, <a href="http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20search.web%20where%20query%20%3D%20%22javascript%22%3B&amp;format=xml">view a full version in your browser</a>):</p>
<p><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;<br />
&lt;query xmlns:yahoo="http://www.yahooapis.com/v1/base.rng" yahoo:count="10" yahoo:created="2010-03-02T09:22:58Z" yahoo:lang="en-US" yahoo:updated="2010-03-02T09:22:58Z" yahoo:uri="http://query.yahooapis.com/v1/yql?q=select+*+from+search.web+where+query+%3D+%22javascript%22%3B"&gt;<br />
&lt;diagnostics&gt;<br />
&lt;publiclyCallable&gt;true&lt;/publiclyCallable&gt;<br />
&lt;url execution-time="157"&gt;&lt;![CDATA[http://boss.yahooapis.com/ysearch/web/v1/javascript?format=xml&amp;start=0&amp;count=10]]&gt;&lt;/url&gt;<br />
&lt;user-time&gt;158&lt;/user-time&gt;<br />
&lt;service-time&gt;157&lt;/service-time&gt;<br />
&lt;build-version&gt;4265&lt;/build-version&gt;<br />
&lt;/diagnostics&gt;<br />
&lt;results&gt;<br />
&lt;result xmlns="http://www.inktomi.com/"&gt;<br />
&lt;abstract&gt;&lt;![CDATA[&lt;b&gt;JavaScript&lt;/b&gt;.com is your source for all things &lt;b&gt;JavaScript&lt;/b&gt;, including tutorials, free java scripts, downloads, tools, &lt;b&gt;javascript&lt;/b&gt; source code and other scripting resources.]]&gt;&lt;/abstract&gt;<br />
&lt;clickurl&gt;http://lrd.yahooapis.com/_ylc=X3oDMTQ4YzcwbGR0BF9TAzIwMjMxNTI3MDIEYXBwaWQDb0pfTWdwbklrWW5CMWhTZnFUZEd5TkouTXNxZlNMQmkEY2xpZW50A2Jvc3MEc2VydmljZQNCT1NTBHNsawN0aXRsZQRzcmNwdmlkAzc4ZHhPR0tJY3JyNGp1ZDd4R3RJcERZWXZOOFNqMHVNMlBJQUM0NkU-/SIG=10va2460d/**http%3A//www.javascript.com/&lt;/clickurl&gt;<br />
&lt;date&gt;2010/02/28&lt;/date&gt;<br />
&lt;dispurl&gt;&lt;![CDATA[www.&lt;b&gt;javascript.com&lt;/b&gt;]]&gt;&lt;/dispurl&gt;<br />
&lt;size&gt;59075&lt;/size&gt;<br />
&lt;title&gt;&lt;![CDATA[&lt;b&gt;JavaScript&lt;/b&gt;.com]]&gt;&lt;/title&gt;<br />
&lt;url&gt;http://www.javascript.com/&lt;/url&gt;<br />
&lt;/result&gt;<br />
&lt;/results&gt;<br />
&lt;/query&gt;<br />
</code></p>
<h3>Read AND Write with YQL</h3>
<p>Looking at the example above you might agree that it&#8217;s pretty easy to use the BOSS web service already since it&#8217;s RESTful and the URL are easy to construct. Well, the same can&#8217;t really be said for the Wordpress XML-RPC API. But, with YQL we can still easily insert a new post into a Wordpress blog:</p>
<p><code>insert into wordpress.post (title, description, blogurl, username, password) values ("Test Title", "This is a test body", "<a href="http://yqltest.wordpress.com" target="_blank">http://yqltest.wordpress.com</a>", "yqltest", "password"); </code></p>
<p>A few things are interesting here. Firstly we are still using SQL syntax, but this time we are inserting data. YQL doesn&#8217;t just read data, you can write too. More than that even though BOSS uses REST and Wordpress is XML-RPC with YQL you don&#8217;t need to care. You just ask for what you want and the YQL table deals with it. Once you start using YQL to get one piece of data there isn&#8217;t any more cost to using more services.</p>
<h3>Getting Started</h3>
<p>So far we&#8217;ve looked at some of the things YQL can do but not how you would go about getting started, so let&#8217;s do that. The easiest way to become familiar with YQL is the <a href="http://developer.yahoo.com/yql/console" target="_blank">YQL console</a>. It&#8217;s a lot like the MySQL console in that you can use it to easily query available tables or to test and construct queries you want to make in your application. The console looks like this:</p>
<p><a href="http://developer.yahoo.com/yql/console/"><img style="border: 1px solid #999999;" title="yql-console1" src="http://carsonified.com/wp-content/uploads/2010/03/yql-console1.jpg" alt="" width="470" height="253" /></a></p>
<p>The first and most obvious thing is the query box. This opens with the query &#8220;show tables&#8221; which as in SQL returns a list of all the available tables. You can see that result underneath the query box. You can use the radio buttons to get the results as XML or JSON, your choice.</p>
<p>On the right hand side we have some navigation to get you started quicker. The list of the current tables is shown and you can open the tree to folders to show specific tables.</p>
<p>By default we show all the Yahoo! tables, but you can also click on a button to show all the tables created by the community. These cover a wide variety of services, almost anything you can think of.</p>
<h3>Contribute Tables of your Own</h3>
<p>You can also contribute new tables. They can be either really straight forward in the case of a good REST web service, or as complex as it needs to be to get the job done. A simple table might look like this one:</p>
<p><code>&lt;table xmlns="<a href="http://query.yahooapis.com/v1/schema/table.xsd" target="_blank">http://query.yahooapis.com/v1/schema/table.xsd</a>"&gt;<br />
&lt;meta&gt;<br />
&lt;author&gt;Yahoo! Inc.&lt;/author&gt;<br />
&lt;documentationURL&gt;<a href="http://craigslist.org/" target="_blank">http://craigslist.org/</a>&lt;/documentationURL&gt;<br />
&lt;sampleQuery&gt;select * from {table} where location="sfbay" and type="sss" and query="schwinn mountain bike"&lt;/sampleQuery&gt;<br />
&lt;/meta&gt;<br />
&lt;bindings&gt;<br />
&lt;select itemPath="" produces="XML"&gt;<br />
&lt;urls&gt;<br />
&lt;url&gt;http://{location}.<a href="http://craigslist.org/search/%7Btype%7D?format=rss" target="_blank">craigslist.org/search/{type}?format=rss</a>&lt;/url&gt;<br />
&lt;/urls&gt;<br />
&lt;inputs&gt;<br />
&lt;key id="location" type="xs:string" paramType="path" required="true" /&gt;<br />
&lt;key id="type" type="xs:string" paramType="path" required="true" /&gt;<br />
&lt;key id="query" type="xs:string" paramType="query" required="true" /&gt;<br />
&lt;/inputs&gt;<br />
&lt;/select&gt;<br />
&lt;/bindings&gt;<br />
&lt;/table&gt;</code></p>
<p>You can see that it&#8217;s just XML, and only a few lines at that. The important bits are the &#8220;select&#8221; element. This represents a select statement we can make in YQL. If you wanted to insert you&#8217;d need an &#8220;insert&#8221; element too.</p>
<p>The select statement has a &#8220;url&#8221; which maps each &#8220;key&#8221; to the web service. In this case we have two path parameters which are inserted into the URL with <tt>{ }</tt> and a query parameter which is automatically added to the end. This is the entire data required to let you select from Craigslist in YQL.</p>
<p>YQL is easy and extensible, and best of all there are already <a href="http://github.com/yql/yql-tables" target="_blank">hundreds of tables contributed by the community</a> to all kinds of great services like Twitter, Facebook, Etsy, bit.ly?</p>
<p>What are you waiting for, <a href="http://developer.yahoo.com/yql/console" target="_blank">try the console today</a>!</p>
<img src="http://carsonified.com/?ak_action=api_record_view&id=4812&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://carsonified.com/blog/dev/the-web-as-a-database/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>17 Essential Developer Networks</title>
		<link>http://carsonified.com/blog/dev/17-essential-developer-networks/</link>
		<comments>http://carsonified.com/blog/dev/17-essential-developer-networks/#comments</comments>
		<pubDate>Wed, 03 Mar 2010 13:27:37 +0000</pubDate>
		<dc:creator>Keir Whitaker</dc:creator>
				<category><![CDATA[Dev]]></category>

		<guid isPermaLink="false">http://carsonified.com/?p=4834</guid>
		<description><![CDATA[By <strong>Keir Whitaker</strong><br />Recently I have been noticing that more and more tech companies are starting up &#8220;developer networks&#8221;. Some of these, like the Yahoo! Developer Network, consist of great tools and resources (think YQL, YUI etc) that we can all make use of in our work whilst others focus on more specific aspects of developing with a [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style=""><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fcarsonified.com%2Fblog%2Fdev%2F17-essential-developer-networks%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcarsonified.com%2Fblog%2Fdev%2F17-essential-developer-networks%2F" height="61" width="51" /></a></div><p>Recently I have been noticing that more and more tech companies are starting up &#8220;developer networks&#8221;. Some of these, like the <a href="http://developer.yahoo.com/">Yahoo! Developer Network</a>, consist of great tools and resources (think <a href="http://developer.yahoo.com/yql/">YQL</a>, <a href="http://developer.yahoo.com/yui/">YUI</a> etc) that we can all make use of in our work whilst others focus on more specific aspects of developing with a particular service or app.</p>
<p>Whilst tutorials and code examples are great the added bonus of a network is the community that grows around it. It&#8217;s likely that you won&#8217;t be the first person to experience a particular issue so it&#8217;s a great place to share application specific tips and frustrations.</p>
<p>Here are 17 networks and sites that you might not know about but are worth checking out.</p>
<h3>Tech Company Networks</h3>
<ol>
<li><a href="http://developer.yahoo.com/">Yahoo! Developer Network</a></li>
<li><a href="http://x.com">PayPal Developer  Network</a></li>
<li><a href="http://developers.sun.com/">Sun Developer Network</a></li>
<li><a href="http://msdn.microsoft.com">Microsoft Developer Network</a></li>
<li><a href="http://www.ibm.com/developerworks/">IBM Developer Works</a></li>
<li><a href="http://developer.apple.com/">Apple Developers</a></li>
<li><a href="https://developer.mozilla.org/En">Mozilla Developer Network</a></li>
<li><a href="http://developer.palm.com/">Palm Developer Center</a></li>
<li><a href="http://code.google.com/">Google  Code</a></li>
<li><a href="http://dev.opera.com/">Opera Developer Community</a></li>
</ol>
<h3>Application Specific Networks &amp; Sites</h3>
<ol>
<li><a href="http://codex.wordpress.org/Main_Page">WordPress Codex</a></li>
<li><a href="http://developer.ning.com/">Ning Developers</a></li>
<li><a href="http://developers.freshbooks.com/">Freshbook Developers</a></li>
<li><a href="http://developers.facebook.com/">Facebook Developers</a></li>
<li><a href="http://apiwiki.twitter.com/">Twitter API Wiki</a></li>
<li><a href="http://about.digg.com/developers">Digg Developers</a></li>
<li><a href="http://developer.37signals.com/">37signals Developer Site</a></li>
</ol>
<p>If you know of any more please add them in the comments, it would be great to publish a more complete list.</p>
<img src="http://carsonified.com/?ak_action=api_record_view&id=4834&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://carsonified.com/blog/dev/17-essential-developer-networks/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
		<item>
		<title>Tips and Tricks for developing Mobile Widgets</title>
		<link>http://carsonified.com/blog/dev/tips-and-tricks-for-developing-mobile-widgets/</link>
		<comments>http://carsonified.com/blog/dev/tips-and-tricks-for-developing-mobile-widgets/#comments</comments>
		<pubDate>Mon, 01 Mar 2010 14:56:43 +0000</pubDate>
		<dc:creator>Keir Whitaker</dc:creator>
				<category><![CDATA[Dev]]></category>

		<guid isPermaLink="false">http://carsonified.com/?p=4672</guid>
		<description><![CDATA[By <strong>Keir Whitaker</strong><br />It&#8217;s not often Bath, the home of Carsonified, hosts full day tech events. However I was recently lucky enough to attend openMIC right here on my doorstep.
&#8220;Open Mobile Innovation Camp&#8221; is organised by Chris Book and takes place around the UK. It describes itself as &#8220;an un-conference for discussion, debate and development new mobile applications [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style=""><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fcarsonified.com%2Fblog%2Fdev%2Ftips-and-tricks-for-developing-mobile-widgets%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcarsonified.com%2Fblog%2Fdev%2Ftips-and-tricks-for-developing-mobile-widgets%2F" height="61" width="51" /></a></div><p>It&#8217;s not often Bath, the home of Carsonified, hosts full day tech events. However I was recently lucky enough to attend <a href="http://openmicamp.ning.com/">openMIC</a> right here on my doorstep.</p>
<p>&#8220;Open Mobile Innovation Camp&#8221; is organised by <a href="http://twitter.com/bookmeister">Chris Book</a> and takes place around the UK. It describes itself as &#8220;an un-conference for discussion, debate and development new mobile applications and mobile web services&#8221;. You can find out more on their <a href="http://openmicamp.ning.com/">Ning</a> site.</p>
<p>As part of the morning sessions <a href="http://www.brucelawson.co.uk">Bruce Lawson</a> from <a href="http://opera.com">Opera</a> gave a great presentation entitled &#8220;Tips and tricks for mobile widgets&#8221;. Whilst part of the talk was directly related to mobile widgets much of it can be related to best practice web development.</p>
<h3>What&#8217;s a Widget?</h3>
<p>Firstly let&#8217;s be clear on what a Mobile Widget actually is. As Bruce explained we can think of Mobile Widgets as &#8220;client side apps&#8221;. They are created using standard web technologies such as HTML, JavaScript and CSS.</p>
<p>To create a widget you ZIP up your project files and rename it with an extension of <em>.wgt</em>. They differ slightly from traditional &#8220;web apps&#8221; in as much as they offer access to the local device file system and can auto-update.</p>
<p>Here&#8217;s a summary of Bruce&#8217;s key points, for some this may be new, for others I am sure it will serve as a good reminder.<span id="more-4672"></span><br />
<strong><br />
Things to consider when creating the widget</strong></p>
<ul>
<li> <strong>The physical and virtual size of the screen</strong> &#8211; How will your interface work, where will the key elements be, how will users navigate around the screen</li>
<li> <strong>Readability</strong> &#8211; Make it clear and readable and get your message across</li>
<li> <strong>Input mechanism</strong> &#8211; Make it easy for users to interact with your widget</li>
<li> <strong>Memory, CPU and Battery limitations</strong> &#8211; Look at ways to limit their usage</li>
<li> <strong>Network speed</strong> &#8211; Don&#8217;t rely on speedy networks</li>
</ul>
<p><strong>Work round flaky networks</strong></p>
<ul>
<li> <strong>Queue XHR (XMLHttpRequest) requests</strong> &#8211; This will reduce the initial load on the network connection</li>
<li> <strong>Cache data</strong> &#8211; Don&#8217;t keep polling for the same data</li>
<li> <strong>Ensure try again options </strong>- What happens if you loose signal, plan for this</li>
<li> <strong>Pick up where you left off </strong>- Ensure that your widget resumes where it left off after a phone call</li>
</ul>
<p><strong>Minimise HTTP requests</strong></p>
<ul>
<li> <strong>Use CSS Sprites</strong> &#8211; Reduce the number of image requests by using one file for all your images (See <a href="http://css-tricks.com/css-sprites/">http://css-tricks.com/css-sprites/</a>)</li>
<li> <strong>Consider using data URLs</strong> &#8211; These allow you to use a URL to represent an image as opposed to a file resulting in one less file request across the network as the image will effectively be present in your HTML. (See <a href="http://software.hixie.ch/utilities/cgi/data/data">http://software.hixie.ch/utilities/cgi/data/data</a>)</li>
</ul>
<p><strong>Markup</strong></p>
<ul>
<li> <strong>Place JavaScript source and file references at bottom of you page</strong> &#8211; This will mean that the bulk of the page will load before your JS files, users will be able to start reading the page straightaway</li>
<li> <strong>Don&#8217;t use TABLE layout</strong> &#8211; Extra overhead that isn&#8217;t necessary</li>
<li> <strong>Declare image sizes in HTML</strong> &#8211; Use height and width attributes on images. This will reduce pages being redrawn once an image is downloaded, resulting in a better user experience and less work for your mobile device&#8217;s CPU.</li>
<li> <strong>Consider using SVG (Scalable Vector Graphics) for illustrations or &lt;canvas&gt; for dynamic images </strong>- These send data as mathematical info which tells the browser how to draw it. It&#8217;s also scalable and doesn&#8217;t pixelate.</li>
</ul>
<p><strong>Understand accessibility</strong></p>
<p>There are many similarities between understanding accessibility on the web and mobile devices. Bruce recommends reading &#8220;<a href="http://www.w3.org/TR/mwbp-wcag/">Relationship between Mobile Web Best Practices (MWBP) and Web Content Accessibility Guidelines (WCAG)</a>&#8221;</p>
<ul>
<li> <strong>No images</strong> &#8211; What happens to your widget with images off?</li>
<li> <strong>No fonts/colours </strong>- What if the device doesn&#8217;t support your preferred font or colour?</li>
<li> <strong>Contrast</strong> &#8211; Ensure that it&#8217;s readable for visually impaired users</li>
</ul>
<p><strong>CSS for mobile devices</strong></p>
<ul>
<li> <strong>Use ems not px for fonts</strong> &#8211; This is better for scalability</li>
<li> <strong>Use CSS sprites</strong> &#8211; See above</li>
<li> <strong>Fluid layouts</strong> &#8211; This will enable your widget to work on different resolutions</li>
<li> <strong>Use <a href="http://www.w3.org/TR/css3-mediaqueries/">media queries</a> </strong>- These will allow you to serve different CSS files dependent on the screen size of the device</li>
<li> <strong>Use SVG for background images</strong> &#8211; Declaring &#8220;width: 100%;  height: auto;&#8221; will allow your image to scale regardless</li>
<li> <strong>Sniff out the device info</strong> &#8211; Like media queries this will enable you to serve a different user experience dependent on the device</li>
</ul>
<p><strong>Be prepared for HTML5</strong></p>
<ul>
<li> <strong>Form validation is free</strong> &#8211; No further need for complicated validation JavaScript</li>
<li> <strong>Client side persistent storage of key/value pairs and support for embedded SQL databases </strong>- This will reduce the need to make requests over the network</li>
<li> <strong>Server sent events</strong> &#8211; The &lt;event-source&gt; element reduce need for polling in web apps. It will allow the receiving of push notifications from a server in the form of DOM   events</li>
</ul>
<p><strong>Opera widgets SDK</strong></p>
<ul>
<li> <strong>Documentation</strong> &#8211; Extensive <a href="http://dev.opera.com/articles/view/opera-widgets-sdk/">documentation</a> provided by Opera</li>
<li> <strong>Test</strong> &#8211; Use the <a href="http://dev.opera.com/articles/view/widget-emulator/">emulator</a> to test your widget</li>
<li> <strong>Opera Libraries</strong> &#8211; Lightweight libraries for <a href="http://dev.opera.com/libraries/animation/">animation</a> etc</li>
<li> <strong>Explore the SDK </strong>- <a href="http://dev.opera.com/sdk">http://dev.opera.com/sdk</a></li>
<li><strong>Debug your widget</strong> &#8211; Opera provide a free debugging tool called <a href="http://www.opera.com/dragonfly/">Dragonfly</a></li>
</ul>
<p><strong>Test your Widget</strong></p>
<ul>
<li> <strong>Test your widget on real devices</strong> &#8211; <a href="http://perfectomobile.com/portal/cms/opera.xhtml?key=OP631R89YL2">http://perfectomobile.com/portal/cms/opera.xhtml?key=OP631R89YL2</a></li>
</ul>
<h3>Thoughts?</h3>
<p>If you have developed a widget or have something to add please let us know in the comments.</p>
<h3>View the Slides</h3>
<p><img style="visibility: hidden; width: 0px; height: 0px;" src="http://counters.gigya.com/wildfire/IMP/CXNID=2000002.0NXC/bT*xJmx*PTEyNjY*OTA1MDE1MTYmcHQ9MTI2NjQ5MDUwNTczOSZwPTEwMTkxJmQ9c3NfZW1iZWQmZz*yJm89NDMwMjUzMDlkOWM1/NDcxOGIwMjMzNDljMDA2OTg5NGYmb2Y9MA==.gif" border="0" alt="" width="0" height="0" /></p>
<div id="__ss_3156151" style="width: 425px; text-align: center;"><a style="display: block; margin: 12px 0 3px 0; text-decoration: underline;" title="Practical Tips for Mobile Widget development" href="http://www.slideshare.net/brucelawson/practical-tips-for-mobile-widget-development-3156151">Practical Tips for Mobile Widget development</a><object style="margin: 0px;" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="425" height="355" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowFullScreen" value="true" /><param name="allowScriptAccess" value="always" /><param name="src" value="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=bath-openmic-100212084105-phpapp01&amp;stripped_title=practical-tips-for-mobile-widget-development-3156151" /><param name="allowfullscreen" value="true" /><embed style="margin: 0px;" type="application/x-shockwave-flash" width="425" height="355" src="http://static.slidesharecdn.com/swf/ssplayer2.swf?doc=bath-openmic-100212084105-phpapp01&amp;stripped_title=practical-tips-for-mobile-widget-development-3156151" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
<div style="text-align: center;">View more <a href="http://www.slideshare.net/">presentations</a> from <a style="text-decoration: underline;" href="http://www.slideshare.net/brucelawson">brucelawson</a>.</div>
</div>
<img src="http://carsonified.com/?ak_action=api_record_view&id=4672&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://carsonified.com/blog/dev/tips-and-tricks-for-developing-mobile-widgets/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Mistakes Were Made: Making Interactive Maps With jQuery</title>
		<link>http://carsonified.com/blog/dev/making-interactive-maps-with-jquery/</link>
		<comments>http://carsonified.com/blog/dev/making-interactive-maps-with-jquery/#comments</comments>
		<pubDate>Fri, 19 Feb 2010 14:00:01 +0000</pubDate>
		<dc:creator>Chrissie Brodigan</dc:creator>
				<category><![CDATA[Dev]]></category>

		<guid isPermaLink="false">http://carsonified.com/?p=4591</guid>
		<description><![CDATA[By <strong>Chrissie Brodigan</strong><br />(Updated note: the data source is an evolving project, one of the reasons we needed this app to be flexible and easily updated by a non-tech team, so this article is really focused on the technical aspects of putting this little ecosystem together.)
I use both Flash and jQuery when designing interactions for data visualization projects. [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style=""><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fcarsonified.com%2Fblog%2Fdev%2Fmaking-interactive-maps-with-jquery%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcarsonified.com%2Fblog%2Fdev%2Fmaking-interactive-maps-with-jquery%2F" height="61" width="51" /></a></div><p><em>(Updated note: the data source is an evolving project, one of the reasons we needed this app to be flexible and easily updated by a non-tech team, so this article is really focused on the technical aspects of putting this little ecosystem together.)</em></p>
<p>I use both Flash and jQuery when designing interactions for data visualization projects. A great opportunity came along to experiment with ways jQuery could be used to develop an interactive map. Before I go further, I admit that mistakes were made, but no pandas were harmed at any point and our team learned a lot, so it ended up a win-win (for us and the pandas).</p>
<p>The project we started out with was simple, we had a comp and a request to create a flash map that could display some static data. After diving in a little deeper, it became clear that the data source would change on a regular basis, so I recommended that we try to create a small ecosystem with various pieces of the project:</p>
<ul>
<li>spreadsheet (our data source)</li>
<li>CMS (client was using Wordpress)</li>
<li>map of the U.S. (caveat: each U.S. location needed to be able to be displayed in 1 of 3 colors: red, yellow, green for the animation, and ultimately managed as an .SVG)</li>
</ul>
<p style="text-align: center"><a href="http://carsonified.com/wp-content/uploads/2010/02/doms_subs.jpg"><img class="aligncenter size-full wp-image-4592" src="http://carsonified.com/wp-content/uploads/2010/02/doms_subs.jpg" alt="" width="470" height="348" /><span id="more-4591"></span></a></p>
<h3>jQuery as a Substitute for Flash?</h3>
<p>We could have accomplished everything with Flash, but we wanted to learn something new and today’s browsers (shame-free plug for Chrome!) speed up DOM manipulations, so Flash isn’t the only or best choice, and there were clear benefits:</p>
<ul>
<li><em>Easy—</em>jQuery is already packaged into Wordpress</li>
<li><em>Styling—</em>design can be easily restyled by almost any team member</li>
<li><em>Integrated—</em>everything lives integrated within the page v. living in layers</li>
<li><em>UX first—</em>end users never need to install a plugin</li>
<li><em>Recession proof—</em>we didn’t have to buy another Adobe product</li>
</ul>
<h3>Other Things we Kept in Mind</h3>
<p><strong>Smart architecture: </strong>All of the data is stored in a simple spreadsheet. jQuery, CSS, and simple variable placement determined by a PHP script takes the data and displays it both properly and in multiple places (click over to <a href="http://teachingjobsportal.com" target="_blank">teachingjobsportal.com</a> to see it in action).</p>
<p><strong>Developer-free updates: </strong>The little ecosystem we created allowed us to use one data source to update both the map and each of the locations’ corresponding pages (51 pages for 50 states &amp; DC) that are stored in Wordpress. This keeps things simple, reduces the chance for user error, saves a ton of time because a user doesn’t have to open all the individual files, and doesn’t require involving a developer.</p>
<p><strong>SEO-friendly:</strong> jQuery allowed us to represent all of the data in HTML, so Google and other search engines can gobble it up and help us make it more discoverable.</p>
<p><strong>Joel Sutherland:</strong> Joel Sutherland of New Media Campaigns wrote an awesome<a href="http://www.newmediacampaigns.com/page/jquery-vs-flash-for-interactive-map"> post</a> on building an interactive map with jQuery over Flash in January 2009, and he made me believe we could do it too (albeit on a far simpler scale).</p>
<h3><strong>Like I Said, Mistakes Were Made</strong></h3>
<p><strong>We got too fancy</strong></p>
<p>At a point while we were executing, we decided to convert the data export from the CSV into XML (this also converted the .SVG and made it dynamic). While XML was easier to work with on the developer-side, it added steps and complexities to the process</p>
<p>Additionally, the map’s point-by-point coordinates, complex outlines (U.S. states are not nicely designed with 90 degree angles), and dynamic states required that we use software to both build the map and manage the images in an alternate library, enter <a href="http://www.imagemagick.org/" target="_blank">ImageMagick</a>. Simple enough, but the problem using ImageMagick to manage the library of the various U.S. state colors we also introduced <a href="http://pecl.php.net/package/imagick" target="_blank">“Imagick”</a> a truly nasty PHP extension into the mix, which caused a new set of issues.</p>
<p><strong>We descended into dependency hell</strong></p>
<p><strong></strong>Installing PHP extensions can be tough, and Imagick is a huge pain in the a$$. During installation, it requires that you be prepared to manage a large set of spaghetti-like dependencies. There’s also a small bug that we ran into, which prevented compiling, so our Debian-friendly team found ourselves in Unix-land attempting to execute YUM (which usually solves the problem of “dependency hell”), and ultimately lost the battle and had to compile ImageMagick manually (both annoying and a time-suck).</p>
<p><strong>We created simple, but stubborn architecture</strong></p>
<p>Our little ecosystem (the one I’ve touted as mostly simple) is quiet stubborn and set in her ways. We can make updates to the data anytime, but because we didn’t build the data source as a database, we cannot easily add new fields without having to update everything.</p>
<p><strong>We overlooked Hawaii &amp; Alaska</strong></p>
<p><strong></strong>I threw this one in for fun, but whoa! Big oversight! We accidentally forgot to include HI and Alaska and essentially redesigned the U.S. without them.</p>
<h3>So, to Wrap it all Up</h3>
<p>jQuery was a great substitute to Flash for us, making <a href="http://TeachingJobsPortal.com" target="_blank">TeachingJobsPortal’s</a> map. Furthermore, the execution was mostly simple, our client can control the map and its related pages’ content without having to hire a developer. <em>(*I also didn’t have to learn Flash on the fly)</em></p>
<p>Though our animation designs are ongoing, we’ve created a new and much nicer hover state, we really like the way that the gauge works (it’s connected to the image library and as the states change color it automatically updates as well), and, as planned, the map smoothly changes colors when the data source is updated.</p>
<p>We’re considering ways we can eliminate using ImageMagick for the library, because we want to use the map on another project and lighten up the load on the CMS, so I’d love your thoughts on that as well as any other ideas you have on jQuery v. Flash!</p>
<p>I owe a lot to Joel Sutherland for sharing his team’s work, so we could learn from it, and for releasing a fantastic jQuery <a href="http://www.newmediacampaigns.com/page/a-jquery-plugin-for-zoomable-interactive-maps" target="_blank">plug-in </a>that I encourage you to use if you ever create <a href="http://www.newmediacampaigns.com/page/a-jquery-plugin-for-zoomable-interactive-maps" target="_blank">zoomable interactive maps. </a></p>
<p><em>*Production by my brilliant partners at <a href="http://jjomedia.com">jjomedia.com</a></em></p>
<img src="http://carsonified.com/?ak_action=api_record_view&id=4591&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://carsonified.com/blog/dev/making-interactive-maps-with-jquery/feed/</wfw:commentRss>
		<slash:comments>18</slash:comments>
		</item>
		<item>
		<title>Future of Web Apps Dublin 2010</title>
		<link>http://carsonified.com/blog/dev/future-of-web-apps-dublin-2010/</link>
		<comments>http://carsonified.com/blog/dev/future-of-web-apps-dublin-2010/#comments</comments>
		<pubDate>Thu, 18 Feb 2010 14:10:56 +0000</pubDate>
		<dc:creator>Keir Whitaker</dc:creator>
				<category><![CDATA[Dev]]></category>

		<guid isPermaLink="false">http://carsonified.com/?p=4685</guid>
		<description><![CDATA[By <strong>Keir Whitaker</strong><br />
In case you missed it we announced Future of Web Apps Dublin 2010 earlier this week. It&#8217;s a one day conference taking place on Friday May 14th 2010 in the heart of Dublin.
We are calling this years event &#8220;Ireland&#8217;s BIG Web App Conference&#8220;. More big name speakers, new bigger venue and big value for attendees. [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style=""><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fcarsonified.com%2Fblog%2Fdev%2Ffuture-of-web-apps-dublin-2010%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcarsonified.com%2Fblog%2Fdev%2Ffuture-of-web-apps-dublin-2010%2F" height="61" width="51" /></a></div><p style="text-align: center;"><a href="http://futureofwebapps.com"><img class="aligncenter size-full wp-image-4687" style="border: 1px solid #999999;" title="fowa_dublin" src="http://carsonified.com/wp-content/uploads/2010/02/fowa_dublin.jpg" alt="" width="470" height="295" /></a></p>
<p style="text-align: left;">In case you missed it we announced <a href="http://futureofwebapps.com">Future of Web Apps Dublin 2010</a> earlier this week. It&#8217;s a one day conference taking place on Friday May 14th 2010 in the heart of Dublin.</p>
<p style="text-align: left;">We are calling this years event &#8220;<em><strong>Ireland&#8217;s BIG Web App Conference</strong></em>&#8220;. More big name speakers, new bigger venue and big value for attendees. Why not make it a long weekend in Dublin, the city practically guarantees a great time.</p>
<p style="text-align: left;">Interested? You can <a href="http://futureofwebapps.com/register/?utm_source=thinkvitamin&amp;utm_medium=textlink&amp;utm_campaign=launch_article">buy your ticket online</a> on the brand new Future of Web Apps website.</p>
<h3 style="text-align: left;">Who&#8217;s Speaking?</h3>
<p>Future of Web Apps regularly brings together leading practitioners in the field of web development and web entrepreneurship. This year is no exception, here&#8217;s a taste of our confirmed lineup. Further speakers will be announced in the coming weeks.</p>
<ul>
<li><strong>Mike McDerment</strong> &#8211; CEO and Founder of <a href="http://www.freshbooks.com">Freshbooks</a> on &#8220;<strong><em>Marketing Metrics and the Systems You Need to Measure Them</em></strong>&#8220;</li>
<li><strong>Raffi Krikorian</strong> &#8211; <a href="http://twitter.com">Twitter</a>&#8217;s Geospatial API lead on &#8220;<strong><em>How to use Geolocation in Your Web App</em></strong>&#8220;</li>
<li><strong>Simon Wardley</strong> &#8211; Cloud computing guru working at <a href="http://www.canonical.com">Canonical</a> on &#8220;<strong><em>Situation Normal, Everything Must Change</em></strong>&#8220;</li>
<li><strong>Christian Heilmann</strong> &#8211; Developer Evangelist at <a href="http://www.yahoo.com">YAHOO</a> on &#8220;<strong><em>Powerful Tools that You Need (and Probably Don&#8217;t Know About)</em></strong>&#8220;</li>
<li><strong>Eoghan McCabe &amp; Des Traynor</strong> &#8211; The guys from <a href="http://www.contrast.ie">Contrast</a> are back with us talking about &#8220;<strong><em>Five Lessons We&#8217;ve Learned</em></strong>&#8220;</li>
<li><strong>Relly Annett-Baker</strong> &#8211; <a href="http://poppycopy.co.uk/">Web copywriter</a> extraordinaire 0n how to &#8220;<strong><em>Write Effective Web Copy</em></strong>&#8220;</li>
</ul>
<p>Full details of the speakers can be found on the <a href="http://futureofwebapps.com/speakers/">Future of Web Apps website</a>.<span id="more-4685"></span></p>
<h3>What can you expect?</h3>
<ul>
<li>Amazing speakers discussing the hot web app topics</li>
<li>Great networking with like minded developers and entrepreneurs</li>
<li>Free refreshments throughout the day and a great lunch</li>
<li>Fun times at the after party</li>
</ul>
<h3>Grab a ticket today</h3>
<p>Tickets are selling fast but there are a handful of early bird passes left for <strong>€195 + VAT</strong> (normal price €245 + VAT). We also have student passes available for €55 + VAT. You can <a href="http://futureofwebapps.com/register/?utm_source=thinkvitamin&amp;utm_medium=textlink&amp;utm_campaign=launch_article">purchase your ticket online</a> on our website.</p>
<h3>Get involved</h3>
<p>We are introducing a new option for 2010 called &#8220;Micro-Sponsorship&#8221;. It&#8217;s a great way of putting your company or web app directly in front of your target audience.</p>
<p>For  €100 + VAT we will email all Future of Web Apps Dublin attendees your link + 140 characters of your choice one week prior to the conference. If your interested just head on over to our <a href="http://futureofwebapps.com/register/?utm_source=thinkvitamin&amp;utm_medium=textlink&amp;utm_campaign=launch_article">registration</a> page.</p>
<p>We look forward to enjoying a pint of the &#8220;black stuff&#8221; with you in May!</p>
<img src="http://carsonified.com/?ak_action=api_record_view&id=4685&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://carsonified.com/blog/dev/future-of-web-apps-dublin-2010/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Finding your Flock in Twitter</title>
		<link>http://carsonified.com/blog/dev/finding-your-flock-in-twitter/</link>
		<comments>http://carsonified.com/blog/dev/finding-your-flock-in-twitter/#comments</comments>
		<pubDate>Thu, 18 Feb 2010 11:00:26 +0000</pubDate>
		<dc:creator>Brian Suda</dc:creator>
				<category><![CDATA[Dev]]></category>

		<guid isPermaLink="false">http://carsonified.com/?p=4585</guid>
		<description><![CDATA[By <strong>Brian Suda</strong><br />Twitter is certainly an interesting beast. It has been the poster child of success stories, saving lives, reporting tragedies, over turning governments and letting thousands of people know where you are going for lunch. There is no denying the impact it has on our scenius.
I wondered if there was a way to find out a [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style=""><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fcarsonified.com%2Fblog%2Fdev%2Ffinding-your-flock-in-twitter%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcarsonified.com%2Fblog%2Fdev%2Ffinding-your-flock-in-twitter%2F" height="61" width="51" /></a></div><p>Twitter is certainly an interesting beast. It has been the poster child of success stories, saving lives, reporting tragedies, over turning governments and letting thousands of people know where you are going for lunch. There is no denying the impact it has on our scenius.</p>
<p>I wondered if there was a way to find out a bit more about how twitter was being used within the local community and if it was even possible to take a smaller stream from the river of data Twitter produces daily. I chose as my local community Iceland.</p>
<p>I did so for several reasons, it is small-only about 300,000 people total, it has a distinct language so it is easy to find people using the only the text search, and it is where I live so any cool information I learn about, I can actually use it.</p>
<p>Any of the following steps can easily be reproduced for your local area, community or group. You&#8217;ll just need to find the key to unlocking like-minded people.</p>
<h3>RSS not API</h3>
<p>The <a href="http://apiwiki.twitter.com/">Twitter API</a> has plenty of great features, but to accomplish all of this I am using the <a href="http://search.twitter.com">twitter search</a> RSS results. There are plenty of libraries in your favourite language to parse RSS, so I won&#8217;t go into depth about those nuts and bolts. The key to getting quality data is to formulate very specific searches.</p>
<p>In Icelandic, there are several characters and words unique to the language. In your niche group there is jargon which can be used to identify the people in the know, a sort of 21st century Shibboleth.</p>
<p>To try and find Icelandic Twitters, an easy first pass is to search for purely Icelandic words. This link will return an RSS feed of matching tweets.</p>
<p><a href="http://search.twitter.com/search.atom?q=það ">http://search.twitter.com/search.atom?q=það </a></p>
<p><code>&lt;entry&gt;<br />
&lt;id&gt;tag:search.twitter.com,2005:8243287523&lt;/id&gt;<br />
&lt;published&gt;2010-01-26T17:29:23Z&lt;/published&gt;<br />
&lt;link type="text/html" href="http://twitter.com/username/statuses/12345" rel="alternate"/&gt;<br />
&lt;title&gt;...&lt;/title&gt;<br />
&lt;content type="html"&gt;...&lt;/content&gt;<br />
&lt;updated&gt;2010-01-26T17:29:23Z&lt;/updated&gt;<br />
&lt;link type="image/png" href="http://a1.twimg.com/profile_images/1234/profile5_normal.png" rel="image"/&gt;<br />
&lt;twitter:geo&gt;<br />
&lt;/twitter:geo&gt;<br />
&lt;twitter:source&gt;...&lt;/twitter:source&gt;<br />
&lt;twitter:lang&gt;is&lt;/twitter:lang&gt;<br />
&lt;author&gt;<br />
&lt;name&gt;Display Name&lt;/name&gt;<br />
&lt;uri&gt;http://twitter.com/username&lt;/uri&gt;<br />
&lt;/author&gt;<br />
&lt;/entry&gt;<span id="more-4585"></span></code></p>
<p>From this, we can then extract the display names and twitter usernames and plenty of other information about the tweet.</p>
<p>If you try searching for some jargon within your field, you can begin to collect like-minded people.</p>
<p>There is also a feature in the search which allows for language detection. Using the parameter <tt>&amp;lang=is</tt> it is possible to further filter the search. For English speakers, this might be more difficult than other languages. The system isn&#8217;t perfect either, but it can be away to limit search results for terms like &#8220;schmuck&#8221; in German to jewelry and &#8220;schmuck&#8221; in English to an insult.</p>
<p>Finally, you can restrict the results to a geographically close group of friends by using the near parameter <tt>&amp;near=New+York&amp;within=15&amp;units=mi</tt>. You can also specific the distance and units (miles or kilometers). At the moment this is trying to using the user&#8217;s Location, but in the future it might also use their new <a href="http://blog.twitter.com/2009/08/location-location-location.html">geolocation API</a>. People don&#8217;t always list their location, or change it out of solidarity to a cause.</p>
<p>These systems aren&#8217;t perfect, but when put together they allow for an easy way to thin down the millions of twitter to a much smaller more manageable size.</p>
<h3>Create your own Groups</h3>
<p>This is ideal for local affinity groups or video game clans. Want to see what all &#8220;EVE Online&#8221; player who are in a specific company and live in &#8220;New York City&#8221; have to say? Well we can search twitter and start to collect matching usernames, index them and search for interesting conversations. Maybe you can make new friends locally beyond the game.</p>
<p>The downside of using search is that you will only find new people as they tweet. Search only goes back 10 days (maybe less as twitter gets larger and larger). There will also be some false positives, but if you select some good, specific search terms, then you minimize the work pruning out mistakes.</p>
<p>I am searching twitter once an hour for any new posts that meet the criteria. Once an hour is enough for me, but depending on the size and frequency of your group, you can poll more or less frequently. As I loop through the RSS results and find username not already in the database, I add them so I have a nice growing list of people. I then subscribe to their RSS and save all the tweets into another table for later analysis.</p>
<h3>Find and Subscribe</h3>
<p>Over time, I have managed to find 3900+ Icelanders on twitter. That&#8217;s over 1% of the population. Twitter does have a limit of 2000 that people you can follow before you need to maintain a ratio of following to followers. This prevent spammers from following thousands of people and wrecking the system.</p>
<p>Once you have the twitter username, it isn&#8217;t necessary to follow them via twitter&#8217;s functionality, it&#8217;s enough to subscribe directly to their RSS feed if they are public. Now it seems rediculous to subscribe to thousands of RSS feeds, that&#8217;s a bandwidth hog. So I have offloaded that work to Google Reader. Google has cached versions, so all I need to do is access a single feed in Google Reader which is a composite of all the Twitter RSS feeds I have found. This makes a single RSS fire hose of your groups tweets.</p>
<h3>Twitter Stats</h3>
<p>Since I started mining my twitter data, some interesting statistics have emerged. I looked at the last 24 hours to see how many unique usernames had posted. Roughly 10% of the twitter population in Iceland is posting on a daily basis, but how active are they? Well, we can look at how many posts there were in the last 24 hours and divide that into active users and get about 6.5 posts per active twitter account per day.</p>
<p>I also looked at a longer time span of the last seven days. This allows me to get a break down by day to see the activity. As you can see, Sundays are pretty slow, then it picks up again on Monday. Presumably, as people return to work and are back in-front of the computer they get back to twittering. You can see the current stats at <a href="http://icelanders.optional.is/">http://icelanders.optional.is/</a></p>
<p>These stats are valuable information if you are trying to spread your message via social networks. Do you send it out on a Sunday where there is less traffic and it is more likely to be seen by fewer eyeballs or on Monday when more people are online, but there is a deluge of other tweets?</p>
<p><a href="http://carsonified.com/wp-content/uploads/2010/02/dcgxb64p_262hpggvfgp_b.png"><img class="aligncenter size-full wp-image-4608" title="dcgxb64p_262hpggvfgp_b" src="http://carsonified.com/wp-content/uploads/2010/02/dcgxb64p_262hpggvfgp_b.png" alt="" width="420" height="200" /></a></p>
<p>I also broke it down further into hour-by-hour slices. As you can see, the early morning hours from midnight until around 8am are pretty quiet. Still some activity, but not the time to expect someone to reply.</p>
<p><a href="http://carsonified.com/wp-content/uploads/2010/02/dcgxb64p_264drrt7cg3_b.png"><img class="aligncenter size-full wp-image-4609" title="dcgxb64p_264drrt7cg3_b" src="http://carsonified.com/wp-content/uploads/2010/02/dcgxb64p_264drrt7cg3_b.png" alt="" width="420" height="200" /></a></p>
<p>Once you are archiving a sub-set of twitter, it becomes possible to search this smaller list. Maybe the types of complains within the group vary greatly than with the general public. Are discussions staying within the niche group or are links and retweets getting outside of the core group? You can even find out how many people within this group are following each other and determine the level of interconnectedness.</p>
<p>Recently, I went through the database and using the Twitter API, found out when each person signed-up. I could then look to see if there was a growth spike or continual steady growth. It turns out there was a spike in early 2009.</p>
<p style="text-align: center;"><em>Click image to view large version</em></p>
<p style="text-align: center;"><a href="http://carsonified.com/wp-content/uploads/2010/02/twitter-trend-en-big.png"><img class="aligncenter size-full wp-image-4610" title="dcgxb64p_265g2x3jdcj_b" src="http://carsonified.com/wp-content/uploads/2010/02/dcgxb64p_265g2x3jdcj_b.png" alt="" width="470" height="213" /></a></p>
<p>Right around the time Twitter was being touted to the masses via Oprah, the major local newspaper joined and mentioned it a few times in print. These two, along with other factors really boosted the sign-ups from a few tens of people to several hundred a month! Even now, there is a solid 100+ new Icelanders coming to Twitter each month to see what it is all about.</p>
<p>Building something similar for your group allows you watch for spikes in discussion or sign-ups, look for trending topics within your community, engage in the discussion and find new friends.</p>
<img src="http://carsonified.com/?ak_action=api_record_view&id=4585&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://carsonified.com/blog/dev/finding-your-flock-in-twitter/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Bulletproof backups for MySQL</title>
		<link>http://carsonified.com/blog/dev/bulletproof-backups-for-mysql/</link>
		<comments>http://carsonified.com/blog/dev/bulletproof-backups-for-mysql/#comments</comments>
		<pubDate>Thu, 04 Feb 2010 13:27:08 +0000</pubDate>
		<dc:creator>Chris Lea</dc:creator>
				<category><![CDATA[Dev]]></category>

		<guid isPermaLink="false">http://carsonified.com/?p=4365</guid>
		<description><![CDATA[By <strong>Chris Lea</strong><br />You have all your important data backed up, right? I mean, come on folks, it&#8217;s 2010. We may not have flying cars yet like we&#8217;re supposed to, but &#8220;having backups&#8221; is a problem that&#8217;s solved. And I&#8217;m sure you&#8217;ve solved it. I&#8217;m sure you sleep well at night knowing that if a comet hit the [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style=""><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fcarsonified.com%2Fblog%2Fdev%2Fbulletproof-backups-for-mysql%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcarsonified.com%2Fblog%2Fdev%2Fbulletproof-backups-for-mysql%2F" height="61" width="51" /></a></div><p>You have all your important data backed up, right? I mean, come on folks, it&#8217;s 2010. We may not have flying cars yet like we&#8217;re supposed to, but &#8220;having backups&#8221; is a problem that&#8217;s solved. And I&#8217;m sure you&#8217;ve solved it. I&#8217;m sure you sleep well at night knowing that if a comet hit the data center where your website lives, and everything was completely destroyed, you could get back up and running somewhere else quickly enough.</p>
<p>Except that the chance this is actually true for you, statistically, is very small. If we look at the statistics, then what we see is that people are storing increasing amounts of things, important things even, online because disks keep getting bigger and cheaper (though sadly not much faster, but that&#8217;s a different article).</p>
<p>But despite this availability of cheap storage, people for the most part still don&#8217;t back things up. This isn&#8217;t universally true of course, there are <a title="Automattic" href="http://automattic.com" target="_blank">some folks</a> who have implemented really brilliant backup systems at their companies.</p>
<p>Of course, it helps when you have an <a title="Barry Abrahamson" href="http://barry.wordpress.com" target="_blank">amazing systems guy</a> on your team who is made out of lighting bolts and awesomeness, taking care of the nitty gritty details for you. If, however, you are one of the many many people who doesn&#8217;t have a good backup strategy in place, this article is here to help you out.</p>
<p>I&#8217;ve written a <a href="http://carsonified.com/wp-content/uploads/2010/02/db-backup.sh.txt" target="_blank">shell script</a> (<em>Ed: please remove .txt extension before use)</em> that will serve as a good starting point, and we&#8217;ll talk through it in a little bit. For now though, let&#8217;s discuss backups in a more general sense so we can decide what our end goals are.<span id="more-4365"></span></p>
<h3>Types of things to back up</h3>
<p>There are lots of different kinds of data that you may need to back up. Three of the most common are:</p>
<ol>
<li>Source Code</li>
<li>Static Files (images, PDFs, etc)</li>
<li>Data in a Database</li>
</ol>
<p>These days, there&#8217;s a good chance you have your source code files in an RCS system somewhere, such as <a title="GitHub" href="http://github.com" target="_blank">GitHub</a>. If you do (and you should), and your RCS system is on a different server or servers than your site, you already have your source code backed up. If your server catches on fire, you can just do a fresh checkout onto a new server. This is one of the <strong>many</strong> advantages of using an RCS system.</p>
<p>Static files, such as images or music or what have you, are easy to back up. A quick search will reveal dozens of different ways to ship this sort of data to some secondary place in case of emergency.</p>
<p>Database data, however, can be a little more tricky. You can&#8217;t just copy your binary data files safely while the database is running because if a write happens during the process, then your &#8220;backup&#8221; will be in an inconsistent state, which will probably render it useless.</p>
<p>Moreover, it&#8217;s not generally the best way to do a backup because restoring data from a binary copy can be tricky. What my shell script does is allow you to automate correctly backing up a standard MySQL database, or databases, with full end-to-end encryption to an offsite location.</p>
<h3>Is my data backed Up?</h3>
<p>This seems like an easy question to answer. In fact, it is a rather easy question to answer, but I&#8217;ve found that many people have never bothered to answer it, and it gets them in trouble. Are you doing backups of some sort currently? If so, does that mean you have backups? Actually, no, it doesn&#8217;t. If there is one golden rule of having backups that I hope you remember after reading this, it&#8217;s the following:</p>
<blockquote><p>If your backup procedure doesn&#8217;t include instructions for doing a restore of the data, or if your restoration procedure has not been tested, then you don&#8217;t have backups.</p></blockquote>
<p>Simply put, unless you <strong>know</strong> that you can reliably do a restoration of your data, you don&#8217;t have backups. If you haven&#8217;t tried, you don&#8217;t know. As an example, I once encountered a setup where an administrator was &#8220;backing up&#8221; several databases by using <tt>rsync</tt> to copy the binary data store to a remote machine once a day. He thought he had backups, and he was wrong.</p>
<p>As I noted before, if a write happens during the <tt>rsync</tt> process, those binary files aren&#8217;t guaranteed to be in a consistent state. If he&#8217;d ever tried to do a restore of those files (he hadn&#8217;t), he would have discovered this problem. So I say again, until you have tested a restore and it&#8217;s worked, and you&#8217;ve documented how to do that restore, you don&#8217;t have backups.</p>
<p>Another thing that I always like to stress is that you really, really want backups that are under as much personal control as possible. This typically means using a third party or offsite service distinct from your ISP to store your backups. If you ever need to restore some data, there&#8217;s a good chance it&#8217;s because something has gone wrong with your systems.</p>
<p>In that case, there&#8217;s also a fair chance that something has gone wrong at your ISP itself, so you&#8217;d rather not have your backups tied to your ISP. What you want is backups that are stored by some other company, preferably in an entirely different physical data center.</p>
<h3>Basic process for setting up database backups</h3>
<p>The steps I use to back up the databases for <a title="Virb" href="http://virb.com" target="_blank">Virb</a> are as follows:</p>
<ul>
<li>Get a dump of the database</li>
<li>Compress the data</li>
<li>Encrypt the data</li>
<li>Send the data over an encrypted connection to an offsite service</li>
<li>Automate the entire procedure with a cron job</li>
</ul>
<p>It&#8217;s nothing fancy, and it shouldn&#8217;t be. Fancy, intricate things tend to break, and this is the last thing you want to worry about breaking.</p>
<h3>Prerequisites</h3>
<p>You&#8217;ll need to have a few things in place for this to all work. I&#8217;m assuming you&#8217;re using a reasonably new Debian style Linux distribution (which includes Ubuntu). You need to be able to use the <tt>mysqldump</tt> program to get a dump of the desired database data. This comes standard with the MySQL installations on every Linux distribution I know of.</p>
<p>I&#8217;m going to assume that you have a <tt>.my.cnf</tt> file set up in your home directory with a username and password that allow you to dump out the data you want. If you&#8217;ve never used a <tt>.my.cnf</tt> file before, it&#8217;s very easy. Create a file called <tt>.my.cnf</tt> in your home directory, and put the following in it:</p>
<pre><code>[client]
user = dbusername
password = dbpassword</code></pre>
<p>of course substituting the correct username and password for your systems. Then run <tt>chmod 600 $HOME/.my.cnf</tt> on the file so other people can&#8217;t read it. You can now use all the <tt>mysql*</tt> command line utilities without having to pass the <tt>-u</tt> and <tt>-p</tt> flags all the time.</p>
<p>Another assumption I&#8217;m making here is that you can safely run <tt>mysqldump</tt> at some point during the day, and this won&#8217;t mess anything on your site up, which practically means that you don&#8217;t have <strong>that</strong> much data. When you dump the database out, a write lock is placed on all the tables in that database (assuming you&#8217;re dumping out all the tables). So while the data is getting written out, reads can still happen, but no INSERTS, UPDATEs or DELETEs can.</p>
<p>If you have say a few hundred megabytes of binary data, usually located in <tt>/var/lib/mysql</tt> on Linux systems, you are probably okay just dumping the data out from whatever machine the database is on. On reasonably modern hardware, 300M of binary data takes about 15 seconds to dump out, for example. Having a write lock for 15 seconds in the middle of the night is not a big deal for most people.</p>
<p>If you have enough data that it really does take a long time, or your requirements are such that you can&#8217;t have a write lock happen even briefly, then the next option is to set up a mysql slave server that exists just for backups. The idea is that the slave is continuously replicating from the master.</p>
<p>When you do the backup on the slave, the write lock will happen there so that the data can get dumped out, and then once it&#8217;s finished the replication will catch back up to the master if it&#8217;s missed anything.</p>
<p>Explaining how to <a title="MySQL replication documentation" href="http://dev.mysql.com/doc/refman/5.0/en/replication.html" target="_blank">set up MySQL replication</a> is beyond the scope of this article, but this &#8220;back up a slave&#8221; strategy is exactly what we do for Virb.</p>
<p>We&#8217;re going to be backing things up using the online back up service provided by <a title="IBackup" href="http://www.ibackup.com" target="_blank">IBackup</a>. There are plenty of these sorts of services available, so if you want to use a different one feel free. Not much of what I&#8217;m going to describe is specific to IBackup. I have no particular affiliation to them, other than having used them for several projects and being pleased with their products and pricing. I&#8217;m going to assume you have an Economy plan with enough storage to hold your backups.</p>
<p>The only other assumptions I&#8217;l make are that you have <tt>stunnel4</tt>, <tt>rsync</tt>, and <tt>gpg</tt> installed. These are very standard, freely available programs. On reasonably recent Debian style systems (which include Ubuntu) you can install all of them by running this command as root:</p>
<pre><code>apt-get update &amp;&amp; apt-get install stunnel4 rsync gnupg</code></pre>
<h3>Setting up encryption</h3>
<p>We are going to encrypt our database backups, and we&#8217;re going to transmit the encrypted files over a secure connection. This is technically overkill, but encryption is free and easy so we&#8217;ll do it anyway. The first thing you&#8217;ll need to do is generate GPG keys to use.</p>
<p>I&#8217;m not going to explain it here because <a href="http://www.madboa.com/geek/gpg-quickstart/" target="_blank">this tutorial</a> will take you all of five minutes to get through, and covers everything you&#8217;ll need. Just be sure to remember your passphrase, and put copies of your key files somewhere safe just in case.</p>
<p>You should now have GPG keys set up, and an account with IBackup, so create a file in your home directory called <tt>.ibackup</tt> with the following contents:</p>
<pre><code>IBACKUP_USERNAME=username
IBACKUP_PASSWORD=password
GPG_EMAIL=<a href="mailto:your@email.com" target="_blank">your@email.com</a></code></pre>
<p>The reason for this file will become apparent shortly. Just substitute the username and password for your IBackup account there, and put in the email address that was used to generate your GPG keys. Be sure to run <tt>chmod 600 $HOME/.ibackup</tt> so that nobody else can see your password.</p>
<p>Now we need to do a little configuration for <tt>stunnel4</tt>. We don&#8217;t need it to be running all the time, so shut it down and make sure it doesn&#8217;t start on boot with the following commands:</p>
<pre><code>/etc/init.d/stunnel4 stop
update-rc.d -f stunnel4 remove</code></pre>
<p>Now let&#8217;s configure <tt>stunnel4</tt> for IBackup. First get the default configuration file out of the way.</p>
<pre><code>cd /etc/stunnel
mv stunnel.conf stunnel.conf-orig</code></pre>
<p>Next, with your text editor of choice, create a file called <tt>ibackup.conf</tt> in the <tt>/etc/stunnel</tt> directory with the following contents:</p>
<pre><code>client = yes
[ibackup]
accept = 8455
connect = <a href="http://rsync4.ibackup.com:5000" target="_blank">rsync4.ibackup.com:5000</a></code></pre>
<p>These options are fairly specific to IBackup&#8217;s service, but other backup services have similar options. The <tt>accept</tt> option defines a local port for <tt>stunnel4</tt> to use, so you don&#8217;t have to pick that particular one if, for some reason, it&#8217;s already in use.</p>
<h3>Performing the backup</h3>
<p>Since we have our security issues handled, we can now perform the backup. Open up that <a href="http://carsonified.com/wp-content/uploads/2010/02/db-backup.sh.txt" target="_blank">shell script</a> (<em>Ed: please remove .txt extension before use)</em> I mentioned at the beginning in your text editor of choice, so we can go through it. The first 14 lines just get the names of databases we&#8217;re going to back up and identify the programs we&#8217;re going to use.</p>
<pre><code>#!/bin/bash

# <a href="http://ibackup.com" target="_blank">ibackup.com</a> destination
IBACKUP_DEST=$1

# database names
DB_NAMES=$2

# binaries we need
MYSQLDUMP=/usr/bin/mysqldump
GZIP=/bin/gzip
GPG=/usr/bin/gpg
RSYNC=/usr/bin/rsync
STUNNEL=/usr/bin/stunnel4</code></pre>
<p>If you&#8217;re not familiar with <tt>bash</tt> shell scripting, it&#8217;s not hard. Things like <tt>$1</tt> and <tt>$2</tt> indicate command line arguments that get passed to the script. So here, <tt>$1</tt> is something we&#8217;re going to use in the name of the eventual backup file we&#8217;ll get, and <tt>$2</tt> will hold the name(es) of the database(es) we will back up.</p>
<p>Things get more interesting from lines 23 to 39.</p>
<pre><code>DOTIBACKUP="$HOME/.ibackup"

if [ ! -r $DOTIBACKUP ]; then
    echo "Need $DOTIBACKUP file for username and password!"
    exit 1
else
    PERMS=`/bin/ls -l $DOTIBACKUP | /usr/bin/awk '{print $1}'`
fi

if [ $PERMS != "-rw-------" ]; then
    echo "Permissions on $DOTIBACKUP are wrong!"
    echo "Should be -rw-------, actually is $PERMS"
    exit 1
fi

. $DOTIBACKUP
export RSYNC_PASSWORD=$IBACKUP_PASSWORD</code></pre>
<p>These commands check that the <tt>.ibackup</tt> file exists and has the correct permissions. If so, they source the file, which is to say they absorb the things that file defines into the running shell script. Then it sets the environment variable <tt>RSYNC_PASSWORD</tt> to be the value of the <tt>IBACKUP_PASSWORD</tt> that you use to access the service.</p>
<p>Lines 41 and 42 grab the local port that <tt>stunnel4</tt> needs in order to work.</p>
<pre><code>
# local stunnel4 port
STUNNEL_PORT=`/bin/grep 'accept' /etc/stunnel/ibackup.conf | awk '{print $3}'`</code></pre>
<p>Next, between lines 44 and 49, we make make sure there&#8217;s a directory where we can dump out all of our data.</p>
<pre><code># place to dump everything
DUMPDIR="$HOME/.ibackup_data"

if [ ! -d $DUMPDIR ]; then
    mkdir $DUMPDIR
fi
</code></pre>
<p>We&#8217;re eventually going to set this up to run daily, and if we&#8217;re doing a once-per-day backup, it&#8217;s nice to keep a few days&#8217; worth around just in case. In lines 51 through 56 we use the very convenient *NIX <tt>date</tt> program to get date stamps for the current day, the previous day, and the day before that.</p>
<pre><code># today, for tagging the dumpfile
DATE=`/bin/date +%Y-%m-%d`

# yesterday, and the day before that
ONEDAYAGO=`/bin/date -d '1 day ago' +%Y-%m-%d`
TWODAYSAGO=`/bin/date -d '2 days ago' +%Y-%m-%d`</code></pre>
<p>We&#8217;re almost ready to actually dump out our data now. Lines 58 to 86 are really boring and just make sure we have a destination name and the programs we need, so I&#8217;ll gloss over those. The important part picks between lines 88 and 92, where we go into our backup directory and actually run <tt>mysqldump</tt>.</p>
<pre><code>cd $DUMPDIR

echo -n "dumping $DB_NAMES to $DUMPDIR/$IBACKUP_DEST-$DATE.mysql... "
$MYSQLDUMP --opt --databases $DB_NAMES &gt; $IBACKUP_DEST-$DATE.mysql
echo "done!"</code></pre>
<p>Let&#8217;s take a look at that dump command to make sure we understand it. The <tt>$DB_NAMES</tt> variable was set earler in the script. It&#8217;s the second command line argument passwed to the script, and it tells <tt>mysqldump</tt> which databases we care about. The <tt>$IBACKUP_DEST</tt> variable, similarly, was the first command line argument passed to the script, and it just sets the part of the name of our dump file. Finally, the <tt>$DATE</tt> variable we just saw getting set a moment ago, and we use it as a date stamp for this dump.</p>
<p>Next, between lines 94 and 105, we compress and encrypt our dump file. We also check to make sure the encryption step actually worked and we <tt>exit</tt> out if not.</p>
<pre><code>echo -n "gzipping $DUMPDIR/$IBACKUP_DEST-$DATE.mysql... "
$GZIP $DUMPDIR/$IBACKUP_DEST-$DATE.mysql
echo "done!"

echo -n "encrypting $DUMPDIR/$IBACKUP_DEST-$DATE.mysql... "
$GPG -e -r $GPG_EMAIL $DUMPDIR/$IBACKUP_DEST-$DATE.mysql.gz
echo "done!"

if [ $? -ne 0 ]; then
    echo "encryption failed!"
    exit 7
fi</code></pre>
<p>We do a little cleanup and start <tt>stunnel4</tt> in lines 107 to 112, which are pretty self explanatory.</p>
<pre><code>echo -n "removing $DUMPDIR/$IBACKUP_DEST-$DATE.mysql.gz... "
/bin/rm -fv $DUMPDIR/$IBACKUP_DEST-$DATE.mysql.gz
echo "done!"

echo "Starting stunnel for rsync..."
/etc/init.d/stunnel4 start</code></pre>
<p>And now on line 114, we finally send our freshly made backup off to the remote servers managed by IBackup for safe keeping.</p>
<pre><code>$RSYNC -r -v -z -t --delete-after --exclude $IBACKUP_DEST-$ONEDAYAGO* --exclude $IBACKUP_DEST-$TWODAYSAGO* $DUMPDIR/ $IBACKUP_USERNAME@localhost::ibackup/$IBACKUP_DEST --port $STUNNEL_PORT</code></pre>
<p>This is using several different features of <tt>rsync</tt> so let&#8217;s talk about them so we know what is going on. The command line flags <tt>-r -v -z -t</tt> are what the folks at IBackup <a href="http://www.ibackup.com/online-backup-faq/faqqrsync.htm#1" target="_blank">tell us to use</a> when syncing things over to them. The <tt>--delete-after</tt> flag tells <tt>rsync</tt> to delete anything in the target directory that&#8217;s not in the local directory being sync&#8217;d. But we also have the two <tt>--exclude</tt> options there.</p>
<p>So what we&#8217;re really saying is &#8220;Keep the file we&#8217;re sending over, and the one from yesterday, and the day before that, but then delete everything else&#8221;. That way we always have the last three days&#8217; worth of backups. The last point of interest is that because we tell <tt>rsync</tt> to use <tt>$STUNNEL_PORT</tt>, all the communication is encapsulated by <tt>stunnel4</tt> and is therefore encrypted across the wire as it gets transferred. Whew!</p>
<p>The last few lines from 116 to 121 simply stop <tt>stunnel4</tt> and clean up things by removing the directory we made to put the dump file into.</p>
<pre><code>echo "Stopping stunnel for rsync..."
/etc/init.d/stunnel4 stop

echo -n "Cleaning up... "
/bin/rm -rfv $DUMPDIR
echo "done!"</code></pre>
<p>So that <strong>should</strong> about do it. To find out, put this script somewhere and run <tt>chmod 755 db-backup.sh</tt> on it so it&#8217;s executable. Then test it to make sure it actually works. If you want the target to be called &#8216;mybackup&#8217;, and you have to back up the databases named &#8216;db1&#8242;, &#8216;db2&#8242;, and &#8216;db3&#8242;, you would invoke the script like this.</p>
<pre><code>/path/to/db-backup.sh mybackup "db1 db2 db3"
</code></pre>
<p>If that works, then you are almost done! We just need to automate the process, which we can do trivially with a <tt>cron</tt> job. In your shell where you tested the script from, type the following:</p>
<pre><code>crontab -e</code></pre>
<p>This will put you into edit mode for your crontab. Assuming you want the backup to happen starting at 12:40am each day, put the following into your crontab file:</p>
<pre><code>0 40 * * * /path/to/db-backup.sh mybackup "db1 db2 db3" &gt;/dev/null 2&gt;&amp;1</code></pre>
<p>Save the file, and then type <tt>crontab -l</tt> to list the crontab and make sure that line is in there. If it is, then there&#8217;s just one last thing to do.</p>
<h3>Testing a restore</h3>
<p>I said at the start of this article that if you haven&#8217;t done a restore, you don&#8217;t have backups. And seriously, I meant that. So if you&#8217;ve made it this far, then you must do one last step. The day after you set this up, you need to go to your IBackup account, download your dump file, decrypt it with the GPG key you made, and do a restore to a running MySQL instance.</p>
<p><strong>Make sure</strong> you do this last step, as the consequences of missing it can be dire.</p>
<h3>In conculsion</h3>
<p>I covered quite a bit in this article, but if you make it through everything, you should be able to rest easier knowing that you have good, safe backups of your database. Although we used the IBackup service in these examples, very little of what I covered is specific to them.</p>
<p>If you wanted to use a different company, or maybe just push the backup files to a different server you have, you&#8217;ll probably just need to change some of the commands that you pass to <tt>rsync</tt>. The basic strategy though should&#8217;t have to change.</p>
<p>I hope you&#8217;re found this helpful, and don&#8217;t hesitate to <a title="contact me" href="http://chrislea.com/contact/" target="_blank">get in touch</a> if you have any questions.</p>
<img src="http://carsonified.com/?ak_action=api_record_view&id=4365&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://carsonified.com/blog/dev/bulletproof-backups-for-mysql/feed/</wfw:commentRss>
		<slash:comments>24</slash:comments>
		</item>
		<item>
		<title>Doctype: CSS3 gradients and local databases in HTML5</title>
		<link>http://carsonified.com/blog/dev/doctype-css3-gradients-and-local-databases-in-html5/</link>
		<comments>http://carsonified.com/blog/dev/doctype-css3-gradients-and-local-databases-in-html5/#comments</comments>
		<pubDate>Tue, 02 Feb 2010 10:25:04 +0000</pubDate>
		<dc:creator>Keir Whitaker</dc:creator>
				<category><![CDATA[Dev]]></category>

		<guid isPermaLink="false">http://carsonified.com/?p=4342</guid>
		<description><![CDATA[By <strong>Keir Whitaker</strong><br />Editors note: Interested in web apps? Join us at the Future of Web Apps Miami on February 24th to learn more about HTML5 and hear from companies such as  Twitter, Facebook, Mint, Reddit and more. Buy your tickets now and get $50 off.
In this weeks 10 minute episode of Doctype Nick shows you how [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style=""><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fcarsonified.com%2Fblog%2Fdev%2Fdoctype-css3-gradients-and-local-databases-in-html5%2F"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fcarsonified.com%2Fblog%2Fdev%2Fdoctype-css3-gradients-and-local-databases-in-html5%2F" height="61" width="51" /></a></div><p><em><strong>Editors note:</strong> Interested in web apps? Join us at the Future of Web Apps Miami on February 24th to learn more about HTML5 and hear from companies such as  Twitter, Facebook, Mint, Reddit and more. <a href="../?utm_source=tv&amp;utm_medium=textlink&amp;utm_campaign=doctype_html5">Buy your tickets now and get $50 off</a>.</em></p>
<p>In this weeks 10 minute episode of <a href="http://doctype.tv/html5">Doctype</a> Nick shows you how to create gradients without images in CSS3, and Jim takes an in depth look at local databases in HTML5.</p>
<p><object id="viddler_91800b8f" classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="470" height="306" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="allowScriptAccess" value="always" /><param name="allowFullScreen" value="true" /><param name="src" value="http://www.viddler.com/player/91800b8f/" /><param name="name" value="viddler_91800b8f" /><param name="allowfullscreen" value="true" /><embed id="viddler_91800b8f" type="application/x-shockwave-flash" width="470" height="306" src="http://www.viddler.com/player/91800b8f/" name="viddler_91800b8f" allowfullscreen="true" allowscriptaccess="always"></embed></object></p>
<p>This is the last episode we of Doctype we will be syndicating on Think Vitamin. We hope you have enjoyed them and found them valuable.</p>
<img src="http://carsonified.com/?ak_action=api_record_view&id=4342&type=feed" alt="" />]]></content:encoded>
			<wfw:commentRss>http://carsonified.com/blog/dev/doctype-css3-gradients-and-local-databases-in-html5/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
