<?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/"
	>

<channel>
	<title>theChrisWalker.net</title>
	<atom:link href="http://thechriswalker.net/feed" rel="self" type="application/rss+xml" />
	<link>http://thechriswalker.net</link>
	<description>I'm sorry we're out of Cake. We only had 3 pieces and didn't expect the rush...</description>
	<pubDate>Thu, 11 Mar 2010 09:18:58 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Mongo &#8212; and the coolness of Document-Oriented Databases</title>
		<link>http://thechriswalker.net/2010-03/mongo-and-the-coolness-of-document-oriented-databases.html</link>
		<comments>http://thechriswalker.net/2010-03/mongo-and-the-coolness-of-document-oriented-databases.html#comments</comments>
		<pubDate>Tue, 09 Mar 2010 21:44:22 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
		
		<category><![CDATA[Code]]></category>

		<category><![CDATA[Databases]]></category>

		<category><![CDATA[MongoDB]]></category>

		<category><![CDATA[Rapid Application Development]]></category>

		<guid isPermaLink="false">http://thechriswalker.net/?p=173</guid>
		<description><![CDATA[I have been following a PHP Rapid Application Development Framework called Lithium with much interest (for other reasons which I fully intend to blog about later) and they are the ones I owe for turning me on to document oriented database systems. 
So what are they and why are they so cool, and what/who the [...]]]></description>
			<content:encoded><![CDATA[<p>I have been following a PHP Rapid Application Development Framework called <a href="http://lithify.me" title="The Most RAD PHP Framework: Lithium">Lithium</a> with much interest (for other reasons which I fully intend to blog about later) and they are the ones I owe for turning me on to document oriented database systems. </p>
<p>So what are they and why are they so cool, and what/who the hell is &#8220;Mongo&#8221;?</p>
<p>Let&#8217;s deal with the what first. &#8220;Traditional&#8221; database systems are Relational, they are characterised by strictly defined tables, strong relations between tables and their <a href="http://wikipedia.org/wiki/ACID" title="ACID on Wikipedia">ACID</a> compliance. It simple terms that means you say: </p>
<p><em>&#8220;I want a table of users and each one <strong>will</strong> have a first name, a last name and an email address, and each of those <strong>will</strong> be a &#8216;text&#8217; entry of a maximum of 255 characters&#8221;</em>.</p>
<p>If at a later date you want to add more info, then you have to go back and alter your table definition, give the old rows default values and fix any coding bugs that relied on the previous structure (not that you&#8217;d ever develop such a dependant application). Now the approach in a document oriented database is that you say:</p>
<p><em>&#8220;I want a table of users&#8221;</em></p>
<p>Then you can give each one whatever data you want. you may have one user with a name and address, another with a name and phone number only, a third might have a phone number and address but no first name. All these records can co-exist! That&#8217;s pretty different and I really didn&#8217;t know whether it was a good idea. So I played with <a href="http://mogodb.org/" title="MongoDB homepage">MongoDB</a>.</p>
<p>MongoDB is really cool. I installed it my laptop simply and fired up the shell to play. The syntax is very javascript-like, becasue it <em>is</em> javascript! So we can do this.</p>
<div class="codecolorer-container javascript mac-classic" ><div class="javascript codecolorer" style="font-family:inherit">MongoDB shell version<span class="sy0">:</span> 1.3.3<span class="sy0">-</span><br />
url<span class="sy0">:</span> test<br />
connecting to<span class="sy0">:</span> test<br />
type <span class="st0">&quot;help&quot;</span> <span class="kw1">for</span> help<br />
<span class="sy0">&gt;</span> db.<span class="me1">myFirstMongoDB</span>.<span class="me1">save</span><span class="br0">&#40;</span><span class="br0">&#123;</span>key<span class="sy0">:</span><span class="st0">&quot;value&quot;</span><span class="sy0">,</span> mixed<span class="sy0">:</span><span class="br0">&#91;</span><span class="st0">&quot;one&quot;</span><span class="sy0">,</span><span class="st0">&quot;two&quot;</span><span class="sy0">,</span><span class="st0">&quot;three&quot;</span><span class="br0">&#93;</span><span class="sy0">,</span> deep<span class="sy0">:</span><span class="br0">&#123;</span>has<span class="sy0">:</span><span class="br0">&#123;</span>another<span class="sy0">:</span><span class="st0">&quot;object&quot;</span><span class="br0">&#125;</span><span class="br0">&#125;</span><span class="br0">&#125;</span><span class="br0">&#41;</span><br />
ObjectId<span class="br0">&#40;</span><span class="st0">&quot;4b96b836ea70a136feb89c20&quot;</span><span class="br0">&#41;</span><br />
<span class="sy0">&gt;</span> db.<span class="me1">myFirstMongoDB</span>.<span class="me1">find</span><span class="br0">&#40;</span><span class="br0">&#41;</span><br />
<span class="br0">&#123;</span> <span class="st0">&quot;_id&quot;</span> <span class="sy0">:</span> ObjectId<span class="br0">&#40;</span><span class="st0">&quot;4b96b836ea70a136feb89c20&quot;</span><span class="br0">&#41;</span><span class="sy0">,</span> <span class="st0">&quot;key&quot;</span> <span class="sy0">:</span> <span class="st0">&quot;value&quot;</span><span class="sy0">,</span> &nbsp;<span class="st0">&quot;mixed&quot;</span> <span class="sy0">:</span> <span class="br0">&#91;</span> <span class="st0">&quot;one&quot;</span><span class="sy0">,</span> <span class="st0">&quot;two&quot;</span><span class="sy0">,</span> <span class="st0">&quot;three&quot;</span> <span class="br0">&#93;</span><span class="sy0">,</span> <br />
&nbsp; &nbsp;<span class="st0">&quot;deep&quot;</span> <span class="sy0">:</span> <span class="br0">&#123;</span> <span class="st0">&quot;has&quot;</span> <span class="sy0">:</span> <span class="br0">&#123;</span> <span class="st0">&quot;another&quot;</span> <span class="sy0">:</span> <span class="st0">&quot;object&quot;</span> <span class="br0">&#125;</span> <span class="br0">&#125;</span> <span class="br0">&#125;</span><br />
<span class="sy0">&gt;</span></div></div>
<p>Notice two amazing things here.</p>
<ol>
<li>We never created the table! we simply call <tt>db.myFirstMongoDB&#8230;</tt> which creates the &#8220;collection&#8221; (as they are called in the document oriented world). We certainly never defined a schema!</li>
<li>We passed an object with nested data. Not just simple fields! We can use this in a much more useful way in the next example</li>
</ol>
<p>So why might you want to do this. Consider a website with articles. Articles are written by a person, they are published on a date and the have content, tags, comments, view counts, trackbacks, and a proprietary rating system. If this where a relational database, we are looking at the following tables:</p>
<div class="codecolorer-container text mac-classic" ><div class="text codecolorer" style="font-family:inherit">articles: holds the article, date, person_id, view counts, proprietary rating<br />
people: holds the writers<br />
comments: the comments, related by article_id<br />
trackbacks: link back details<br />
ratings: the info for the proprietary system.<br />
tags: tag info<br />
tags_articles: a join table linking tags to the articles</div></div>
<p>Joining all that info together is not only complex, but can be a fair amount of load on the system. As more info wants to be added by the website owners changes become more complicated and difficult. However with Mongo I can hold the article in one collection like this:</p>
<p>[</p>
<div class="codecolorer-container javascript mac-classic" ><div class="javascript codecolorer" style="font-family:inherit"><span class="br0">&#123;</span> <br />
&nbsp; <span class="st0">&quot;published&quot;</span><span class="sy0">:</span> <span class="st0">&quot;2010-03-09 21:21:00&quot;</span><span class="sy0">,</span> <br />
&nbsp; <span class="st0">&quot;author&quot;</span><span class="sy0">:</span> <span class="br0">&#123;</span> <span class="st0">&quot;name&quot;</span><span class="sy0">:</span> <span class="st0">&quot;Chris Walker&quot;</span><span class="sy0">,</span> <span class="st0">&quot;profile&quot;</span><span class="sy0">:</span> <span class="st0">&quot;/profiles/chris-walker&quot;</span> <span class="br0">&#125;</span><span class="sy0">,</span><br />
&nbsp; <span class="st0">&quot;title&quot;</span><span class="sy0">:</span> <span class="st0">&quot;My amazing Article&quot;</span><span class="sy0">,</span><br />
&nbsp; <span class="st0">&quot;content&quot;</span><span class="sy0">:</span> <span class="st0">&quot;here's the text...&quot;</span><span class="sy0">,</span><br />
&nbsp; <span class="st0">&quot;tags&quot;</span><span class="sy0">:</span> <span class="br0">&#91;</span> <span class="st0">&quot;wonder&quot;</span><span class="sy0">,</span> <span class="st0">&quot;amazement&quot;</span><span class="sy0">,</span> <span class="st0">&quot;mongo&quot;</span><span class="sy0">,</span> <span class="st0">&quot;demo&quot;</span><span class="sy0">,</span> <span class="st0">&quot;chris&quot;</span> <span class="br0">&#93;</span><span class="sy0">,</span><br />
&nbsp; <span class="st0">&quot;comments&quot;</span><span class="sy0">:</span> <span class="br0">&#91;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span> <span class="st0">&quot;commenter&quot;</span><span class="sy0">:</span> <span class="st0">&quot;Rosie&quot;</span><span class="sy0">,</span> <span class="st0">&quot;comment&quot;</span><span class="sy0">:</span> <span class="st0">&quot;What is this?&quot;</span><span class="sy0">,</span> <span class="st0">&quot;when&quot;</span><span class="sy0">:</span> <span class="st0">&quot;2010-03-09 22:02:00&quot;</span> <span class="br0">&#125;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span> <span class="st0">&quot;commenter&quot;</span><span class="sy0">:</span> <span class="st0">&quot;Chris&quot;</span><span class="sy0">,</span> <span class="st0">&quot;url&quot;</span><span class="sy0">:</span> <span class="st0">&quot;http://thechriswalker.net/&quot;</span><span class="sy0">,</span> <span class="st0">&quot;comment&quot;</span><span class="sy0">:</span><span class="st0">&quot;it's class, that's what!&quot;</span><span class="sy0">,</span> <span class="st0">&quot;when&quot;</span><span class="sy0">:</span> <span class="st0">&quot;2010-03-09 23:12:00&quot;</span> <span class="br0">&#125;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span> <span class="st0">&quot;commenter&quot;</span><span class="sy0">:</span> <span class="st0">&quot;anonymous&quot;</span><span class="sy0">,</span> <span class="st0">&quot;comment&quot;</span><span class="sy0">:</span><span class="st0">&quot;I am your father.&quot;</span><span class="sy0">,</span> <span class="st0">&quot;when&quot;</span><span class="sy0">:</span> <span class="st0">&quot;2010-03-10 01:25:20&quot;</span> <span class="br0">&#125;</span><br />
&nbsp; <span class="br0">&#93;</span><span class="sy0">,</span><br />
&nbsp; rating<span class="sy0">:</span> <span class="br0">&#123;</span> stars<span class="sy0">:</span> <span class="nu0">5</span><span class="sy0">,</span> tagline<span class="sy0">:</span> <span class="st0">&quot;what a monster!&quot;</span> <span class="br0">&#125;</span><span class="sy0">,</span><br />
&nbsp; views<span class="sy0">:</span> <span class="nu0">1024</span><span class="sy0">,</span><br />
&nbsp; trackbacks<span class="sy0">:</span> <span class="br0">&#91;</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span> <span class="st0">&quot;url&quot;</span><span class="sy0">:</span> <span class="st0">&quot;http://some.blog/some/where&quot;</span><span class="sy0">,</span> <span class="st0">&quot;quote&quot;</span><span class="sy0">:</span> <span class="st0">&quot;the text for the link&quot;</span><span class="br0">&#125;</span><span class="sy0">,</span><br />
&nbsp; &nbsp; <span class="br0">&#123;</span> <span class="st0">&quot;url&quot;</span><span class="sy0">:</span> <span class="st0">&quot;http://some.other.blog/some/where/else&quot;</span><span class="sy0">,</span> <span class="st0">&quot;quote&quot;</span><span class="sy0">:</span> <span class="st0">&quot;the text they used to link here&quot;</span><span class="br0">&#125;</span><span class="sy0">,</span><br />
&nbsp; <span class="br0">&#93;</span><br />
<span class="br0">&#125;</span></div></div>
<p>So that might look like a more complex entity. It is, but you can search for values in sub-documents, you can filter results on existence of certain keys, and you can pull all this info one result. Your previous 7 tables and 8 joins, just became 1 collection and no joins. guess which is quicker?</p>
<p>Try to pull articles with a certain tag: &#8220;balls&#8221;? In SQL you&#8217;d be doing this:</p>
<div class="codecolorer-container sql mac-classic" ><div class="sql codecolorer" style="font-family:inherit"><span class="kw1">SELECT</span> <span class="st0">`article_id`</span> <span class="kw1">FROM</span> <span class="st0">`tags_articles`</span> <span class="st0">`ta`</span> <span class="kw1">JOIN</span> <span class="st0">`tags`</span> <span class="st0">`t`</span> <span class="kw1">ON</span> <span class="st0">`ta`</span><span class="sy0">.</span><span class="st0">`tag_id`</span> <span class="sy0">=</span> <span class="st0">`t`</span><span class="sy0">.</span><span class="st0">`id`</span> <span class="kw1">WHERE</span> <span class="st0">`t`</span><span class="sy0">.</span><span class="st0">`name`</span> <span class="sy0">=</span> <span class="st0">'balls'</span></div></div>
<p>And that would just get you the list of Id&#8217;s and you&#8217;d still need to get the info for each article. In Mongo with the collection we described above, you&#8217;d do:</p>
<div class="codecolorer-container javascript mac-classic" ><div class="javascript codecolorer" style="font-family:inherit">db.<span class="me1">articles</span>.<span class="me1">find</span><span class="br0">&#40;</span><span class="br0">&#123;</span> tags<span class="sy0">:</span> <span class="st0">&quot;balls&quot;</span><span class="br0">&#125;</span><span class="br0">&#41;</span></div></div>
<p>How much easier is that, and we&#8217;ve now got all the info, not just the &#8220;id&#8221;s! I was just amazed at how easy that is!</p>
<p>Of course this simplicity comes with a price, you lose the relational elements making tight relationships harder to work with. Also you some ease in aggregating things like &#8220;tags&#8221;, but MapReduce support makes this very efficient anyway.</p>
<p>In my next blog I&#8217;ll talk about Lithium, Mongo and how fast you can build a full blown web app with these tools.</p>
]]></content:encoded>
			<wfw:commentRss>http://thechriswalker.net/2010-03/mongo-and-the-coolness-of-document-oriented-databases.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>UPnP Wizardry</title>
		<link>http://thechriswalker.net/2010-01/upnp-wizardry.html</link>
		<comments>http://thechriswalker.net/2010-01/upnp-wizardry.html#comments</comments>
		<pubDate>Tue, 12 Jan 2010 15:18:37 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
		
		<category><![CDATA[Not Code]]></category>

		<category><![CDATA[Android]]></category>

		<category><![CDATA[UPnP]]></category>

		<category><![CDATA[xbox]]></category>

		<guid isPermaLink="false">http://thechriswalker.net/?p=167</guid>
		<description><![CDATA[You may notice an Xbox360 related theme in my current posts, as after getting one, most of my technology thought process is involved in something to do with it. Hence the Xbox Live Gamercard API I wrote about before. Now we get on to UPnP.
Universal Plug and Play is used for 2 mains things as [...]]]></description>
			<content:encoded><![CDATA[<p>You may notice an Xbox360 related theme in my current posts, as after getting one, most of my technology thought process is involved in something to do with it. Hence the <a href="http://thechriswalker.net/2009-12/xbox-live-gamercard-api.html">Xbox Live Gamercard API</a> I wrote about before. Now we get on to <a href="http://en.wikipedia.org/wiki/Universal_Plug_and_Play">UPnP</a>.</p>
<p>Universal Plug and Play is used for 2 mains things as far as I can tell.</p>
<ol>
<li>Dynamically opening holes in firewalls/NAT configurations for inbound connections to services. (<em>bad!</em></li>
<li>Media Discover/playback/control on a local network. (<em>good!</em>)</li>
</ol>
<p>The first is bad in my opinion. I don&#8217;t want the ability for some software behind my firewall to allow connections into my network. It might make some software function a little more smoothly, but if it&#8217;s that important that connections can be made inbound I would have set up a port-forward myself.</p>
<p>So I am only concerned with the second scenario.</p>
<p>The situation was that the Xbox360 can Stream Music/Pictures and Video from a <a href="www.xbox.com/PCsetup">Windows based PC</a>. Great, except if you haven&#8217;t got a windows based PC, or you have all your media on a fileserver running Ubuntu Server and don&#8217;t want to have to have another PC on just to stream to your Xbox360. So I did some digging and it turns out that the Xbox360 uses a &#8220;<em>standardised</em>&#8221; UPnP discovery protocol. I say &#8220;<em>standardised</em>&#8221; because it&#8217;s not quite compliant, but close enough.</p>
<p>I look at the options available and try <a href="http://ushare.geexbox.org/">uShare </a>first. It looks good, but the Xbox won&#8217;t see it and it can&#8217;t read the ID3 info from my music - rendering the whole thing useless.</p>
<p>Next <a href="http://www.twonkyvision.de/buy_server.html">TwonkyMediaServer</a>. I read somewhere that the linux demo doesn&#8217;t expire. I hope not, because it worked beautifully pretty much out of the box. The only gripe is that there&#8217;s no nice init scripts and I have to run a shell script every time I want to start/stop/status/restart it. But it read my media and the Xbox360 recognised it and I haven&#8217;t looked back.</p>
<p>So I thought, <em>Wow, this UPnP thing is pretty cool. but it must be more than this?</em>. So I booted up a Windows7 PC. I had had trouble with this machine because Windows Media Player didn&#8217;t like the fact that all my music was on a Read-Only SMB share. That and I hate the way the Windows won&#8217;t let you connect to different shares on the host with different credentials! How rubbish!</p>
<p>Still WMP12 didn&#8217;t like my read-only filesystem. However, with Twonky running on the network, all the music just &#8220;appeared&#8221; like magic in the &#8220;Other Libraries&#8221; section. nice.</p>
<p>Then I thought of another thing that had been annoying me. <em>Why can&#8217;t I stream media from my fileserver to my Android phone over Wifi?</em></p>
<p>Well, guess what? There&#8217;s an App for that!</p>
<p><a href="http://www.andromote.de/">Andromote</a> can connect to UPnP media servers and play back the content. Also, and this is quite cool, I can specifiy the media server as Twonky, specify the Media Renderer (i.e. what plays it) as my Windows7 PC, and use the Andromote App as the Control Point - allow full media browsing, playback, skipping, seeking and volume control of the PC from my phone. Pretty neat, eh?</p>
<p>The whole time, all the servers and renderers are auto-discovered, no configuration necessary. That&#8217;s pretty cool.</p>
<p>So in summary UPnP media is in 3 distinct parts and the best bit is that each part can be on a separate physical machine, or 2 on 1, or 1 each on 3 separate physical devices. Very flexible. The parts:</p>
<p><strong>Media Server</strong> &#8212; Serves the media - duh. i.e. media is physically stored (or accessed from) here.</p>
<p><strong>Media Renderer</strong> &#8212; Plays back the media - simples.</p>
<p><strong>Media Control Point</strong> &#8212; Controls the Media. Reads media info and tells the renderer what to play.</p>
<p>So the most common configuration is the server on one machine and the renderer and control point in another. That&#8217;s how the Xbox360 works.</p>
<p>So that was my experience into UPNP. I realise now that it was slightly unecessary as my old Xbox, running <a href="http://xbmc.org/">XBMC</a>, would have (<a href="http://xbmc.org/wiki/?title=UPnP_Sharing#Compatible_UPnP_ControlPoints_and_Media-Players_.28UPnP-clients.29">according to their wiki</a>) worked as the UPNP media server out of the box and is conencted to all my shares, and isn&#8217;t a hassle to turn on as it sits right next to my Xbox360. It&#8217;ll be my fallback if Twonky does expire&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://thechriswalker.net/2010-01/upnp-wizardry.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Xbox Live Gamercard API</title>
		<link>http://thechriswalker.net/2009-12/xbox-live-gamercard-api.html</link>
		<comments>http://thechriswalker.net/2009-12/xbox-live-gamercard-api.html#comments</comments>
		<pubDate>Thu, 31 Dec 2009 11:34:25 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
		
		<category><![CDATA[Code]]></category>

		<category><![CDATA[Google]]></category>

		<category><![CDATA[Javascript]]></category>

		<category><![CDATA[PHP]]></category>

		<category><![CDATA[Web]]></category>

		<category><![CDATA[xbox]]></category>

		<guid isPermaLink="false">http://thechriswalker.net/?p=155</guid>
		<description><![CDATA[So, got decided to join most of my friends and I got an Xbox 360. Me being me though, I got interested in the way that all the information about your &#8220;Gamertag&#8221; is stored an accessible on the xbox.com website. Wouldn&#8217;t it be fun to do something with this data!
As it turns out, I was [...]]]></description>
			<content:encoded><![CDATA[<p>So, got decided to join most of my friends and I got an Xbox 360. Me being me though, I got interested in the way that all the information about your &#8220;Gamertag&#8221; is stored an accessible on the xbox.com website. Wouldn&#8217;t it be fun to do something with this data!</p>
<p>As it turns out, I was beaten to the post by Duncan MacKensie (<a href="http://duncanmackenzie.net/Blog/put-up-a-rest-api-for-xbox-gamertag-data">http://duncanmackenzie.net/Blog/put-up-a-rest-api-for-xbox-gamertag-data</a>) who hosts a webservice to retrieve gamer data from Microsoft. <del datetime="2009-12-31T11:41:44+00:00"> I could find <strong>no</strong> details about how this service works, where the data comes from or anything! Either he has a relationship with Microsoft, or he scrapes xbox.com but either way, the data seems pretty consistent and reliable.</del> <em>Actually it turns out this information was right there on his website&#8230; <a href="http://www.duncanmackenzie.net/Blog/if-you-are-wondering-where-i-get-my-xbox-live-info">http://www.duncanmackenzie.net/Blog/if-you-are-wondering-where-i-get-my-xbox-live-info</a> So he gets it as part of his membership to the Xbox Community Developer Program.</em></p>
<p>However, the webservice is great, and returns XML which is fine, but I thought it would be more useful to me to have a PHP API for this data. So I wrote one which retrieves data from Duncans webservice.</p>
<p>Then I thought wouldn&#8217;t it be great to be able to use this dynamically in a webpage, so I wrote a service frontend which will return JSON formatted data. Then I thought wouldn&#8217;t it be useful to let other people use this as well, so I modified it and it can now cope with JSONP requests with a &#8220;_callback&#8221; parameter.</p>
<p>OK, so what does this all mean.</p>
<p><strong>The PHP</strong></p>
<p>The class is called gamertag and the usage is very simple:</p>
<div class="codecolorer-container php mac-classic" ><div class="php codecolorer" style="font-family:inherit"><span class="kw2">&lt;?php</span><br />
<span class="co1">// include the class file</span><br />
<span class="kw1">require</span> <span class="st0">&quot;gamertag.php&quot;</span><span class="sy0">;</span><br />
<br />
<span class="co1">//instantiate</span><br />
<span class="re0">$G</span> <span class="sy0">=</span> <span class="kw2">new</span> Gamertag<span class="br0">&#40;</span><span class="st_h">'thechriswalker'</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
<span class="co1">//get data</span><br />
<span class="re0">$data</span> <span class="sy0">=</span> <span class="re0">$G</span><span class="sy0">-&gt;</span><span class="me1">getArray</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="sy0">;</span><br />
<br />
<span class="kw3">print_r</span><span class="br0">&#40;</span><span class="re0">$G</span><span class="br0">&#41;</span><span class="sy0">;</span></div></div>
<p>which outputs something like this:</p>
<pre class='code'>Array
(
    [Gamertag] => thechriswalker
    [AccountStatus] => Silver
    [State] => Valid
    [ProfileUrl] => http://live.xbox.com/member/thechriswalker
    [TileUrl] => http://avatar.xboxlive.com/avatar/thechriswalker/avatarpic-l.png
    [AvatarFullUrl] => http://avatar.xboxlive.com/avatar/thechriswalker/avatar-body.png
    [Country] => United Kingdom
    [Location] => Bradninch
    [Bio] =>
    [Reputation] => 58.72229
    [ReputationImageUrl] => http://live.xbox.com/xweb/lib/images/gc_repstars_external_12.gif
    [Zone] => Recreation
    [GamerScore] => 230
    [PresenceInfo] => Array
        (
            [Valid] => true
            [Info] => Last seen 12/29/09   playing Modern Warfare® 2
            [Info2] =>
            [LastSeen] => Tue, 29 Dec 2009 21:35:22 +0000
            [Online] => false
            [StatusText] => Offline
            [Title] => Modern Warfare® 2
        )

    [RecentGames] => Array
        (
            [0] => Array
                (
                    [Name] => Modern Warfare® 2
                    [TotalAchievements] => 50
                    [TotalGamerScore] => 1000
                    [Image32Url] => http://tiles.xbox.com/tiles/Z+/tF/12dsb2JgbA9ECgQJGgYfVl5UL2ljb24vMC84MDAwIAABAAAAAPhq63g=.jpg
                    [Image64Url] => http://tiles.xbox.com/tiles/CE/Vx/0Gdsb2JhbC9ECgQJGgYfVl5UL2ljb24vMC84MDAwAAAAAAAAAP9eRRc=.jpg
                    [LastPlayed] => Tue, 29 Dec 2009 21:32:52 +0000
                    [Achievements] => 9
                    [GamerScore] => 115
                    [DetailsURL] => http://live.xbox.com/en-US/profile/Achievements/ViewAchievementDetails.aspx?tid=%09%5d%3a%60m%2fl%3b%7cw&amp;compareTo=thechriswalker
                )

            [1] => Array
                (
                    [Name] => PGR 4
                    [TotalAchievements] => 60
                    [TotalGamerScore] => 1250
                    [Image32Url] => http://tiles.xbox.com/tiles/Y1/qn/0Gdsb2JgbA9ECgR8GgMfWSlaL2ljb24vMC84MDAwIAABAAAAAP+IWnw=.jpg
                    [Image64Url] => http://tiles.xbox.com/tiles/DP/ST/12dsb2JhbC9ECgR8GgMfWSlaL2ljb24vMC84MDAwAAAAAAAAAPi89BM=.jpg
                    [LastPlayed] => Mon, 28 Dec 2009 16:59:25 +0000
                    [Achievements] => 5
                    [GamerScore] => 115
                    [DetailsURL] => http://live.xbox.com/en-US/profile/Achievements/ViewAchievementDetails.aspx?tid=%09%5d%3a%15%18*iAq%0b&amp;compareTo=thechriswalker
                )

        )

)</pre>
<p>So now we can easily get at the data. The source code for the class (which is not fully tested, but the basics work!) is at <a href="http://thechriswalker.net/xbox360/gamertag.source.php">http://thechriswalker.net/xbox360/gamertag.source.php</a> (NB it requires either PHP5 (for json_encode) or the PEAR Services_JSON class if you want to use the &#8220;getJSON()&#8221; method).</p>
<p><strong>The JSON</strong></p>
<p>PHP is well and good but what if I want to use a JSON/JSONP (JSONP is for cross-domain information requesting and is very useful for public information services, see http://en.wikipedia.org/wiki/JSON#JSONP) request, well, that can be done at <a href="http://thechriswalker.net/xbox360/?gamertag=YOUR_GAMERTAG">http://thechriswalker.net/xbox360/?gamertag=YOUR_GAMERTAG</a> for the straight JSON or <a href="http://thechriswalker.net/xbox360/?gamertag=YOUR_GAMERTAG&#038;_callback=YOUR_CALLBACK_FUNCTION_NAME"> http://thechriswalker.net/xbox360/?gamertag=YOUR_GAMERTAG&#038;_callback=YOUR_CALLBACK_FUNCTION_NAME</a> for JSONP.</p>
<p>The first returns just JSON with a content type &#8220;application/json&#8221; and the second returns a javascript function call to your callback function with the JSON object as the only parameter and a content type of &#8220;text/javascript&#8221;.</p>
<p>These enabled me to build a simple Google Gadget to display a Gamercard:</p>
<p><center><br />
<script src="http://www.gmodules.com/ig/ifr?url=http://thechriswalker.net/xbox360/xblgamercard.xml&amp;up_gamertag=thechriswalker&amp;synd=open&amp;w=600&amp;h=200&amp;title=Xbox+Live+Gamertag+Info+for+%22chriswalker%22&amp;border=%23ffffff%7C3px%2C1px+solid+%23999999&amp;output=js"></script></center></p>
]]></content:encoded>
			<wfw:commentRss>http://thechriswalker.net/2009-12/xbox-live-gamercard-api.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>ZFS-FUSE and OpenSolaris and why Google Groups are such a good resource&#8230;</title>
		<link>http://thechriswalker.net/2009-09/zfs-fuse-and-opensolaris-and-why-google-groups-are-such-a-good-resource.html</link>
		<comments>http://thechriswalker.net/2009-09/zfs-fuse-and-opensolaris-and-why-google-groups-are-such-a-good-resource.html#comments</comments>
		<pubDate>Thu, 03 Sep 2009 10:21:22 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
		
		<category><![CDATA[Not Code]]></category>

		<category><![CDATA[fileserver]]></category>

		<category><![CDATA[Solaris]]></category>

		<category><![CDATA[ZFS]]></category>

		<guid isPermaLink="false">http://thechriswalker.net/?p=150</guid>
		<description><![CDATA[As my last post said, I&#8217;m using ZFS and love the way it works, but am having trouble with the performance of ZFS-FUSE. It&#8217;s not unusable, I just expected more.
So I thought, OpenSolaris. It&#8217;s the original implementation of the filesystem it must be great, so I export my zpools and boot from the LiveCD (another [...]]]></description>
			<content:encoded><![CDATA[<p>As my <a href='http://thechriswalker.net/2009-08/why-didnt-i-know-about-zfs-before.html'>last post</a> said, I&#8217;m using ZFS and love the way it works, but am having trouble with the performance of ZFS-FUSE. It&#8217;s not unusable, I just expected more.</p>
<p>So I thought, OpenSolaris. It&#8217;s the original implementation of the filesystem it must be great, so I export my zpools and boot from the LiveCD (another great reason to try it).</p>
<p>However it wasn&#8217;t going to be that easy&#8230; When I try to import my zpools in Solaris I get errors stating the vdev&#8217;s are corrupt! Something like:</p>
<blockquote><p>status: One or more devices contains corrupted data.<br />
action: The pool cannot be imported due to damaged devices or data.</p></blockquote>
<p>Scared I boot back to linux to find they are all fine.</p>
<p>Back to Solaris and they still look corrupt. So I search and find <a href='http://groups.google.com/group/zfs-fuse/browse_thread/thread/0fe4c06dad476d0d#'>this</a> on the ZFS-FUSE Google Group.</p>
<p>Sun claims best practice is to use an entire disk when assigning disks to vdevs, rather than just partitions. So that&#8217;s what I did in linux. However the Linux implementation differs form the Solaris one and whole disks added in Solaris get a single partition first and that is added to the vdev.</p>
<p>Great! Now I have these zpools I can&#8217;t use anywhere else. To test I used a pool I set up as a mirror and detached a vdev (one disk). I then repartitioned the disk to have one big partition and also wiped the ZFS pool info from it (easier said than done! <a href='http://techarcana.net/2009/02/19/stubbornly-persistent-zfs-pools/'>Ghost pools seem to be a problem!</a>). Then I re-inserted the new partition into the the zpool and waited for resilver. Then I did the same with the other drive, detach from pool, partition, attach partition and resilver.</p>
<p>Bingo. It works in Solaris! Now I just have to find a spare 750Gb disk so I can do the same for my JBOD style zpool&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://thechriswalker.net/2009-09/zfs-fuse-and-opensolaris-and-why-google-groups-are-such-a-good-resource.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Why didn&#8217;t I know about ZFS before?</title>
		<link>http://thechriswalker.net/2009-08/why-didnt-i-know-about-zfs-before.html</link>
		<comments>http://thechriswalker.net/2009-08/why-didnt-i-know-about-zfs-before.html#comments</comments>
		<pubDate>Thu, 06 Aug 2009 09:31:11 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
		
		<category><![CDATA[Not Code]]></category>

		<category><![CDATA[fileserver]]></category>

		<category><![CDATA[Solaris]]></category>

		<category><![CDATA[ZFS]]></category>

		<guid isPermaLink="false">http://thechriswalker.net/?p=141</guid>
		<description><![CDATA[I have a fileserver at home. I have done for many years now. The first incarnation was based on Fedora Core 3 (which will tell you *exactly* how long ago that was&#8230;) and was very simple. I had an old Xbox HDD (8GB Seagate) and 2 shiny new 200GB Western Digiatl drives for storage.
This was [...]]]></description>
			<content:encoded><![CDATA[<p>I have a fileserver at home. I have done for many years now. The first incarnation was based on Fedora Core 3 (which will tell you *exactly* how long ago that was&#8230;) and was very simple. I had an old Xbox HDD (8GB Seagate) and 2 shiny new 200GB Western Digiatl drives for storage.</p>
<p>This was also my first major experience with Linux as a whole, so I was trying to keep things simple. So I did a default type install, with LVM on the 2&#215;200GB disks to give one logical 400GB partition.</p>
<p>All was fine and dandy until I wanted to upgrade a couple of years later and not knowing much about LVM, wiped all my data. Yes, ALL my data. I had some important stuff backed up, but a lot of non-critical but frustrating to lose data (many GBs of painstakingly ripped and encoded CDs and Audiobooks for example). </p>
<p>I was gutted, and vowed not to use LVM again (note my solution to my mistake and lack of knowledge - never use the software again! Well thought out!). So I rebuilt the server using CentOS 4.x ( I can&#8217;t remember&#8230;) and added another 250GB disk. This time I kept each disk seperate with it&#8217;s own filesystem.</p>
<p>This worked fine for ages until the disks were nearly full and I spent all my time moving data from one disk to another to gain a few GBs extra on another disk. Nightmare.</p>
<p>So I decided it was time to start again and did some research into the available filesystems people use for fileservers, how software RAID can be implemented and so on. In this time I came across ZFS and I couldn&#8217;t believe what it could do. It seemed to good to be true. I now know this to be false and it can&#8217;t do everything, but it can do an awful lot!</p>
<p>So how can I use ZFS? Well, if you use any Solaris variant, then you probably already are. Otherwise chances are slim that you&#8217;ve encountered it. I didn&#8217;t really want to go down the OpenSolaris route, but instead stick to Linux where I&#8217;m more comfortable. This poses issues, as the licencing behind ZFS from Sun doesn&#8217;t fit with GPL, so no kernel support for ZFS. Instead someone (I&#8217;d love to reference but I forget his name, google will surely help - <a href="http://google.com/search?q=ZFS+FUSE">http://google.com/search?q=ZFS+FUSE</a>) has ported ZFS to FUSE which is great except for the massive memory usage and the poor performance. </p>
<p>Those actually sound like quite big issues! Well, the memory thing is not so bad as it seems. ZFS is not memory instense (well, actually it constantly uses about 256Mb so it&#8217;s not light) but uses available memory cache to store data in case it needs it again. A good idea, as the memory is otherwise just doing nothing! The Performance is pretty poor though. It&#8217;s enough for my network and to stream music, pictures and video over my network. But single file transfer never hits much more than 8Mb/s read or write.</p>
<p>Now I&#8217;m interested in trying some of the other OS options, as ZFS is easy to &#8220;export&#8221; from one OS and &#8220;import&#8221; into another. What are the options?</p>
<ul>
<li><strong>Option 1: OpenSolaris &ndash;</strong> Seems like a good idea. The native platform, has a good AMP stack so should be fine for my needs. Have heard some stability issues, but not so much with ZFS, but the OS itself.</li>
<li><strong>Option 2: Nextenta &ndash;</strong> Solaris Kernel with GNU userland. Supposed to be a good happy medium, sounds too much like a compromise to me&#8230;</li>
<li><strong>Option 3: BTRFS &ndash;</strong> different route totally but a new filesystem designed not to mirror ZFS, but to take the best of everything it can. Some aspects very like ZFS. Very promising project, but too young.</li>
</ul>
<p>Kinda only leaves OpenSolaris&#8230; I&#8217;ll let you know how I get on.</p>
]]></content:encoded>
			<wfw:commentRss>http://thechriswalker.net/2009-08/why-didnt-i-know-about-zfs-before.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>What people misunderstand about Google Wave</title>
		<link>http://thechriswalker.net/2009-06/what-people-misunderstand-about-google-wave.html</link>
		<comments>http://thechriswalker.net/2009-06/what-people-misunderstand-about-google-wave.html#comments</comments>
		<pubDate>Wed, 10 Jun 2009 09:34:18 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
		
		<category><![CDATA[Not Code]]></category>

		<category><![CDATA[Google]]></category>

		<category><![CDATA[Wave]]></category>

		<guid isPermaLink="false">http://thechriswalker.net/?p=136</guid>
		<description><![CDATA[I had heard about Google Wave, had a quick look at their UI, thought &#8220;shiny&#8221; and not really paid it much attention. Then I was reminded of it again recently and so I had another look, watched the Keynote Speech that they gave at the Google I/O 2009 and had a bit of a look [...]]]></description>
			<content:encoded><![CDATA[<p>I had heard about Google Wave, had a quick look at their UI, thought &#8220;shiny&#8221; and not really paid it much attention. Then I was reminded of it again recently and so I had another look, watched the Keynote Speech that they gave at the Google I/O 2009 and had a bit of a look around the web for related articles.</p>
<p>And I got really excited and really angry.</p>
<p>I got angry, because most people weren&#8217;t excited for the right reasons, or were dismissive / &#8220;anti&#8221; because they didn&#8217;t really see what Google has done.</p>
<p>But because I am so excited about Wave (not just Google Wave), I thought I&#8217;d post this to help you understand what Google Wave actually is and what it isn&#8217;t.</p>
<h3>What Google Wave isn&#8217;t</h3>
<p><strong>Google Wave isn&#8217;t Wave.</strong></p>
<p><em>Wait a second! Why have you dropped the &#8220;Google&#8221;, what&#8217;s &#8220;Wave&#8221; all about?</em></p>
<p>Firstly let&#8217;s take an analogy, with something you are no doubt familiar with. Consider the statement: </p>
<blockquote><p>Google Mail is not email.</p></blockquote>
<p>Imagine that email didn&#8217;t exist and Google showcased Google Mail. People might think that email <strong>was</strong> Google Mail, but we all know that isn&#8217;t the case. </p>
<p>The same for Wave. Google have designed a messaging system which can be run by anyone. They have designed the protocols it will use which anyone can implement. This messaging system is not Google Wave, but Wave itself.</p>
<h3>What Google Wave is</h3>
<p>Google have designed a UI for Wave, which is Google Wave. </p>
<p>Don&#8217;t get me wrong, I like their interface. It is written in HTML5 using the Google Web Toolkit and it is super slick. </p>
<p>However, the Wave itself is far more exciting.</p>
<h3>What Wave is</h3>
<p>Wave is email redesigned for the 21st century. Email was born before the internet and has been flogged and flogged into how we use it now. It is inefficient, single one-way message based, bad with files, incosistent with rich styling, non-collaborative and basically just way past it&#8217;s &#8220;sell by date&#8221;. </p>
<p>With Wave we no longer deal in single messages, but conversations; where content evolves over time and can be &#8220;played back&#8221; to provide the user with context. Everything email and IM can do and more. They have designed the system to be extensible and so can communicate with other systems. They also designed it to work over a federated networks model, so many people running their own Wave servers can communicate in the same rich way as if they were communicating with their people on their own server.</p>
<p>Amazing really, and provided we can bridge the backwards compatibility gap<sup><a id='footnote-1-link' href='#footnote-1' title='go to footnote'>*</a></sup> (which we can, remember Wave is extensible!) then I see Wave replacing email altogether.</p>
<p>When Google Wave goes live, Google will also be releasing the server for anyone to run, learn, enjoy and stop using email with. I am looking forward it immensely. </p>
<p><strong><a href='#footnote-1-link' id='footnote-1' title='return to text'>[update 2009-08-06]</a></strong> Further developments have shown that yes &#8220;gateways&#8221; have been designed in, so Wave can replace email and any other messaging/collaboration protocols/tools if someone creates a &#8220;gateway&#8221; for it.</p>
]]></content:encoded>
			<wfw:commentRss>http://thechriswalker.net/2009-06/what-people-misunderstand-about-google-wave.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Fantastic Contraption</title>
		<link>http://thechriswalker.net/2009-03/fantastic-contraption.html</link>
		<comments>http://thechriswalker.net/2009-03/fantastic-contraption.html#comments</comments>
		<pubDate>Sun, 29 Mar 2009 22:14:29 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
		
		<category><![CDATA[Not Code]]></category>

		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://thechriswalker.net/?p=132</guid>
		<description><![CDATA[Oh my god. I can&#8217;t believe how addictive this game is. http://fantasticcontraption.com/. The simplicity of it really appeals to me. The idea is to move a pink block from one area on the course to another, and you do so by building a contraption from wheels and connectors. that&#8217;s pretty much it!
Doesn&#8217;t sound like much, [...]]]></description>
			<content:encoded><![CDATA[<p>Oh my god. I can&#8217;t believe how addictive this game is. http://fantasticcontraption.com/. The simplicity of it really appeals to me. The idea is to move a pink block from one area on the course to another, and you do so by building a contraption from wheels and connectors. that&#8217;s pretty much it!</p>
<p>Doesn&#8217;t sound like much, but if you are like me, you&#8217;ll not only want to finish all the levels but also go back and experiment with loads of other different ways to finish in the vain hope of finding the perfect solution. A solution that excels by being so simple, or so elegant. So unusual, or so complex. I could play for hours. But I won&#8217;t go on for hours.</p>
<p>I will leave you with some of the best contraptions I have managed to come up with, and the first one you should really vote as amazing, because (and I know this sounds a bit arrogant) is ingenious!</p>
<ul>
<li><a href='http://FantasticContraption.com/?designId=7000201'>unusual technique!</a> See if you can guess how it works before you start it!</li>
<li><a href='http://FantasticContraption.com/?designId=7001467'>Minimalistic elegance, perfect timing.</a></li>
<li><a href='http://FantasticContraption.com/?designId=6999805'>I saw a solution with more than one spinny thing, but this seemed a cooler solution (notice the pole to slow down the last ball slightly&#8230;)</a></li>
<li><a href='http://FantasticContraption.com/?designId=6981893'>A cool way to do &#8220;The Ball&#8221;</a></li>
</ul>
<p>That&#8217;s all for the moment, but I&#8217;m sure I&#8217;ll post more contraptions in the future&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://thechriswalker.net/2009-03/fantastic-contraption.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>More WebKit Goodies - CSS Transforms and Transitions - the OSX Dock example</title>
		<link>http://thechriswalker.net/2009-03/more-webkit-goodies-css-transforms-and-transitions-the-osx-dock-example.html</link>
		<comments>http://thechriswalker.net/2009-03/more-webkit-goodies-css-transforms-and-transitions-the-osx-dock-example.html#comments</comments>
		<pubDate>Thu, 12 Mar 2009 19:44:22 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
		
		<category><![CDATA[Code]]></category>

		<category><![CDATA[CSS]]></category>

		<category><![CDATA[WebKit]]></category>

		<guid isPermaLink="false">http://thechriswalker.net/?p=98</guid>
		<description><![CDATA[As promised last time, I here we will discuss the transforms in WebKit, and how they can be used to create interactive applications without Javascript (for animation that is &#8211; we still need it for AJAX, etc.)
Tranforms have been implemented on a few browser using proprietary syntax, and the same is true of WebKit. As [...]]]></description>
			<content:encoded><![CDATA[<p>As promised last time, I here we will discuss the transforms in WebKit, and how they can be used to create interactive applications without Javascript (for animation that is &ndash; we still need it for AJAX, etc.)</p>
<p>Tranforms have been implemented on a few browser using proprietary syntax, and the same is true of WebKit. As we shall see further down the article though, the WebKit transitions make them so much more powerful.</p>
<p>But what are they? They modify an element, without displacing it&#8217;s original setting within the document, which means we can move it about and the spacing doesn&#8217;t change. </p>
<style type='text/css'>
.flip:hover { -webkit-transform:rotate(180deg); }
.transition { -webkit-transition:-webkit-transform 1s linear }
.transition-allover, .transition-left { -webkit-transform-origin:30% 50%;-webkit-transition:-webkit-transform 1s linear; }
.transition-left:hover {
 -webkit-transform:rotate(180deg);
 -webkit-transform-origin:30% 50%; 
}
.transition-allover:hover {
  -webkit-transform: rotate(180deg) scale(1.5) translate(-50%, 50%);
  -webkit-transform-origin:30% 50%; 
}
#hey-look-at-me:target pre {
  outline:2px solid red;
  color:#f0f;
}
#hey-look-at-me pre{
  -webkit-transition-property:outline, color;
  -webkit-transition-duration:500ms;
}
</style>
<blockquote style='color:#c00;'><p>Remember these will only work in WebKit based browsers, for example Safari for Mac, Chrome for Windows or Midori for Linux</p></blockquote>
<p>An example: how about rotation.</p>
<pre class='code flip'>element:hover {
  -webkit-transform:rotate(180deg);
}</pre>
<p>Not very exciting, but combine this with a transition! (Try putting you mouse in the middle of the box for best effect)</p>
<pre class='code flip transition'>element:hover {
  -webkit-transform:rotate(180deg);
}
element {
  -webkit-transition:-webkit-transform 1s linear
}</pre>
<p>Much more useful! But there&#8217;s more, we can scale, we can translate (change its position on the screen)  and also we can change the &#8220;center&#8221; for the transform. Usually the rotation happens from the center like above, but we could do it from closer to the left:</p>
<pre class='code transition-left'>element:hover {
  -webkit-transform:rotate(180deg);
  -webkit-transform-origin:30% 50%;
}
element {
  -webkit-transition:-webkit-transform 1s linear;
  -webkit-transform-origin:30% 50%;
}</pre>
<p>Or we could scale and move and rotate! (you might need to track it with you mouse to keep the animation! this is a demo after all!)</p>
<pre class='code transition-allover'>element:hover {
  -webkit-transform:rotate(180deg) scale(2) translate(-100%,0);
  -webkit-transform-origin:30% 50%;
}
element {
  -webkit-transition:-webkit-transform 1s linear;
  -webkit-transform-origin:30% 50%;
}</pre>
<div id='hey-look-at-me'>
<div id='untarget'>
<p>As the above eaxmple showed, hover is not always the best trigger for this. So lets use the <tt>:target</tt> pseudo-class. This is the pseudo-class that is applied when the element is the &#8216;target&#8217; of an anchor/url hash. e.g:</p>
<pre class='code'>&lt;div id='hey-look-at-me'&gt; &lt;div id='untarget'&gt; &lt;pre&gt;
CSS:
#hey-look-at-me:target pre {
  outline:2px solid red;
  color:#f0f;
}
#hey-look-at-me pre {
  -webkit-transition-property:outline, color;
  -webkit-transition-duration:500ms;
}
&lt;/pre&gt; &lt;/div&gt; &lt;/div&gt;

<a href='#hey-look-at-me'>target me!</a> <a href='#untarget'>untarget me!</a>
</pre>
</div>
</div>
<p><strong>NB:</strong> Notice how I nested the <tt>PRE</tt> to stop unwanted excessive screen movement.</p>
<p>So, what can we do with all this? Well, the culmination of the post, the Mac OSX style Dock menu, using no Javascript. Yes, that&#8217;s right a bulging docked menu, with no javascript.</p>
<p>Just so you remember, there <strong>no javascript</strong> in the demo.</p>
<p>Check out the <a href='/osx-dock'>Javascript free OSX Dock Menu Demo</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://thechriswalker.net/2009-03/more-webkit-goodies-css-transforms-and-transitions-the-osx-dock-example.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Webkit CSS Transitions - pretty cool stuff</title>
		<link>http://thechriswalker.net/2009-03/webkit-css-transitions-pretty-cool-stuff.html</link>
		<comments>http://thechriswalker.net/2009-03/webkit-css-transitions-pretty-cool-stuff.html#comments</comments>
		<pubDate>Tue, 10 Mar 2009 22:11:00 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
		
		<category><![CDATA[Code]]></category>

		<category><![CDATA[CSS]]></category>

		<category><![CDATA[WebKit]]></category>

		<guid isPermaLink="false">http://thechriswalker.net/?p=84</guid>
		<description><![CDATA[I recently read somewhere about developing web applications for the iPhone / Android browsers that you shouldn&#8217;t use Javascript Frameworks (e.g. jQuery) for animation in your web apps but instead use CSS3 transitions. I had no idea what these where, so had to look it up. Turns out it&#8217;s pretty much a WebKit only thing, [...]]]></description>
			<content:encoded><![CDATA[<p>I recently read somewhere about developing web applications for the iPhone / Android browsers that you shouldn&#8217;t use Javascript Frameworks (e.g. jQuery) for animation in your web apps but instead use CSS3 transitions. I had no idea what these where, so had to look it up. Turns out it&#8217;s pretty much a WebKit only thing, but that&#8217;s fine for iPhone (Safari) and Android (Chrome) Browsers.  </p>
<p>But what is it? Simply put, it&#8217;s a way to create a transition between to CSS states (hope that cleared <em>everything</em> up for you!)</p>
<p>Better, an example: You have two CSS rules for an element, say a link, and for it&#8217;s <tt>:hover</tt> state. like this:</p>
<div class="codecolorer-container css mac-classic" ><div class="css codecolorer" style="font-family:inherit">a <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw1">background</span><span class="sy0">:</span><span class="re0">#eee</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">color</span><span class="sy0">:</span><span class="re0">#333</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">text-decoration</span><span class="sy0">:</span><span class="kw2">none</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">padding</span><span class="sy0">:</span><span class="re3">5px</span> <span class="re3">10px</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">border</span><span class="sy0">:</span><span class="re3">2px</span> <span class="kw2">solid</span> <span class="re0">#333</span><span class="sy0">;</span><br />
&nbsp; &nbsp; border-radius<span class="sy0">:</span> <span class="re3">5px</span><span class="sy0">;</span> <br />
&nbsp; &nbsp; -moz-border-radius<span class="sy0">:</span> <span class="re3">5px</span><span class="sy0">;</span> <br />
&nbsp; &nbsp; -webkit-border-radius<span class="sy0">:</span> <span class="re3">5px</span><span class="sy0">;</span> <br />
<span class="br0">&#125;</span><br />
a<span class="re2">:hover </span><span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw1">background</span><span class="sy0">:</span><span class="re0">#333</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">color</span><span class="sy0">:</span><span class="re0">#eee</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span></div></div>
<p>Now usually, the browser would switch instantly between these two states, but with transitions we can slow it down into a smooth animation.</p>
<p>We can specify which propertys to transition and which to allow to change instantly. Here we can transition in the <tt>background</tt> and <tt>color</tt> properties.</p>
<div class="codecolorer-container css mac-classic" ><div class="css codecolorer" style="font-family:inherit">a <span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw1">background</span><span class="sy0">:</span><span class="re0">#eee</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">color</span><span class="sy0">:</span><span class="re0">#333</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">text-decoration</span><span class="sy0">:</span><span class="kw2">none</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">padding</span><span class="sy0">:</span><span class="re3">5px</span> <span class="re3">10px</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">border</span><span class="sy0">:</span><span class="re3">2px</span> <span class="kw2">solid</span> <span class="re0">#333</span><span class="sy0">;</span><br />
&nbsp; &nbsp; border-radius<span class="sy0">:</span> <span class="re3">5px</span><span class="sy0">;</span> <br />
&nbsp; &nbsp; -moz-border-radius<span class="sy0">:</span> <span class="re3">5px</span><span class="sy0">;</span> <br />
&nbsp; &nbsp; -webkit-border-radius<span class="sy0">:</span> <span class="re3">5px</span><span class="sy0">;</span><br />
&nbsp; &nbsp; &nbsp;<br />
&nbsp; &nbsp; <span class="coMULTI">/* Add the transition properties! */</span><br />
&nbsp; &nbsp; -webkit-transition-property<span class="sy0">:</span> <span class="kw1">background-color</span><span class="sy0">,</span> <span class="kw1">color</span><span class="sy0">;</span><br />
&nbsp; &nbsp; -webkit-transition-duration<span class="sy0">:</span> 600ms<span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="coMULTI">/* you can control the acceleration curve here */</span><br />
&nbsp; &nbsp; -webkit-transition-timing-function<span class="sy0">:</span> ease-in-out<span class="sy0">;</span> <br />
<span class="br0">&#125;</span><br />
a<span class="re2">:hover </span><span class="br0">&#123;</span><br />
&nbsp; &nbsp; <span class="kw1">background</span><span class="sy0">:</span><span class="re0">#333</span><span class="sy0">;</span><br />
&nbsp; &nbsp; <span class="kw1">color</span><span class="sy0">:</span><span class="re0">#eee</span><span class="sy0">;</span><br />
<span class="br0">&#125;</span></div></div>
<p>Here&#8217;s two links, the they are identical except that the second has the transisions applied and if you&#8217;re using a WebKit based browser then it will fade nicely between states.</p>
<style type='text/css'>
a.tryme {
    display:inline-block;
    margin:5px 10px;
    background:#eee;
    color:#333;
    text-decoration:none;
    padding:5px 10px;
    border:2px solid #333;
    border-radius: 5px; 
    -moz-border-radius: 5px; 
    -webkit-border-radius: 5px;
}
a.trans {
    -webkit-transition-property: background-color, color;
    -webkit-transition-duration: 600ms;
    -webkit-transition-timing-function: ease-in-out;
}
a.tryme:hover {
    background:#333;
    color:#eee;
}
</style>
<p><a href='javascript:void(0);' class='tryme'>I will flick between states.</a> <a href='javascript:void(0);' class='tryme trans'>Do I fade or do I flick?</a></p>
<p>Next time I&#8217;ll go into a bit more detail and show how using CSS Transforms as well we can make an OSX Dock style menu using CSS alone!</p>
]]></content:encoded>
			<wfw:commentRss>http://thechriswalker.net/2009-03/webkit-css-transitions-pretty-cool-stuff.html/feed</wfw:commentRss>
		</item>
		<item>
		<title>Discovering QR Codes</title>
		<link>http://thechriswalker.net/2009-02/discovering-qr-codes.html</link>
		<comments>http://thechriswalker.net/2009-02/discovering-qr-codes.html#comments</comments>
		<pubDate>Wed, 18 Feb 2009 15:32:42 +0000</pubDate>
		<dc:creator>Chris</dc:creator>
		
		<category><![CDATA[Not Code]]></category>

		<category><![CDATA[Phones]]></category>

		<category><![CDATA[QR Codes]]></category>

		<guid isPermaLink="false">http://thechriswalker.net/?p=76</guid>
		<description><![CDATA[I recently discovered QR codes and how cool they are! Basically it&#8217;s a 2-D barcode and can store much more information than your standard bar code.
A QR code is a square of dots in a certain computer-readable pattern, for example there is one to the top-left of this post, encoded with the URL to this [...]]]></description>
			<content:encoded><![CDATA[<p>I recently discovered QR codes and how cool they are! Basically it&#8217;s a 2-D barcode and can store much more information than your standard bar code.<br />
A QR code is a square of dots in a certain computer-readable pattern, for example there is one to the top-left of this post, encoded with the URL to this post.</p>
<p>Why bother though? Well, they are used mostly in Japan, where mobile phones are generally all Internet-enabled, so on an advert you might have a QR code for a URL where more info can be found. So you whip out your phone, point the in-built camera at the code, and bingo, it takes you to the website. Also you could have a film opening encoded in QR as a calendar event, so when you scan it it puts a reminder in your calendar. Useful no?</p>
<p>On a personal level though, when QR codes are not big in England, why should I care. Well, they are useful for transferring information I want to a phone. For example, I have a <a href="http://en.wikipedia.org/wiki/Bookmarklet">bookmarklet</a> on my browser that converts the current page I&#8217;m looking at into a QR code (courtesy of the <a href="http://code.google.com/apis/chart/types.html#qrcodes">Google Chart API</a>) and open the image in a new tab. Very useful if I find a page and think, &#8220;I&#8217;ll want to look at that later&#8221; I can make the QR scan it with my phone, and the page goes into it&#8217;s browser history for my later enjoyment.</p>
<p>For those of you interested the bookmarklet code is (should be all on one line, but for the page width&#8217;s sake&#8230;):</p>
<div class="codecolorer-container javascript mac-classic" ><div class="javascript codecolorer" style="font-family:inherit">javascript<span class="sy0">:</span><span class="br0">&#40;</span><span class="kw2">function</span><span class="br0">&#40;</span><span class="br0">&#41;</span><span class="br0">&#123;</span>window.<span class="kw3">open</span><span class="br0">&#40;</span><br />
&nbsp; <span class="st0">'http://chart.apis.google.com/chart?cht=qr&amp;chs=400x400&amp;chl='</span><span class="sy0">+</span><br />
&nbsp; encodeURIComponent<span class="br0">&#40;</span>window.<span class="me1">location</span>.<span class="me1">href</span><span class="br0">&#41;</span><br />
<span class="br0">&#41;</span><span class="sy0">;</span><span class="br0">&#125;</span><span class="br0">&#41;</span><span class="br0">&#40;</span><span class="br0">&#41;</span></div></div>
<p><a href="javascript:(function(){window.open('http://chart.apis.google.com/chart?cht=qr&#038;chs=400x400&#038;chl='+encodeURIComponent(window.location.href));})()">Try it! (will generate the QR code for this page, but a lot bigger than the one by the title)</a></p>
<p>You may have noticed that there are QR codes for the permalinks to these posts aswell, so you can easily bookmark them with a capable phone. Another useful function that my phone can do is to display the QR code for a Contact in my address book, so I can easily share that with another QR enabled phone without having to &#8220;pair&#8221; them with bluetooth, or use Infrared (if the phone still has it!) or text it or whatever. Much more convenient. I just need to find someone else with a QR enabled phone&#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://thechriswalker.net/2009-02/discovering-qr-codes.html/feed</wfw:commentRss>
		</item>
	</channel>
</rss>
