<?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>Joss Crowcroft</title>
	<atom:link href="http://www.josscrowcroft.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.josscrowcroft.com</link>
	<description>Freelance Coder, Web Developer &#38; UX Designer. Making things work since 1988.</description>
	<lastBuildDate>Fri, 10 Feb 2012 15:29:39 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>One Inspiring Viking</title>
		<link>http://www.josscrowcroft.com/2012/random/one-inspiring-viking/</link>
		<comments>http://www.josscrowcroft.com/2012/random/one-inspiring-viking/#comments</comments>
		<pubDate>Fri, 10 Feb 2012 13:49:44 +0000</pubDate>
		<dc:creator>Joss</dc:creator>
				<category><![CDATA[Random]]></category>

		<guid isPermaLink="false">http://www.josscrowcroft.com/?p=1966</guid>
		<description><![CDATA[Some close friends of mine, Tom and his beautiful wife, had a baby. I don&#8217;t know the exact details, but his son &#8211; the most important thing in Tom&#8217;s life ...]]></description>
			<content:encoded><![CDATA[<p>Some close friends of mine, Tom and his beautiful wife, had a baby. I don&#8217;t know the exact details, but his son &#8211; the most important thing in Tom&#8217;s life for a long time already now &#8211; was born with an extremely rare medical condition.</p>
<blockquote style="color: #777;"><p>Today I was told my Son has no bowel left to save. They have never seen a case this bad and there is nothing they can do for him at this point. I have to learn to accept that it is likely I will lose my beautiful Son or watch him have a very tough life if he can survive on a drip. There is no more hope all there is left is to love him. I want to make sure he knows he was loved no matter how long he will be on this planet.</p></blockquote>
<p>I&#8217;m not going to try to turn their grief into a message of inspiration and hope; I don&#8217;t have to. From the beginning, when they first suspected something was wrong, Tom&#8217;s unfailing hope, love and enlightened acceptance of life has touched everybody they know.</p>
<blockquote style="color: #777;"><p>I am not a victim. I am a creator and I will find a way to make something good of this. I don&#8217;t know what yet but I will find it.</p></blockquote>
<p>Tom posted the following message in reply to the outpouring of support and sympathy from friends and family &#8211; I&#8217;m going to read it every time I feel sorry for myself about anything, no matter how seemingly unfair or disastrous. All the inspirational shit people read couldn&#8217;t come close:</p>
<blockquote style="color: #777;"><p>Thanks for the offers of help. The best way you can help me is to not waste your life and dare to live your dreams. Life is short and fragile so don&#8217;t take time for granted but use every minute to live your dream. My Son don&#8217;t have that chance but you do so honour him and don&#8217;t waste your life. I know it is scary because I have done it and am doing it every day but know that when other people are laughing and telling you, you are wrong listen for my voice because I will be there cheering for you.</p>
<p>Stop making excuses. Everything is energy, pain, joy, laughter, fear. It is nothing more, just energy and your choice is how you use that energy. Depression is just unused energy. Fear is our friend that never had much education or wisdom so his advice is often very bad but well meaning. Use all your emotions to drive you to do everything you dream about and you will have helped me, because that is my mission with the time I have on this planet.</p>
<p>Don&#8217;t be sad for me because I am lucky. My circumstances are very bad and painful at the moment but my mind is full of love so I am lucky and from pain and tears I will grow in time. Vikings never surrender.</p></blockquote>
<p>So this is just a really small tribute to one hell of a guy and his beautiful family. A spiritual teacher, masquerading as a tall, ginger Viking, leading the way for all of us, refusing to feel sorry for himself.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.josscrowcroft.com/2012/random/one-inspiring-viking/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>HTML5 History / pushState URLs, .htaccess and You</title>
		<link>http://www.josscrowcroft.com/2012/code/htaccess-for-html5-history-pushstate-url-routing/</link>
		<comments>http://www.josscrowcroft.com/2012/code/htaccess-for-html5-history-pushstate-url-routing/#comments</comments>
		<pubDate>Mon, 09 Jan 2012 16:00:00 +0000</pubDate>
		<dc:creator>Joss</dc:creator>
				<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://www.josscrowcroft.com/?p=1888</guid>
		<description><![CDATA[This guide explains the issues with using JavaScript&#8217;s HTML5 History (pushState) URLs in Apache and covers how to set up your .htaccess file to handle URL routing. If you&#8217;re not ...]]></description>
			<content:encoded><![CDATA[<p>This guide explains the issues with using JavaScript&#8217;s HTML5 History (<code>pushState</code>) URLs in Apache and covers how to set up your <code>.htaccess</code> file to handle URL routing.</p>
<p class="message">If you&#8217;re not sure about <code>pushState</code> and the HTML5 History API, <a title="HTML5 History API, pushState and replaceState - MDN" target="_blank" href="https://developer.mozilla.org/en/DOM/Manipulating_the_browser_history">here&#8217;s a solid starter</a>. If you just want the <code>.htaccess</code> code, you can <a title="Go ahead, be boring and skip the introduction I wrote for you. I don't care." href="#give-me-teh-code">skip the explanation</a>.</p>
<p>So we&#8217;ve reached this point now where every half-decent JavaScripter knows their way around the <code>pushState / replaceState</code> History API and the related wrappers/plugins, and has a decent idea of <a target="_blank" title="HTML5 History browser support" href="https://developer.mozilla.org/en/DOM/Manipulating_the_browser_history#Browser_compatibility">browser support</a> and <a target="_blank" title="History.js - a cross-browser pushState polyfill" href="https://github.com/balupton/history.js">cross-browser polyfills</a> for HTML5 History. I think.</p>
<p>But at the same time, the very people who want to be using it are faced with a blight that, for love nor money, they can&#8217;t fix: <strong>HTML5 History URLs screw up Apache</strong>. And there are just no damn guides anywhere about how to make it work (<em>until now!</em>)</p>
<p>The Apache web server was designed long before the first murmurings of rewriting URLs without a page refresh were heard, and a certain amount of tomfoolery is required to make dynamically-updating URLs work seamlessly.</p>
<p>So without further ado, I present the problem and the starter-pack solution.</p>
<h3>Apache doesn&#8217;t like you with your damn pushState</h3>
<p>So, as you hopefully know by now, to navigate between different sections, screens or pages of a client-side JavaScript application, you&#8217;d traditionally use hash (<code>#</code>) or hash-bang (<code>#!</code>) fragments (e.g. <code>.com/#shopping-cart</code> or <code>.com/#!/profile/yourmum/</code>). The JS code picks up the <code>hashchange</code> event (either natively or via a custom listener/event in older browsers) and fires off a function in your app to switch out the content, or perform some killer action.</p>
<p>When you use HTML5 History, you don&#8217;t use hash fragments; instead, your JS app or website uses <code>.pushState()</code>, or you use your library/wrapper of choice, to navigate (update the URL and create an entry in the window history, enabling Back/Forward support) to e.g. <code>.com/shopping-cart</code> or <code>.com/profile/yourmum/</code> &#8211; all <strong>without</strong> a page refresh.</p>
<p>Perfect. But&#8230; when you save/bookmark/send these URLs, then try to visit them a little later on, you may be disappointed to discover that they <em>don&#8217;t exist</em>. The horror!</p>
<p>Why don&#8217;t they exist?</p>
<p>Think about it &#8211; you&#8217;re trying to find a resource located at a specific URL. It has to be served through Apache. Apache is gonna look for that file, because it doesn&#8217;t have any idea that you&#8217;re looking for a dynamic resource, and even if it did, it wouldn&#8217;t know what to send back to help you find it!</p>
<h3>Apache can handle HTML History/pushState with .htaccess</h3>
<p>Apache was just being mean, earlier. It doesn&#8217;t have anything against <code>pushState</code>. In fact, it <em>loves</em> <code>pushState</code>: now every user, instead of requesting 20 pages in quick succession, requests only one page, with those 20 states being requested bit-by-bit (as smaller fragments, or however your site or JS app handles it.)</p>
<p>But it does choke a little bit.</p>
<p>As I mentioned before, it has to follow the rules: when a visitor requests a resource (or a location that <em>looks</em> like a resource) Apache has to look for it, first in the <code>.htaccess</code> file, if any, then in the filesystem to see if it can find a matching directory/file.</p>
<p>It won&#8217;t find it, so it throws a 404 error. <em>&#8220;I wanted to help,&#8221;</em> it mumbles, <em>&#8220;I just couldn&#8217;t find the damn thing you wanted. Not my problem!&#8221;</em></p>
<p>So we gotta tell it where to look!</p>
<p>Where would it look? Well, where is the JavaScript app that&#8217;s going to check the URL and route the page/screen/section accordingly?</p>
<p>For most apps, it&#8217;s <code>index.html</code>, which would include in all the JavaScript required to handle this. For example, that&#8217;s the page containing your single-page app, in Backbone.js, or jQuery, or just (whoa) plain ol&#8217; JavaScript.</p>
<p>And that&#8217;s what this solution assumes.</p>
<h2 id="give-me-teh-code">.htaccess rules for HTML5 pushState support:</h2>
<p>So the solution: you add a few lines to your <code>.htaccess</code> file.</p>
<p>These lines check firstly whether the requested filename is NOT a static resource (such as an image, stylesheet, or other asset, so that they don&#8217;t all get redirected to <code>index.html</code>), then whether the requested resource is not already <code>index.html</code> (<em>uh oh</em> infinite loops!) and then finally redirects <em>everything</em> to &#8211; you guessed it &#8211; <code>index.html</code>.</p>
<pre class="prettyprint" style="width: 680px; margin-left: -180px;"># html5 pushstate (history) support:
&lt;ifModule mod_rewrite.c&gt;
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_URI} !index
    RewriteRule (.*) index.html [L]
&lt;/ifModule&gt;</pre>
<p>There might even be a nicer way to write it. I&#8217;m no Apache warrior, so to speak, but this works for us.</p>
<p>What does this mean for the visitor?</p>
<p>Obviously, when on the site/single-page app, they don&#8217;t notice a thing. Everything works fine.</p>
<p>The kicker is that when they bookmark a page, or email a funny link to their friend, the next time that URL is opened (the one that was navigated to by <code>pushState</code>), Apache will simply direct the visitor to the homepage. At that point, the JavaScript app takes over. Boom.</p>
<p>This works for multiple-levels of nesting, too, which was a big pain-point when finding a solution. Thus the following URL redirects to <code>index.html</code> without a fuss:</p>
<pre>.com/profiles/yourmum/images/?starttime=<em>[stalkerishly long time ago]</em>
  -&gt; .com/index.html</pre>
<p>At which point the JavaScript code would step in and do it&#8217;s nasty business.</p>
<p><em>Et voila.</em> The <code>.htaccess</code> rules above may not work for everyone and <abbr title="your mileage may vary">YMMV</abbr>, but it&#8217;s doing it for us.</p>
<p>Further reading:</p>
<ul>
<li>Inspired by: <a href="http://www.workingwith.me.uk/blog/software/open_source/apache/mod_rewriting_an_entire_site" title="mod_rewriting an entire site - workingwith.ame.uk" rel="nofollow" target="_blank">mod_rewriting an entire site &#8211; workingwith.me.uk</a>. Inspiration also taken from WordPress&#8217; <code>.htaccess</code> rules.</li>
<li>Nice post: <a href="http://badassjs.com/post/840846392/location-hash-is-dead-long-live-html5-pushstate" title="location.hash is dead. Long live HTML5 pushState! - badassJS" target="_blank">location.hash is dead. Long live HTML5 pushState! &#8211; badassJS</a></li>
</ul>
<p>Any comments? Suggestions, improvements, errors? You know what to do!</p>
<p><small><em>PS. I know, I know. &#8220;Don&#8217;t use Apache blah blah nginx blah.&#8221; I know. But people still use Apache.</em></small></p>
<p><small># edit: Updated .htaccess rules to be a bit better, based on WordPress permalinks&#8217; <code>.htaccess</code> rules.</small></p>
]]></content:encoded>
			<wfw:commentRss>http://www.josscrowcroft.com/2012/code/htaccess-for-html5-history-pushstate-url-routing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Cheung Chau Island, Hong Kong</title>
		<link>http://www.josscrowcroft.com/2012/random/cheung-chau-island-hong-kong/</link>
		<comments>http://www.josscrowcroft.com/2012/random/cheung-chau-island-hong-kong/#comments</comments>
		<pubDate>Tue, 03 Jan 2012 17:16:57 +0000</pubDate>
		<dc:creator>Joss</dc:creator>
				<category><![CDATA[Random]]></category>

		<guid isPermaLink="false">http://www.josscrowcroft.com/?p=1816</guid>
		<description><![CDATA[Off-topic: recently spent a day walking around Cheung Chau Island, near Hong Kong. The whole place is paved, but it&#8217;s still great to explore, only a short ferry from Central pier. ...]]></description>
			<content:encoded><![CDATA[<p><em>Off-topic:</em> recently spent a day walking around Cheung Chau Island, near Hong Kong. The whole place is paved, but it&#8217;s still great to explore, only a short ferry from Central pier. I took a steaming heap of photos before my camera died, and picked out a few I liked the best:</p>
<div id="attachment_1817" class="wp-caption alignright" style="width: 690px"><a href="http://www.josscrowcroft.com/2012/random/cheung-chau-island-hong-kong/"><img class="border size-large wp-image-1817" title="boats" src="http://www.josscrowcroft.com/wp-content/uploads/2012/01/boats-680x382.jpg" alt="" width="680" height="382" /></a><p class="wp-caption-text">Fishing boats in the harbour</p></div>
<p>The guide book gives a suggested route &#8211; heading south and taking in as many of the touristy bits as possible. I suggest you go the opposite way, where you&#8217;ll get some fantastic views and be away from the crowds, then do the touristy route afterwards&#8230;</p>
<p><span id="more-1816"></span><div id="attachment_1819" class="wp-caption alignright" style="width: 690px"><a href="http://www.josscrowcroft.com/wp-content/uploads/2012/01/island-beach.jpg"><img class="border wp-image-1819" title="beach" src="http://www.josscrowcroft.com/wp-content/uploads/2012/01/island-beach-680x382.jpg" alt="" width="680" height="382" /></a><p class="wp-caption-text">The island's main town and beach.</p></div></p>
<div id="attachment_1820" class="wp-caption alignright" style="width: 690px"><a href="http://www.josscrowcroft.com/wp-content/uploads/2012/01/junk.jpg"><img class="border size-large wp-image-1820" title="old boat" src="http://www.josscrowcroft.com/wp-content/uploads/2012/01/junk-680x382.jpg" alt="" width="680" height="382" /></a><p class="wp-caption-text">Old fishing boat through trees. Not a permanent fixture.</p></div>
<p>The town itself is tiny and charming, but with all the bustle of any other Hong Kong harbour village, which I love. I got some great photos of buildings, temples and people doing normal shit, but they couldn&#8217;t really capture what it&#8217;s like.</p>
<div id="attachment_1818" class="wp-caption alignright" style="width: 690px"><a href="http://www.josscrowcroft.com/wp-content/uploads/2012/01/cake.jpg"><img class="border wp-image-1818" title="cake" src="http://www.josscrowcroft.com/wp-content/uploads/2012/01/cake-680x382.jpg" alt="" width="680" height="382" /></a><p class="wp-caption-text">Hometown Teahouse sells these amazing red bean cakes for HK $4 (about 30p)</p></div>
<div id="attachment_1821" class="wp-caption alignright" style="width: 690px"><a href="http://www.josscrowcroft.com/wp-content/uploads/2012/01/rickshaw.jpg"><img class="border size-large wp-image-1821" title="rickshaw" src="http://www.josscrowcroft.com/wp-content/uploads/2012/01/rickshaw-680x382.jpg" alt="" width="680" height="382" /></a><p class="wp-caption-text">Rickshaw. I can imagine this in a Wes Anderson movie, with four people clinging to it</p></div>
<div id="attachment_1822" class="wp-caption alignright" style="width: 690px"><a href="http://www.josscrowcroft.com/wp-content/uploads/2012/01/signs.jpg"><img class="border wp-image-1822" title="signs" src="http://www.josscrowcroft.com/wp-content/uploads/2012/01/signs-680x382.jpg" alt="" width="680" height="382" /></a><p class="wp-caption-text">Signs. Before the neon billboards, I figure they all looked like this</p></div>
<p>While walking around and taking it all in, enjoying the solitude that&#8217;s so rare when you live and work in HK island, it occurred to me that this has been here all along &#8211; it just took me over a year to actually come find it. </p>
<p>In hindsight, it&#8217;s pretty stunning how easily you can lose that sense of curiosity and fascination that comes with moving somewhere completely new, and let everything become dulled by &#8216;real life&#8217;!</p>
<div id="attachment_1823" class="wp-caption alignright" style="width: 510px"><a href="http://www.josscrowcroft.com/wp-content/uploads/2012/01/the-path.jpg"><img class="border size-full wp-image-1823" title="the path" src="http://www.josscrowcroft.com/wp-content/uploads/2012/01/the-path.jpg" alt="" width="450" height="800" /></a><p class="wp-caption-text">This one pretty much sums up the whole day&#39;s exploring, for me.</p></div>
<p>Watching the sun set over what I can only assume is the South China Sea &#8211; my camera having long since expired &#8211; I resolved to get out and explore more before I leave this crazy part of the world. And get some comfier boots.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.josscrowcroft.com/2012/random/cheung-chau-island-hong-kong/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Convert a table of mixed values to a single currency with money.js</title>
		<link>http://www.josscrowcroft.com/2011/code/convert-table-mixed-values-single-currency-with-money-js-open-exchange-rates/</link>
		<comments>http://www.josscrowcroft.com/2011/code/convert-table-mixed-values-single-currency-with-money-js-open-exchange-rates/#comments</comments>
		<pubDate>Fri, 30 Dec 2011 08:21:57 +0000</pubDate>
		<dc:creator>Joss</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Projects]]></category>

		<guid isPermaLink="false">http://www.josscrowcroft.com/?p=1747</guid>
		<description><![CDATA[You can use money.js and data from the open exchange rates API to convert/normalise an entire table of values from multiple currencies to any other single currency. I&#8217;m using it ...]]></description>
			<content:encoded><![CDATA[<p>You can use <a href="http://josscrowcroft.github.com/money.js/" title="money.js - tiny javascript currency conversion library" target="_blank">money.js</a> and data from the <a href="http://josscrowcroft.github.com/open-exchange-rates/" title="open exchange rates - free, open-source currency conversion data" target="_blank">open exchange rates API</a> to convert/normalise an entire table of values from multiple currencies to any other single currency.</p>
<p>I&#8217;m using it in our analytics application to let users compare the money values from assorted items (in different currencies) in a single currency of their choice. Every data table has an option to normalise currencies for all values.</p>
<h2>Convert a table of values with money.js</h2>
<p>Below you&#8217;ll find a table of Christmas-themed adult novelty products. All of the items are in different currencies for some reason (a realistic scenario, if you&#8217;ve been scraping data from various websites.)</p>
<p>What if you want to compare the unit price and gross revenue values for each product in a single currency? Try it!</p>
<p><iframe style="border:0; margin:0; padding:0; outline:0; width:680px; height:300px; margin-left:-180px" src="http://www.josscrowcroft.com/demos/money.js/tables/#demo"></iframe></p>
<p><em><small>Iframe not loading? You can also <a href="http://www.josscrowcroft.com/demos/money.js/tables/" title="money.js table conversion demo" target="_blank">view the demo here</a>. I wrote it before Christmas, in case you&#8217;re wondering why it&#8217;s Christmas-themed!</small></em></p>
<p>In this demo, I&#8217;m also using <a href="http://documentcloud.github.com/underscore/" title="underscore.js - javascript's utility belt library" target="_blank">underscore.js</a> for data manipulation and client-side templating, <a href="http://jquery.com/" title="No introduction needed?" target="_blank">jQuery</a> for DOM manipulation/events and <a href="http://josscrowcroft.github.com/accounting.js/" title="JavaScript library for number, money, currency formatting" target="_blank">accounting.js</a> for number formatting.</p>
<p>The table is built using a very simple underscore.js template, from a matrix of values (array of arrays) representing table rows and individual cells. (If you&#8217;re unsure about building tables from data matrices, I wrote a post that deals with it some more, explaining how to <a href="http://www.josscrowcroft.com/2011/code/formatting-currency-columns-in-javascrip-tables-underscore-zip-accounting-js/" title="Formatting currency columns in tables with underscore.zip and accounting.js" target="_blank">format tables of numbers with accounting.js and underscore.js</a>).</p>
<h2>The code</h2>
<p>The code that does the conversion is a little rough around the edges, but here&#8217;s how it breaks down:</p>
<ul>
<li>Define the data table as an array of columns (each an object, with title and metadata) and an array of table rows (each an array of table cells). In your application, this data would probably come from an API.</li>
<li>Use the underscore.js template to draw the table and jQuery to render it.</li>
<li>When the select box is changed, loop over the table rows (items), and for each one, get the item&#8217;s original currency, and use money.js&#8217; <code>fx.convert()</code> to convert the value. Then redraw the table.</li>
</ul>
<p>Here&#8217;s the underscore.js template, some funky syntax highlighting going on there:</p>
<pre class="prettyprint lang-html" style="width:680px;margin-left:-180px;">&lt;script type=&quot;text/template&quot; id=&quot;tableTemplate&quot;&gt;
    &lt;table&gt;
        &lt;thead&gt;
            &lt;tr&gt;
                &lt;% _(tplColumns).each(function(col) { %&gt;
                    &lt;th data-column=&quot;&lt;%= col.key %&gt;&quot;&gt;&lt;%= col.title %&gt;&lt;/th&gt;
                &lt;% }); %&gt;
            &lt;/tr&gt;
        &lt;/thead&gt;

        &lt;tbody&gt;
            &lt;% _(tplRows).each(function(row) { %&gt;
                &lt;tr&gt;
                    &lt;% _(row).each(function(value, i) { %&gt;
                        &lt;td class=&quot;&lt;%= tplColumns[i].type || '' %&gt;&quot;&gt;
                            &lt;%= formatCell(value, tplColumns[i].type) %&gt;
                        &lt;/td&gt;
                    &lt;% }); %&gt;
                &lt;/tr&gt;
            &lt;% }); %&gt;
        &lt;/tbody&gt;
    &lt;/table&gt;
&lt;/script&gt;</pre>
<p>So we gots a table header row, with the <code>&lt;th&gt;</code> cells templated from the <code>tplColumns</code> array, and then the table body, with each <code>&lt;th&gt;</code> representing a single item (an array in the <code>tplRows</code> array and each <code>&lt;td&gt;</code> representing a single value. The template relies on a handy <code>formatCell()</code> function, which uses accounting.js to format each table cell&#8217;s value, according to its type.</p>
<p>The JavaScript code itself is a little janky, but it works for our purposes:</p>
<pre class="prettyprint lang-js" style="width:680px;margin-left:-180px;">// Handy callback function to run accounting.js formatting on cells:
function formatCell(value, type) {
    return type === 'number' ? accounting.formatNumber(value)
         : type === 'money' ? accounting.formatNumber(value, 2)
         : value;
}

// On ready:
jQuery(document).ready(function($) {

    // The columns in the table:
    var columns = [
        { title: 'Product',       key: 'name'      },
        { title: 'Units Sold',    key: 'sold',    type: 'number' },
        { title: 'Currency',      key: 'fx',      type: 'fx'     },
        { title: 'Unit Price',    key: 'price',   type: 'money'  },
        { title: 'Gross Revenue', key: 'revenue', type: 'money'  }
    ];

    // The rows of data (corresponding to columns):
    var rows = [
        [ 'His &#38;amp; Hers Prophylactics',         24965, 'USD', 12.99, 324295.35 ],
        [ 'Christmas Stockings, Fishnet',         12600, 'GBP', 16.8,  211680    ],
        [ 'Candy Underwear, Gummy',               8965,  'SEK', 80.5,  721682.5  ],
        [ 'Santa Hat and Santa Suit, Crotchless', 13543, 'EUR', 10.5,  142201.5  ],
        [ 'Vibrating Christmas Crackers x 6',     9954,  'HKD', 108,   1075032   ]
    ];

    // Handy underscore.js template that builds a table from data like the above:
    // (See script tag with template, above)
    var template = _.template( $('#tableTemplate').html() );

    // Template the table's HTML using our data:
    $('#table').html( template({
        tplColumns: columns,
        tplRows: rows
    }));

    // Convert the data:
    $('#currency').change(function() {
        var targetFx = $(this).find(':selected').val();
        var currentFx;

        if ( !targetFx ) return false;

        // Now we're gonna use underscore.js to confapulate the data:
        var newRows = _.map(rows, function(row) {
            // Keeps the original row intact:
            row = _.clone(row);

            // Get the 'from' currency:
            currentFx = row[2];

            // Update the row's currency with the 'target':
            row[2] = targetFx;

            // Convert the numbers yo:
            row[3] = fx.convert(row[3], { from: currentFx, to: targetFx });
            row[4] = fx.convert(row[4], { from: currentFx, to: targetFx });

            return row;
        });

        // Now template the data:
        $('#table').html(template({
            tplColumns: columns,
            tplRows: newRows
        }));

        return false;
    });

    // Reset to original data:
    $('#reset').click(function() {
        // Template the original data:
        $('#table').html( template({
            tplColumns: columns,
            tplRows: rows
        }));
    });
});</pre>
<p>Note that the formatting part takes a shortcut and uses predefined indices to find values in the data array (in our app, it&#8217;s a little more complicated, as the index of the currency value is unpredictable &#8211; so there&#8217;s a method to find out which it is, which I&#8217;ve left out for brevity.) </p>
<p>This method relies on your using data arrays (e.g. vie AJAX) to build tables dynamically with JavaScript. If your tables are templated on the server-side and delivered as fully-rendered HTML, there are other ways to achieve this result, but I&#8217;ll save those for another day.</p>
<p>Any questions, hit me up in the comments!</p>
<h2>Bonus points</h2>
<p>PS. Here&#8217;s the code that loads the data from <a href="http://josscrowcroft.github.com/open-exchange-rates/" title="open exchange rates - free, open-source currency conversion data" target="_blank">opeexchangerates.org</a> into money.js, and also builds the drop-down currency select box:</p>
<pre class="prettyprint lang-js" style="width:680px;margin-left:-180px;">// Get the latest exchange rates from openexchangerates.org:
$.ajax({
    url: 'http://openexchangerates.org/latest.json',
    dataType: 'jsonp',
    success: function(data) {
        fx.rates = data.rates;
        fx.base = data.base;
    }
});

// Get the list of currencies too, and create an extra group in the drop-down:
$.ajax({
    url: 'http://openexchangerates.org/currencies.json',
    dataType: 'jsonp',
    success: function(data) {
        var $optgroup = $('&lt;optgroup label=&quot;All Currencies&quot;/&gt;');
        _.each(data, function(name, code) {
            $optgroup.append('&lt;option value=&quot;' + code + '&quot;&gt;' + name + ' (' + code +')&lt;/option&gt;');
        });
        $optgroup.appendTo('#currency');
    }
});</pre>
<p>Hope you&#8217;ve enjoyed reading this festive exploration of money exchanging extravagance!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.josscrowcroft.com/2011/code/convert-table-mixed-values-single-currency-with-money-js-open-exchange-rates/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Open Exchange Rates Project (and money.js) update</title>
		<link>http://www.josscrowcroft.com/2011/projects/open-exchange-rates-project-money-js-update/</link>
		<comments>http://www.josscrowcroft.com/2011/projects/open-exchange-rates-project-money-js-update/#comments</comments>
		<pubDate>Mon, 12 Dec 2011 17:07:45 +0000</pubDate>
		<dc:creator>Joss</dc:creator>
				<category><![CDATA[Projects]]></category>

		<guid isPermaLink="false">http://www.josscrowcroft.com/?p=1726</guid>
		<description><![CDATA[Just a few notable updates to money.js and the open exchange rates API: Open Exchange Rates API In a nutshell: We&#8217;ve added exchange rate data going back to 1999, thanks ...]]></description>
			<content:encoded><![CDATA[<p>Just a few notable updates to money.js and the open exchange rates API:</p>
<h2><a title="open source exchange rates project - free JSON API for currency conversion data" href="http://josscrowcroft.github.com/open-exchange-rates/" target="_blank">Open Exchange Rates API</a></h2>
<p>In a nutshell:</p>
<ul>
<li>We&#8217;ve added exchange rate data going back to <a title="open exchange rates data for january 1999" href="http://openexchangerates.org/historical/1999-01-01.json" target="_blank">1999</a>, thanks to the hard work of <a title="Sebastian Majstorovic" href="https://github.com/canbuffi" target="_blank">Sebastian Majstorovic</a> and his <a title="epic pull request" href="https://twitter.com/josscrowcroft/status/145532765155229696" target="_blank">epic 390,000-line pull request</a></li>
<li>The data is now collected from the public Yahoo! Finance API, which seems to be more accurate and reliable.</li>
<li>The proxy at openexchangerates.org now supports JSONP requests (<a title="open exchange rates jsonp" href="http://openexchangerates.org/latest.json?callback=myCoolFunction" target="_blank">like this</a>) by adding a <code>`callback`</code> parameter to the URL. This works for <a title="historical exchange rate data with jsonp callback" href="http://openexchangerates.org/historical/2010-10-10.json?callback=whoaYeah" target="_blank">historical files</a>, too.</li>
<li>The proxy also now downloads, caches and serves the API files statically instead of requesting them from github each time (should be 10x faster, no benchmarks yet though.)</li>
</ul>
<p>This project has really taken on a life of its own, thanks to a bunch of great people and feedback and the ever-diligent <a title="Currency Bot" href="http://currencybot.github.com/" target="_blank">Currency Bot</a>. Check out the <a title="open exchange rates API" href="http://josscrowcroft.github.com/open-exchange-rates/" target="_blank">homepage</a> if you&#8217;ve not seen it yet. The documentation still needs work in the coming weeks.</p>
<p>Oh, and the code is now under MIT license, but the data license we&#8217;re still trying to figure out. Anybody a lawyer?</p>
<h2><a title="money.js JavaScript currency conversion library" href="http://josscrowcroft.github.com/money.js/" target="_blank">money.js (JavaScript Currency Conversion library)</a></h2>
<p>What&#8217;s new:</p>
<ul>
<li>Added a license (MIT) which it turns out is a really big deal for people wanting to use the library in commercial applications. Now everyone can do whatever they like, wherever they please.</li>
<li>Added basic parsing, so you can write e.g. <code>`fx("$1.99 HKD").to("EUR")`</code> and have it work exactly as you&#8217;d expect.</li>
</ul>
<p>Beyond a few fixes and extra comments, not much has changed. It&#8217;s still tiny (~1.2kb minified, probably around 0.6kb gzipped) and still does everything you need out of the box, with no dependencies, so <a title="money.js demo" href="http://josscrowcroft.github.com/money.js/#playground" target="_blank">give it a shot</a>!</p>
<h3>Mail &#8216;em in!</h3>
<p>If you&#8217;re using money.js and/or the Open Exchange Rates API in any neat projects, please let me know so I can build a showcase!</p>
<p>By the way &#8211; I&#8217;m shooting for a post every few days until New Year to clear a several-month backlog of 90%-finished drafts and ideas.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.josscrowcroft.com/2011/projects/open-exchange-rates-project-money-js-update/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>The Über-Programmer</title>
		<link>http://www.josscrowcroft.com/2011/code/the-uber-programmer/</link>
		<comments>http://www.josscrowcroft.com/2011/code/the-uber-programmer/#comments</comments>
		<pubDate>Wed, 16 Nov 2011 12:26:19 +0000</pubDate>
		<dc:creator>Joss</dc:creator>
				<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://www.josscrowcroft.com/?p=1706</guid>
		<description><![CDATA[If you ever catch me staring quietly into space when shit hits the fan &#8211; when it seems as though I should be furiously typing, sweating profusely and throwing back ...]]></description>
			<content:encoded><![CDATA[<p>If you ever catch me staring quietly into space when shit hits the fan &#8211; when it seems as though I should be furiously typing, sweating profusely and throwing back coffee by the litre &#8211; recall this quotation by <a title="The 10X-programmer explained: 'Why programmers are not paid in proportion to their productivity'" href="http://www.johndcook.com/blog/2009/12/23/why-programmers-are-not-paid-in-proportion-to-their-productivity/" target="_blank">John D. Cook</a> and breathe a sigh of relief:</p>
<blockquote style="color: #464646;"><p>The romantic image of an über-programmer is someone who fires up Emacs, types like a machine gun, and delivers a flawless final product from scratch. A more accurate image would be someone who stares quietly into space for a few minutes and then says “Hmm. I think I’ve seen something like this before.”</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.josscrowcroft.com/2011/code/the-uber-programmer/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>money.js and the Open Source Exchange Rates API = better currency conversion</title>
		<link>http://www.josscrowcroft.com/2011/projects/money-js-and-the-open-source-exchange-rates-api-better-currency-conversion/</link>
		<comments>http://www.josscrowcroft.com/2011/projects/money-js-and-the-open-source-exchange-rates-api-better-currency-conversion/#comments</comments>
		<pubDate>Thu, 13 Oct 2011 09:56:14 +0000</pubDate>
		<dc:creator>Joss</dc:creator>
				<category><![CDATA[Projects]]></category>

		<guid isPermaLink="false">http://www.josscrowcroft.com/?p=1638</guid>
		<description><![CDATA[Today I&#8217;m chuffed to release two closely related projects that have been eating up all my spare time recently. I started work on both specifically for our enterprise analytics application ...]]></description>
			<content:encoded><![CDATA[<p>Today I&#8217;m chuffed to release two closely related projects that have been eating up all my spare time recently. I started work on both specifically for our enterprise analytics application (just like accounting.js) but they soon took on a life of their own &#8211; quite literally, in one case.</p>
<h2>money.js &#8211; JavaScript currency conversion library</h2>
<div id="attachment_1624" class="wp-caption alignright" style="width: 690px"><a href="http://josscrowcroft.github.com/money.js/" target="_blank"><img class="border size-large wp-image-1624" title="money.js - javascript currency conversion library" src="http://www.josscrowcroft.com/wp-content/uploads/2011/10/money-js-screenshot-680x291.png" alt="money.js - javascript currency conversion library" width="680" height="291" /></a><p class="wp-caption-text">money.js - javascript currency conversion library</p></div>
<p>money.js is a tiny (1kb) JavaScript library for realtime currency conversion, in the browser and on the server, with zero dependencies. It features simple method chaining and can convert to / from any currency, provided you have the exchange rates for them.</p>
<p>You only need exchange rates relative to one single currency (eg. USD) to be able to convert between any others &#8211; money.js does it all for you.</p>
<p>No longer will you need to go wading through shit-heaps of messy, 10-year-old <em>&#8220;FREE currency converter javascripts!!1&#8243;</em> code just to add basic conversion to your web-app or online store!</p>
<p><strong>More info, demo, download and docs at the <a title="money.js - JavaScript currency conversion library, no dependencies, in just over 1 kb." href="http://josscrowcroft.github.com/money.js/" target="_blank">money.js homepage</a></strong></p>
<p><em>&#8220;But where do we get these exchange rates?&#8221; (&#8220;Maybe there&#8217;s some in that truck!!..&#8221;)</em></p>
<p>The biggest issue with currency conversion has to be sourcing reliable exchange rates without having to sell your mum to pay for the API access. I&#8217;ve been wanting to take a stab at that for a long time, and here it is:</p>
<h2>The Open Source Exchange Rates API project</h2>
<div id="attachment_1616" class="wp-caption alignright" style="width: 690px"><a href="http://josscrowcroft.github.com/open-exchange-rates/" target="_blank"><img class="border size-large wp-image-1616" title="Open Source Exchange Rates API" src="http://www.josscrowcroft.com/wp-content/uploads/2011/10/open-exchange-rates-screenshot-680x233.png" alt="Open Source Exchange Rates API" width="680" height="233" /></a><p class="wp-caption-text">The Open Source Exchange Rates API, powered by the lovable (and deadly) Currency Bot</p></div>
<p>While working on money.js, I realised very quickly that finding a free, reliable source of JSON-formatted, regularly updated data (with no access limits or hidden catches) is, well, impossible. It just doesn&#8217;t exist.</p>
<p>Until now!</p>
<p>The Open Source Exchange Rates API provides up-to-date, flexible and portable currency conversion data that can be used in any application, framework or language (not just JavaScript).</p>
<p>It was originally designed for integration with money.js, and hacked together in an afternoon. It&#8217;s powered by a simple nodeJS scraper and a list of currencies: every hour, <a title="Currency Bot's little homepage" href="http://currencybot.github.com/" target="_blank">Currency Bot</a> collects all the exchange rates from the Google Calculator API (one by one), then pushes them in JSON format to a public GitHub code repository for everybody to use.</p>
<p>The rates are available historically for any day since the project started, and could soon be extended to provide data going back several years.</p>
<p>Also, it&#8217;s mirrored on <a title="openexchangerates.org, open source exchange rates api mirror" href="http://openexchangerates.org/latest.json" target="_blank">openexchangerates.org</a>, which sends files with friendly <code>Access-Control</code> HTTP headers for cross-origin resource sharing (<code>CORS</code>) &#8211; so that they can be loaded into an app or page via AJAX.</p>
<p>I would write more, but I&#8217;m shattered after waking up at 6am to get Currency Bot out of his <em>can&#8217;t-scrape-won&#8217;t-scrape funk</em> (he had a few teething problems.) He&#8217;s back on form and collecting data like a boss &#8211; you can see it at the <a title="currencybot/open-exchange-rates" href="https://github.com/currencybot/open-exchange-rates" target="_blank">currencybot/open-exchange-rates</a> GitHub repository.</p>
<p><strong>Learn more about using the free service at the <a title="Open Source Exchange Rates API - hourly updated currency conversion data, free." href="http://josscrowcroft.github.com/open-exchange-rates/" target="_blank">Open Source Exchange Rates API</a> homepage!</strong></p>
<h3>The next step</h3>
<p>Wow. I&#8217;ve wanted to get these two done for a long time, and now I&#8217;m left scrambling to find something else to do &#8211; lucky for me, there&#8217;s plenty. Here&#8217;s the future plans for these two projects (if you feel you can contribute, please get in touch!)</p>
<ul>
<li>Find a way to do a once-off retrospective crawl of historical exchange rates going back as far as possible. This will almost certainly involve abusing another free but non-user-friendly or rate-limited service. Open to suggestions.</li>
<li>Package up money.js into a <code>npm</code> module so that you can go <code>npm install moneyjs</code>.</li>
<li>Write documentation for how to use the Open Source Exchange Rates API in the most popular languages and frameworks</li>
<li>Write a full test suite for money.js</li>
<li>And a bunch more &#8211; all I can say is, hit &#8216;watch&#8217; on the GitHub repositories (<a title="josscrowcroft/money.js" href="https://github.com/josscrowcroft/money.js" target="_blank">here</a> and <a title="currencybot/open-exchange-rates" href="https://github.com/currencybot/open-exchange-rates" target="_blank">here</a>) and follow me on twitter <a title="@josscrowcroft on Twitter" href="http://twitter.com/josscrowcroft" target="_blank">here</a> if you&#8217;re interested and want to keep up to date.</li>
</ul>
<p>Thanks for reading!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.josscrowcroft.com/2011/projects/money-js-and-the-open-source-exchange-rates-api-better-currency-conversion/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>I&#8217;m not an artist: attempted self-portrait</title>
		<link>http://www.josscrowcroft.com/2011/random/im-not-an-artist-attempted-self-portrait/</link>
		<comments>http://www.josscrowcroft.com/2011/random/im-not-an-artist-attempted-self-portrait/#comments</comments>
		<pubDate>Thu, 06 Oct 2011 10:36:49 +0000</pubDate>
		<dc:creator>Joss</dc:creator>
				<category><![CDATA[Random]]></category>

		<guid isPermaLink="false">http://www.josscrowcroft.com/?p=1580</guid>
		<description><![CDATA[Earlier this week, we went to a painting session in a really cool art space in Causeway Bay. While sketching some ideas, I looked up and noticed I was sitting ...]]></description>
			<content:encoded><![CDATA[<p>Earlier this week, we went to a painting session in a really cool art space in Causeway Bay. While sketching some ideas, I looked up and noticed I was sitting in front of a huge mirror and thought it would be poetic or something to attempt a self-portrait, in which I could see myself painting myself (painting myself):</p>
<div id="attachment_1582" class="wp-caption alignright" style="width: 690px"><a href="http://www.josscrowcroft.com/wp-content/uploads/2011/10/joss-crowcroft-selfportrait.jpg"><img src="http://www.josscrowcroft.com/wp-content/uploads/2011/10/joss-crowcroft-selfportrait.jpg" alt="Joss&#039; first self portrait" title="Joss&#039; first self portrait" width="680" height="340" class="size-large wp-image-1582" /></a><p class="wp-caption-text">Early attempts at recursion caused a RangeError, so I limited myself to 2 levels of depth #boom</p></div>
<p>(Click for full size)</p>
<p>Actually, I just thought it would look cool, although some sobering but expected family news later that night made me realise that perhaps there&#8217;s something meaningful in it, or some reason I painted it &#8211; it&#8217;s kinda like I cant really see myself. One thing&#8217;s for sure: I&#8217;m no Picasso.</p>
<p>Still, I think it&#8217;s important for people who spend all day writing code (and/or pushing pixels) to occasionally get away from the screen and throw some paint around, or create some art that requires tactile sensations, so we&#8217;ll definitely be doing this again.</p>
<p>As an aside &#8211; mixing paint is <em>nothing</em> like in PhotoShop, and the colours never seem to resemble hex colours. I couldn&#8217;t get my favourite colour, <code style="color:#BADA55; font-weight:bold; background-color:#444">#BADA55</code>, no matter how hard I tried. Luckily they had a shade of blue that matched my shirt exactly!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.josscrowcroft.com/2011/random/im-not-an-artist-attempted-self-portrait/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>javascript sandbox console &#8211; a playground for your users to mess around in (Backbone.js)</title>
		<link>http://www.josscrowcroft.com/2011/code/javascript-sandbox-console-playground/</link>
		<comments>http://www.josscrowcroft.com/2011/code/javascript-sandbox-console-playground/#comments</comments>
		<pubDate>Tue, 04 Oct 2011 11:59:32 +0000</pubDate>
		<dc:creator>Joss</dc:creator>
				<category><![CDATA[Code]]></category>
		<category><![CDATA[Design]]></category>
		<category><![CDATA[Projects]]></category>

		<guid isPermaLink="false">http://www.josscrowcroft.com/?p=1555</guid>
		<description><![CDATA[While working on an upcoming JavaScript library and open source API service, I accidentally created a mini javascript playground, with the goal of allowing users to easily try out the ...]]></description>
			<content:encoded><![CDATA[<p>While working on an upcoming JavaScript library and open source API service, I accidentally created a mini javascript playground, with the goal of allowing users to easily try out the library&#8217;s functionality, without having to open their console.</p>
<p><a href="http://josscrowcroft.github.com/javascript-sandbox-console/" target="_blank"><img class="border alignright size-large wp-image-1549" title="JavaScript sandbox console" src="http://www.josscrowcroft.com/wp-content/uploads/2011/10/js-sandbox-console.png" alt="javascript sandbox console" width="700" height="380" /></a></p>
<p>It seemed like a cool enough concept to warrant taking a break from that project and indulging in an all-night coding marathon to get it finished. Work the next day was painful, but I&#8217;m pretty pleased with how version 0.1 came out.</p>
<h2>Introducing the javascript sandbox console</h2>
<p>The 0.1 release features a pretty design, up/down command history (with localStorage saving), basic syntax highlighting for output and some other cool features.</p>
<h4><a title="javascript sandbox console" href="http://josscrowcroft.github.com/javascript-sandbox-console/" target="_blank">javascript sandbox console demo</a> • <a title="javascript sandbox console" href="http://josscrowcroft.github.com/javascript-sandbox-console/" target="_blank">github repository</a></h4>
<p>It&#8217;s seriously easy to style with CSS (I&#8217;ll add some extra skins soon) and to install on your library/plugin&#8217;s homepage. Do it! Your users will thank you.</p>
<p>What&#8217;s more, it&#8217;s entirely programmable through the global <code>sandbox</code> object, so you can manually feed it commands for the user to try (as on the demo.)</p>
<p>Oh, and it&#8217;s not tested in IE, as of publishing, because I don&#8217;t have my windows laptop with me.</p>
<p>Enjoy!</p>
<blockquote><p>The js sandbox console is a javascript playground designed to enhance demos and homepages for javascript libraries, plugins and scripts, giving visitors an easy and chilled-out way to test-drive the functionality &#8211; without whacking open their Firebug / Dev Tools console.</p>
<p>The idea is inspired by jsconsole.com and was built with Backbone.js and jQuery, in a strange and terrible all-night code-off. Then tidied up a bit the next day.</p></blockquote>
<h3>PS:</h3>
<p>Make sure to hit &#8216;watch&#8217; on the repository, as it will be getting a bunch of fixes and improvements in the next few months. Please <a title="javascript sandbox console issues" href="https://github.com/josscrowcroft/javascript-sandbox-console/issues">make issues</a> if you find any bugs or have suggestions, and feel free to contribute code.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.josscrowcroft.com/2011/code/javascript-sandbox-console-playground/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>A little URL generator for Backbone.js</title>
		<link>http://www.josscrowcroft.com/2011/code/a-little-url-generator-for-backbone-js/</link>
		<comments>http://www.josscrowcroft.com/2011/code/a-little-url-generator-for-backbone-js/#comments</comments>
		<pubDate>Wed, 28 Sep 2011 16:24:40 +0000</pubDate>
		<dc:creator>Joss</dc:creator>
				<category><![CDATA[Code]]></category>

		<guid isPermaLink="false">http://www.josscrowcroft.com/?p=1538</guid>
		<description><![CDATA[Just something I wrote at work today: our app has a model that acts as an API for submodules, and as part of it, it allows interlinking between different modules ...]]></description>
			<content:encoded><![CDATA[<p>Just something I wrote at work today: our app has a model that acts as an API for submodules, and as part of it, it allows interlinking between different modules (aka &#8216;screens&#8217;).</p>
<p>You can pass this method the &#8216;slug&#8217; of any screen (module) in the app, plus any number of arguments and it builds a URL for them. Each of the args is separated by a &#8216;<code>/</code>&#8216;. </p>
<p>Arrays are joined with commas, functions are executed, objects are strigified via jQuery&#8217;s <code>$.param</code>, and strings/numbers are just given as-is.</p>
<pre class="prettyprint lang-js">// Build URL for any screen:
urlify: function(slug) {
	slug = slug || "";

	// Create array of strings from arguments:
	var args = _.map(Array.prototype.slice.call(arguments, 1), function(arg) {
		// Join arrays, evaluate functions, stringify objects, leave strings/numbers:
		return _.isArray(arg) ? arg.join(',') : _.isFunction(arg) ? arg() : _.isObject(arg) ? $.param(arg) : arg;
	});
	return (!Backbone.history.options.pushState ? '#' : '') + slug + '/' + ( args.length > 0 ? args.join('/') + '/' : '' );
}

// for example:
Model.urlify('screen-name', 1253431, ["a","b","c"], {a:1});
// => "#screen-name/1253431/a,b,c/a%5Bb%5D=1/"
</pre>
<h3>What the <em>hash</em>?</h3>
<p>Note the <code>(!Backbone.history.options.pushState ? '#' : '')</code> ?</p>
<p>When supporting <code>pushState</code> in Backbone.history, some browsers will use e.g. <code>app.com/#page</code>, while others will use simply <code>app.com/page</code>.</p>
<p>But what about when you need to template in links to other sections of your app, but you&#8217;re not sure if the user&#8217;s browser supports <code>pushState</code>?</p>
<p>I got your back, bro. What this function does is inserts a hash <code>#</code> when pushState is not supported, so that inter-linking modules still get routed to the correct place.</p>
<p>Not sure if any of this makes sense, as currently a little tipsy &#8211; will update tomorrow with better info and examples.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.josscrowcroft.com/2011/code/a-little-url-generator-for-backbone-js/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic page generated in 0.411 seconds. -->
<!-- Cached page generated by WP-Super-Cache on 2012-02-23 09:32:00 -->

