<?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>QuirkeyBlog &#187; JavaScript</title>
	<atom:link href="http://www.quirkey.com/blog/category/javascript/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.quirkey.com/blog</link>
	<description>A Developer with too little time.</description>
	<lastBuildDate>Mon, 01 Aug 2011 16:07:38 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>Sammy 0.7: Boy Meets Girl</title>
		<link>http://www.quirkey.com/blog/2011/08/01/sammy-0-7-boy-meets-girl/</link>
		<comments>http://www.quirkey.com/blog/2011/08/01/sammy-0-7-boy-meets-girl/#comments</comments>
		<pubDate>Mon, 01 Aug 2011 13:00:07 +0000</pubDate>
		<dc:creator>AQ</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Sammy]]></category>
		<category><![CDATA[Software/Scripts]]></category>

		<guid isPermaLink="false">http://www.quirkey.com/blog/?p=541</guid>
		<description><![CDATA[Another long time in the making, Sammy 0.7 is here and its sexy. Check out the HISTORY and the full Changes to get the full details. The Boy of &#8220;Boy meets Girl&#8221; is Sammy, and the Girl is HTML5. Download it! It&#8217;s probably seemed like Sammy development had stopped a while ago. With all the [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://www.quirkey.com/skitch/boymeetsgirl-20110730-170414.png" alt="" /></p>
<p>Another long time in the making, Sammy 0.7 is here and its sexy. Check out the <a href="https://github.com/quirkey/sammy/blob/master/HISTORY.md"><span class="caps">HISTORY</span></a> and the full <a href="https://github.com/quirkey/sammy/compare/v0.6.3...v0.7.0">Changes</a> to get the full details. The Boy of &#8220;Boy meets Girl&#8221; is Sammy, and the Girl is HTML5.</p>
<p><a href="http://github.com/quirkey/sammy/tarball/v0.7.0">Download it!</a></p>
<span id="more-541"></span>
<p>It&#8217;s probably seemed like Sammy development had stopped a while ago. With all the other similar frameworks bouncing around these days, I&#8217;ll admit there were some dark days of doubt leading up to this release. In fact, most of the code that comprises Sammy 0.7 has been in the master branch for over 4 months. However, development and my belief in this project hasn&#8217;t wained, its more just that I&#8217;ve been completely consumed by my work at <a href="http://www.paperlesspost.com">Paperless Post</a> (and in a very good way). One of the benefits of leading the team there has been the ability to push the boundaries of what we can do with our code and our libraries. We use Sammy extensively at PP and I was super excited to have a use case and a way to develop and test this latest version and all its power. The big addition of HTML5 History support has made the big new app we&#8217;ve been working on for the past 6 months seamlessly deep-link between full urls and hash urls between multiple browsers. We&#8217;re pretty psyched about it.</p>
<h3>History is History</h3>
<p>Despite which side you fell in on in the <a href="http://www.quirkey.com/blog/2011/02/10/ish/">Great hashchange debacle of '11</a> you can&#8217;t argue with the pure fact that regular <span class="caps">URI</span> paths are just better than hash (#) paths. The makers of the great browsers of the world and the HTML5 History spec have a solution that attempts to appeal to everyone. The premise is simple &#8211; create a JS <span class="caps">API</span> for manipulating the full path of the current browsers location without forcing a page reload. Meaning, you can tell the url to change from <code>http://www.example.org/one</code> to <code>http://www.example.org/two</code> without having to reload the window, and allowing you to then manipulate the state of the page. Seems sort of like a dream, doesn&#8217;t it? Not only that but it really is a perfect fit for the way Sammy manages state and how Sammy applications are already built around routes and paths. I knew this was the case the first time I saw it, but I was unsure how to mix it with the existing hash based routing that works (and would have to persist) across every browser, not just the latest and greatest.</p>
<p>I believe Sammy 0.7 presents a pretty solid solution. Now, instead of routing on paths that look like <code>#/mypath</code> you just route on paths that look like a server side path <code>/mypath</code></p>
<div class="highlight"><pre><span class="kd">var</span> <span class="nx">Sammy</span><span class="p">(</span><span class="s1">&#39;#container&#39;</span><span class="o">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span><br />
  <span class="k">this</span><span class="p">.</span><span class="nx">use</span><span class="p">(</span><span class="s1">&#39;Mustache&#39;</span><span class="p">);</span><br />
<br />
  <span class="k">this</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;/&#39;</span><span class="o">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span><br />
    <span class="k">this</span><span class="p">.</span><span class="nx">partial</span><span class="p">(</span><span class="s1">&#39;templates/index.mustache&#39;</span><span class="p">);</span> <br />
  <span class="p">});</span><br />
<br />
  <span class="k">this</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;/:user&#39;</span><span class="o">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span><br />
    <span class="k">this</span><span class="p">.</span><span class="nx">load</span><span class="p">(</span><span class="s1">&#39;users/&#39;</span> <span class="o"><ins></span> <span class="k">this</span><span class="p">.</span><span class="nx">params</span><span class="p">.</span><span class="nx">user</span> <span class="o"></ins></span> <span class="s1">&#39;.json&#39;</span><span class="p">)</span><br />
        <span class="p">.</span><span class="nx">partial</span><span class="p">(</span><span class="s1">&#39;user.mustache&#39;</span><span class="p">);</span><br />
  <span class="p">});</span><br />
<br />
<span class="p">});</span><br />
</pre></div>
<p>The beauty and magic of above is a those routes will match both <code>quirkey.com/#!/aq</code> and <code>quirkey.com/aq</code> and execute the user route as expected. I&#8217;ve created a simple working example for you to play with at <a href="http://pushstate.quirkey.com/">http://pushstate.quirkey.com/</a> (source <a href="https://github.com/quirkey/sammy-pushstate">here</a>). We&#8217;ve been using and testing this for the past months and I can say its pretty solid (and pretty awesome).</p>
<p>There are some known caveats:</p>
<ul>
	<li>History only works in latest and greatest browsers (Chrome, FF5, Safari 4) but support for it is growing. Ben Cherry and the team at twitter also found some issues with certain versions of <a href="https://bugs.webkit.org/show_bug.cgi?id=42940">webkit and URLs getting out of sync (though its been resolved</a></li>
	<li>Your server side needs to be able to handle whatever urls you&#8217;re changing to. This means that if you route/redirect to something like <code>/path/one/two</code> in Sammy, the server better be able to handle that url as well and point you in the right direction. Otherwise, refreshing the browser will lead users to a 404 or worse. The <a href="https://github.com/quirkey/sammy-pushstate">sammy-pushstate</a> example has a pretty clever way of dealing with this in couchapps. It uses CouchDB rewrite rules to route any url request (minus the key files) to the index.html page (and hence allows sammy to handle the routing).</li>
	<li>Currently, mobile webkit (aka Mobile Safari and the Android browser) report support for pushState/History when in fact they don&#8217;t have it. Since I&#8217;ve tried to keep browser sniffing out of the core Sammy repo, it currently doesn&#8217;t detect for this. You can manually disable push state per application, though, and do the browser sniff yourself if you plan to use your app on mobile.</li>
	<li>This causes some possible breaking changes for upgrading Sammy apps. If you previously did any routing (or path checking) the path reported in a route (EventContext.prototype.path) is now the full path starting at <code>/</code> not just the path beyond the hash. Also HashLocationProxy was renamed to DefaultLocationProxy.</li>
</ul>
<p>That being said, its a pretty awesome feature and it makes writing Sammy apps really powerful when exposed to the full path. Theres more information in the <span class="caps">API</span> docs <a href="http://sammyjs.org/docs/api/0.7.0/all#Sammy.DefaultLocationProxy">here</a>.</p>
<h3>Templating engines are so 2010</h3>
<p>One thing thats frustrated a number of Sammy users is that previously all the template plugins (aka Sammy.Mustache, Sammy.Handlebars, etc) included the source for the engine in the plugin. In the beginning, I thought this was a great idea because it reduced the number of potential headaches and complaints of &#8216;Mustache isn&#8217;t working (because I didn&#8217;t include the source)&#8217;. However, what turned out to be a bigger issue was keeping up with all the plugins and their individual rapid development cycles. Because of this, all templating plugins (with the exception of Sammy.Template and Sammy.Meld) are now just simple wrappers and expect you to include the respective templating library in your own source. This also makes the case of using Mustache outside of Sammy in the same source/app as a Sammy.Mustache application a lot easier. For the sake of making the transition easier, the latest version of all of the engines is included in the repo (in <a href="https://github.com/quirkey/sammy/tree/master/vendor/templating">vendor/templating</a>).</p>
<h3>More!</h3>
<p>Those are  certainly the biggest things with this release but its also not the whole deal. There were <a href="https://github.com/quirkey/sammy/blob/master/HISTORY.md">12 other changes, bug fixes, and new plugins written by 10 different contributors!</a> I can&#8217;t thank the people who use and contribute patches and ideas back to Sammy, enough. You guys rock.</p>]]></content:encoded>
			<wfw:commentRss>http://www.quirkey.com/blog/2011/08/01/sammy-0-7-boy-meets-girl/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Get your Sammy.js Stickers</title>
		<link>http://www.quirkey.com/blog/2011/03/17/get-your-sammy-js-stickers/</link>
		<comments>http://www.quirkey.com/blog/2011/03/17/get-your-sammy-js-stickers/#comments</comments>
		<pubDate>Thu, 17 Mar 2011 23:47:15 +0000</pubDate>
		<dc:creator>AQ</dc:creator>
				<category><![CDATA[Geekery]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Sammy]]></category>

		<guid isPermaLink="false">http://www.quirkey.com/blog/?p=517</guid>
		<description><![CDATA[Thanks to the awesome folks at stickermule I now have a big stack of Sammy.js stickers I want to share with all you fine folks. There are a couple ways to get them: I&#8217;ll be at JSConf (duh) and a bunch of other meetups and get togethers until then, so just harass me for one [...]]]></description>
			<content:encoded><![CDATA[	<p><img src="http://farm6.static.flickr.com/5097/5536057210_5af9a85a17.jpg" alt="" border="0" /></p>

	<p>Thanks to the awesome folks at <a href="http://stickermule.com" title="">stickermule</a> I now have a big stack of Sammy.js stickers I want to share with all you fine folks. There are a couple ways to get them:</p>

	<ul>
		<li>I&#8217;ll be at JSConf (duh) and a bunch of other meetups and get togethers until then, so just harass me for one when you see me.</li>
		<li>If you live outside of <span class="caps">NYC</span> or the Bay Area, just send a self-addressed stamped envelope (MAIL &#8211; <span class="caps">I KNOW CRAZY</span>) to:</li>
	</ul>

	<p><blockquote><br />
Sammy.js Stickers<br />
c/o Paperless Post<br />
3130 24th St, Unit C<br />
San Francisco, <span class="caps">CA 94110</span><br />
</blockquote></p>

	<p>I&#8217;ll send you more than one, and you can sport it on your laptop like yours truly:</p>

	<p><img src="http://farm6.static.flickr.com/5054/5535479767_98c28bb67b.jpg" alt="" border="0" /></p>
 ]]></content:encoded>
			<wfw:commentRss>http://www.quirkey.com/blog/2011/03/17/get-your-sammy-js-stickers/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Flash Rules</title>
		<link>http://www.quirkey.com/blog/2011/03/08/flash-rules/</link>
		<comments>http://www.quirkey.com/blog/2011/03/08/flash-rules/#comments</comments>
		<pubDate>Tue, 08 Mar 2011 23:44:34 +0000</pubDate>
		<dc:creator>AQ</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Geekery]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.quirkey.com/blog/?p=503</guid>
		<description><![CDATA[I&#8217;m probably going to get in trouble for this, but I&#8217;ll let you in on a little secret. Your hatred of Flash is wrong and misplaced. I love web standards and I love the magical unicorn that is HTML5. I don&#8217;t hate Flash. Sure, I have my disagreements with it, but the &#8220;FLASH SUCKS&#8221; mantra [...]]]></description>
			<content:encoded><![CDATA[	<p>I&#8217;m probably going to get in trouble for this, but I&#8217;ll let you in on a little secret. Your hatred of Flash is wrong and misplaced. I love web standards and I love the magical unicorn that is <span class="caps">HTML5</span>. I don&#8217;t hate Flash. Sure, I have my disagreements with it, but the &#8220;FLASH <span class="caps">SUCKS</span>&#8221; mantra that was spawned with the iPhone and only gets louder and louder these days is just silly. Actually, it goes beyond that &#8211; not only is it pointless but its actually hurting the JavaScript and development community at large.</p>

	<p><span id="more-503"></span></p>

	<p>I&#8217;ve been around the block when it comes to web development and I&#8217;ve witnessed this sea change first hand. I&#8217;m not going to go in and recount war stories, but I&#8217;ve had my ups and downs working with Flash and Flash developers. I can&#8217;t really pinpoint a specific moment when people started to question it, but I remember working on a site for a high end fashion client and seeing early versions of script.aculo.us and just being blown away. It seemed so simple: this animated dropdown menu didnt need to be designed and compiled in an entirely different environment! It could all be <em>one thing</em>. Sure the animation was pretty chunky and yeah it might have crashed the occasional Firefox, but it seemed like magic &#8211; and I wanted more. It took some convincing, but we started to build out more and more outside of Flash and it felt great. Then there was the iPhone, and soon enough it all seemed so repulsive. You mean, I can&#8217;t see what kind of noodles this Thai Fusion place sells!? <em>argh</em>. I dont know how Apple did it, but wow, what a spin. Instead of blaming the device, or even better, the authors of these restaurant&#8217;s websites &#8211; we all started blaming Flash itself. <em><span class="caps">FLASH SUCKS</span></em> became the new mantra and we all went along with it. Like an angry mob with iPitchforks we stormed Flash&#8217;s castle.</p>

	<p>The result of all this yelling and vigorous finger pointing is in some ways what we all call <a href="http://www.html5rocks.com/" title=""><span class="caps">HTML5</span></a>. This glory train of hope, a beacon from a distant land where <em>everything</em> is a standard and you can order thai food from your phone. The hilarious thing however, is that as JavaScript developers the joke is on us.</p>

	<h3>Why People Hate Flash</h3>

	<p>Beyond the pure cargo-culting and the flash-blockers, some people at the heart of the argument do have their reasons. Lets take a brief detour from the main story to examine some of them.</p>

	<h4>It&#8217;s a proprietery product with a single owner</h4>

	<p>This is the con that most open source developers take issue with and something that hurts somewhere deep inside. As a very active open source developer, not only on my own projects, but as part of the community at large, I really don&#8217;t want to work on closed platforms. Since my first experience with open source and my first experience reporting, finding and fixing a bug, I haven&#8217;t turned back. Ruby, Rails, jQuery, etc. the benefits of open source are more than I can extol here. As a user, though, the core of <span class="caps">OSS</span> is transparency. It&#8217;s discovering a nasty bug and being able to effect change. This factor is obviously a range between projects but at some level, even if you don&#8217;t report a bug, it&#8217;s just knowing it&#8217;s there. It&#8217;s the knowledge that a <em>community</em> of people is willing and able to <em>fix</em> things. The lack of this is what instills fear in me when using software these days. As part of a team we&#8217;ve experienced bugs in Flash and reported them, and waited for a fix. When it&#8217;s something critical, sometimes you just want to be able to poke at the source. Even if it&#8217;s just to leave and say not my problem. I get this, it is a problem. I can&#8217;t really excuse this, other than saying that this same problem exists with <em>most</em> software and tools people use on a daily basis. Open Source is the exception, not the rule. Apple and the iPhone <span class="caps">SDK</span> is as much of a problem in this regard as Flash. Steve Jobs&#8217; saying that they&#8217;re commited to open source and standards by supporting Mobile Safari and Webkit doesnt mean that the <span class="caps">SDK</span> or the tools to compile iPhone apps are going to be open source any time soon.</p>

	<h4>It doesn&#8217;t work on my iPhone</h4>

	<p>This is true, it doesnt and that&#8217;s a problem. In <a href="http://www.apple.com/hotnews/thoughts-on-flash/" title="">Steve Jobs&#8217; angry missive</a> he blamed unreliable performance and battery draining as well as other things in their lack of support for Flash. I have an Android these days, and it is slow, but at the same time, it&#8217;s pretty useful to have Flash running on the device. Does it drain battery? Probably? No more than watching a video or checking Twitter every 20 seconds. Clearly there were other factors at work there, and I&#8217;m not blaming Apple really. It <strong>is</strong> annoying that a lot of sites <em>rely</em> on Flash at their core (in part Paperless Post is not exempt) but really that&#8217;s an issue with developement practices, not with Flash or the device.</p>

	<p>With or without Flash mobile is really a seperate concern. On mobile devices making something interactive, fast, and compatible is really the challenge.<br />
(In fact <strong>Interactive, Fast, Compatible</strong> is really the <a href="http://en.wikipedia.org/wiki/CAP_theorem" title=""><span class="caps">CAP</span></a> of mobile applications). Unfortunately the promise of <span class="caps">HTML5</span> only sort of solves this at this point. Have you used canvas on an iPad? It feels like you&#8217;re running Flash in <span class="caps">IE6</span> on a Pentium II. <span class="caps">SLOW</span>. Sure, there&#8217;s <span class="caps">CSS </span>Animation, but that really only takes you so far. I guarantee this will change in the next short while (years not months), but we&#8217;re talking about <em>now</em>.</p>

	<h4>It&#8217;s not crawlable by search engines</h4>

	<p>At its core this is true, but its just as true as with <span class="caps">AJAX</span> applications, as can be seen by the recent <a href="http://www.quirkey.com/blog/2011/02/10/ish/" title="">hash-bang hubub.</a> With Flash or JS you have the same challenges and roughly the same solutions. The most complete solution at this point is just to make a mobile or JS and Flash-free version that the more interactive version is a layer on top of. The fact that your restaurant&#8217;s website doesnt have an <span class="caps">HTML</span> menu is not Flash&#8217;s fault, its the developer&#8217;s fault for not making it accessible.</p>

	<h4>Its slow and crashy and makes my fans turn on</h4>

	<p>Yes, there are slow and buggy sites out there. Yes a lot of them have .swfs on them. Is Flash as a tool and platform really at fault here? Flash openened up the web to interactivity, high quality streaming video, and robust applications. As a tool it&#8217;s very very powerful. With great power comes great responsibility. It&#8217;s pretty easy to invoke a memory leak in Flash and it&#8217;s up to the developers to contain and optimize their apps. Again, this is really a problem of education and the development community at large. The most common target of this complaint are Flash based advertisements and banners. So an ad for body spray takes over your page, and seems to slow your whole computer down. Thats pretty annoying. Well just wait for <span class="caps">DOM</span>/canvas based ads. They&#8217;re coming, and they&#8217;re manipulating your entire page and breaking your JS. Just you wait.</p>

	<h3>A couple of reasons to love Flash</h3>

	<p>At the same time, and despite all the yelling, there are some clear reasons to still love Flash. It was the first to do a lot of these things we now call <span class="caps">HTML5</span> on the web. In many and maybe most cases it&#8217;s still better at doing them. In particular, while <span class="caps">HTML5</span> video works pretty well on certain devices and browsers, it&#8217;s pretty far behind its Flash counterpart in terms of speed and general functionality. Fonts as well. One of the sticking points we&#8217;ve had at Paperless Post is the lack of detailed font controls and especially interactivity with fonts. Sure @font-face is nice, but it has its limitations and compatibility issues when it comes to pixel perfect rendering. Canvas fonts are even worse.</p>

	<p>Flash is also pretty much everywhere. Besides the iThings, Android, your browser (every browser) its there and works almost exactly the same. That&#8217;s pretty sweet. It was one of Flash&#8217;s original promises and it still rings true (with one major exception). The proprietary thing also comes in handy in this respect, too. I&#8217;m not agreeing with it, but when a bug is fixed or a security hole is patched, updates come rather quickly to your end users. This is as compared to the wide range of browser release cycles.</p>

	<p>From a development standpoint, ActionScript is  close to something we know and love (presumably): <span class="caps">ECMA</span>Script. Newer versions have added more Java-like package management but a lot of the syntax (; and {}) et al will be very familiar. If you have only ever programmed on the Flash timeline, you would also know that most ActionScript apps are coded in a normal editor of your choosing and compiled on the command line. In fact, there&#8217;s a pretty cool project generation and build tool for ActionScript in Ruby called <a href="http://projectsprouts.org/" title="">sproutes</a>. Its syntax tends to lean more towards the Java and less towards the script, but it&#8217;s still very easy to pick up. In fact, I jumped in to one of our projects at Paperless recently and was able to code up a bunch of a module in a single day with only passing help from our resident <span class="caps">AS3</span> expert.</p>

	<h3>There is hope: quit being an asshole.</h3>

	<p>That all is great, but it misses the biggest and best thing that Flash has &#8211; a thriving community of extremely talented developers. Its not uncommon to find a Flash developer at this point with > 10 years experience coding in Flash for the web. 10+ years! How many years have you been programming JavaScript professionally? For how many years has it been your primary focus? How many large scale interactive applications have you built? My guess is that the average Flash developer has built 20 times that. For good reasons. Not only have they had better tools for most of that time, but they&#8217;ve also been in heavy demand for that whole time, and building applications non-stop. Many of the challenges that JS and <span class="caps">HTML5</span> developers are facing when building these large scale interactive apps, the Flash developers have already solved. They have those algorithms, that knowledge of 3D, that ability to turn code into motion and excitement.</p>

	<p>As a talented Flash developer, you&#8217;re probably starting to explore the world of <span class="caps">HTML5</span> and canvas and in some cases Cocoa and Objective-C. You&#8217;re starting to learn how to adapt your Flash expertise to this brave new world. In some cases you&#8217;re pretty put-off by the attitude of the JS community and its blind hatred of a tool and framework that you&#8217;ve devoted a portion of your career to up to this point. Understandably. A lot of these people are being assholes. If you devoted a lot of your waking hours to Java, it was and is really hard to want to ease into Ruby due to the bile and anti-you sentiment coming from the Ruby community. Over time, Ruby has adapted to its community and its forebearers (see <a href="http://jruby.org/" title="">JRuby</a>).</p>

	<p>As a JavaScript developer, it&#8217;s now your responsibility to stop the hate and welcome these super smart developers with open arms. Ask them questions, lean on them for advice, for hacks, for problem-solving. Hire them, even! They will appreciate it and they will blow your socks off. The best Flash developers aren&#8217;t tied to a language or technology, they&#8217;re just really interested in making awesome, boundary-pushing applications for the web. The fact is that they&#8217;re moving this way with or without you. If you help them, and respect them, and learn from them, your app and eventually the entire web will be a better place. If you shun them, they&#8217;ll just do what you do, but do it better. They&#8217;ve already done all the things that you&#8217;re trying to accomplish.</p>

	<p>Flash isn&#8217;t going anywhere for a little while, and complaining about it doesn&#8217;t help. Instead let&#8217;s all quit being assholes and work together to push the open web and open standards. Most importantly, let&#8217;s learn from all our mistakes and triumphs and hacks and continue to make the <em>now</em> web more fun.</p>

 ]]></content:encoded>
			<wfw:commentRss>http://www.quirkey.com/blog/2011/03/08/flash-rules/feed/</wfw:commentRss>
		<slash:comments>22</slash:comments>
		</item>
		<item>
		<title>#-ish</title>
		<link>http://www.quirkey.com/blog/2011/02/10/ish/</link>
		<comments>http://www.quirkey.com/blog/2011/02/10/ish/#comments</comments>
		<pubDate>Thu, 10 Feb 2011 23:19:15 +0000</pubDate>
		<dc:creator>AQ</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Ranting]]></category>
		<category><![CDATA[Sammy]]></category>

		<guid isPermaLink="false">http://www.quirkey.com/blog/?p=494</guid>
		<description><![CDATA[I&#8217;ve been sitting back and watching from the sidelines this week as a lot of smart people [de]ride the hash (or more specifically the #!). Most of this has come from the recent switchover of the gawker media properties to using a new URL structure based on the !# and a JavaScript app to load [...]]]></description>
			<content:encoded><![CDATA[	<p>I&#8217;ve been sitting back and watching from the sidelines this week as <a href="http://simonwillison.net/tags/hashbanghell/" title="">a lot of smart people [de]ride the hash</a> (or more specifically the #!). Most of this has come from the recent switchover of the gawker media properties to using a new <span class="caps">URL</span> structure based on the !# and a JavaScript app to load content. As someone <a href="http://sammyjs.org" title="">who&#8217;s invested a lot of time into the #</a> I want to make something clear &#8211; as with many things in life, the hash is no different: It&#8217;s not broken, its how you use it.</p>

	<p><span id="more-494"></span></p>

	<h3>Deep Linking</h3>

	<p>Let&#8217;s take a little trip down memory lane, shall we? My first interaction with the &#8216;#&#8217; as a method for getting at specific content (not as an anchor tag) was working in the ad/interactive space and with a lot of Flash developers. On every proposal or statement of work was a line about &#8216;Deep Linking&#8217;. In this case it meant plugging in <a href="http://www.asual.com/swfaddress/" title="">swfaddress</a> and wiring it up to your fancy Flash slideshow or fashion showcase. The point of this all was that when you clicked on the 8pt text in the menu that said &#8216;MENS <span class="caps">BLOUSES</span>&#8217; you would be taken to the photo of a puffy shirt and the url would change to &#8216;#/items/puffy-shirt&#8217;. When you refreshed the page, or sent the link to your friend you would be taken immediately to the puffy shirt and be able to bask in its frilly glory without navigating through the 8pt menu again.</p>

	<p>This was a big thing! Big, as in exciting and awesome, because it meant you could build relatively complex Flash applications, felt &#8216;stateful&#8217; somehow. You would navigate somewhere and you&#8217;d be <em>there</em>, not in the middle of nowhere.</p>

	<p>An important thing to note here is that this was not for Google. It was Flash. Google can&#8217;t crawl Flash. The point was allowing people to &#8216;Skip intro&#8217; and have them feeling that this crazy interactive experience wasn&#8217;t all that different from there normal browsing. For crawling and <span class="caps">SEO</span> there were a host of other strategies &#8211; <span class="caps">META</span> tags, &#8216;ghost&#8217; static <span class="caps">HTML</span> sites, etc. &#8211; and these were deployed alongside &#8216;Deep Linking&#8217; as two different strategies trying to accomplish different things.</p>

	<h3><span class="caps">AJAX FOR THE PEOPLE</span></h3>

	<p>We&#8217;ve moved on (sort of) from the days of 8pt menus and pixel fonts. The old problem is new all over again. Now we&#8217;ve built these applications that rely on JavaScript being enabled to construct our site and fetch our data and animate our menus. Awesome! Its <span class="caps">HTML5</span>-tastic. At some point, we discovered the same problems that we had with Flash. Namely, when you&#8217;re loading all your content with <span class="caps">AJAX</span> and loading it onto the page based on clicks, you get lost in a sea of asynchronicity. What <strong>state</strong> are you in? Clearly, there&#8217;s an easy way to solve this &#8211; use the &#8216;#&#8217; to <strong>route</strong> URLs without reloading the page and <strong>Deep Linking</strong> directly into content. I created and continue to work on <a href="http://sammyjs.org" title="">Sammy.js</a>, partly, as a solution to this problem. You want your application to feel interactive and fluid, you want to avoid page reloads, but <em>when</em> the user does reload, or copy the link, they should be taken back to the same place.</p>

	<p>Then, confusion sets in. In a world where <a href="http://www.readwriteweb.com/archives/facebook_wants_to_be_your_one_true_login.php" title="">the only way people get to Facebook is by Googling Facebook</a> you want your site to be &#8216;googleable&#8217;. This presents a problem: your application is dependent on javascript and &#8216;#&#8217; and google don&#8217;t know about those. Well then, brotha, Google&#8217;s <a href="http://code.google.com/web/ajaxcrawling/docs/getting-started.html" title="">got your back</a>. All you have to do is put a little ! after your # and tell google where to fetch your content and it&#8217;s like <span class="caps">BLAM</span>: <strong><span class="caps">SEO</span></strong>.</p>

	<p>Except, no.</p>

	<p>This is the part where I want to shake everyone. Like physically shake and be like &#8220;YOU! <span class="caps">YOU</span>&#8217;RE <span class="caps">MISSING THE POINT</span>&#8221;.</p>

	<p>There are two different things. Crawlability and Deep Linking are two different things. For different reasons and different goals, and conflating them not only makes it hard on users, but also makes it hard on developers. You end up doing neither of them right.</p>

	<p>I&#8217;ve been asked about a million times now, &#8220;How do you do <span class="caps">SEO</span> with Sammy?&#8221;. The answer is never simple, because its the wrong question. The question should really be &#8211; &#8220;If I&#8217;m really concerned about <span class="caps">SEO</span>, the crawlability of my site, and the persitance of my links should I use Sammy?&#8221;. The answer without a doubt is <strong>No</strong>. I&#8217;ll be the first one to say that Sammy and other similar frameworks are not for every site. <strong>Period</strong>. Theres no reason that your blog or your news site needs to load all its content with <span class="caps">AJAX</span> or needs to use &#8216;#&#8217; to route for state. An important disctinction in what I&#8217;m trying to say is that its &#8220;you shouldnt have to&#8221; not &#8220;you never should&#8221;. If you&#8217;re building a site like Gizmodo you should pretty much always at least <span class="caps">START</span> with good ol&#8217; semi-static pages that dont require JavaScript and load at old-fashioned URLs. This is not to say that you can&#8217;t build an application <em>on top of</em> these static pages that is more dynamic and interactive and relies on JavaScript.</p>

	<p>Sammy and the &#8216;#&#8217; are for applications. It provides a way to maintain state in a world where you <em>can</em> require JavaScript and even require the presence of certain browsers. If you&#8217;re an application, that requires login/signup you can make a number of demands of your users. You also probably dont even <em>want</em> the crawlability. You&#8217;re using &#8216;#&#8217; to maintain state for a specific user in a specific session.</p>

	<p>Outside of the world of the &#8216;application&#8217; you really, really shouldn&#8217;t rely on JavaScript being there for your site to work (at least at a basic level). <a href="http://jsconf.eu/2010/speaker/javascript_web_standards_ii_th.html" title="">Jen Lukas has already talked really eloquently about why thats the case.</a> I believe that this is where a lot of the recent frustration has come from, and really it should be directed at the use case, not the overall usage of &#8216;#&#8217; for state. There have been some fingers pointed at Google for making this conflation possible, and I tend to agree.</p>

	<h3>How to do this right</h3>

	<p>I&#8217;m not going to go into detail about what framework you should use or how to lay out your app. Those are fairly complicated and my opinions could take up a couple blog posts. However, the basics are straightforward.</p>

	<p>First, you need to determine some things about the structure of what you&#8217;re building and what your content is. Are you building an &#8216;application&#8217; or a site? Does your content need to be searchable and reachable by the entire web? Do your links require true permanance and will changing them in the future &#8220;break&#8221; traffic to your site?</p>

	<p>If you need searchability and permancance and you&#8217;re <em>not</em> building an application, the real best way to approach is to build your site as if JavaScript doesn&#8217;t exist. The fact is that there&#8217;s still a chunk of users for which that will be true. Not only because they&#8217;re using old browsers, but they&#8217;re on phones, or they&#8217;re on assistive devices or they just turn JavaScript off for &#8216;security&#8217; reasons. If your site works this way and looks pretty decent (meaning its readable and the content is accessible) then basically you&#8217;re good. Golden. Your site works as expected, but maybe not all <span class="caps">AJAAAAZZAY</span>. It&#8217;s at this point that it&#8217;s acceptable to build a layer on top of your existing site, sprinkle the magic dust.</p>

	<p>Twitter is an interesting example here because they took what was at its core really an information site, not all that different from a blog and turned it into an application. The questions of <span class="caps">URL</span> permanence are really gray here but I dont find myself hating it at all.</p>

	<p>Web standards are at the core of this debate. Many make a strong argument that concept of the <span class="caps">URL</span> and <span class="caps">HTTP</span> is here for a reason, that URLs have worked and continue to work. I think instead of fueling <span class="caps">FUD</span>, we should get back to the work of building a better standard and a better web.</p>

	<p><hr /></p>

	<h4>A brief epilogue on pushState/HTML5 History</h4>

	<p>A lot of people are pointing to the new <span class="caps">HTML5 </span>History <span class="caps">API</span> as a much better solution to this problem. I agree with reservations. First, the browser support for this currently isn&#8217;t very wide, and certain browsers that do support it have buggy/broken implementations. The bottom line is that it will work in some places, but not most, and this will probably be the case for years to come. That said, it <strong>is</strong> really exciting and I&#8217;m working on built in support for it in the next version of Sammy.js. I have other reservations, too &#8211; namely I think that not all hashes are created equal and in some cases the state you want to represent is really the state of a specific page <em>not</em> a seperate page that really requires a fully seperate <span class="caps">URL</span>.</p>

 ]]></content:encoded>
			<wfw:commentRss>http://www.quirkey.com/blog/2011/02/10/ish/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>SammyJS.org</title>
		<link>http://www.quirkey.com/blog/2011/01/27/sammyjs-org/</link>
		<comments>http://www.quirkey.com/blog/2011/01/27/sammyjs-org/#comments</comments>
		<pubDate>Thu, 27 Jan 2011 19:50:12 +0000</pubDate>
		<dc:creator>AQ</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Sammy]]></category>
		<category><![CDATA[Software/Scripts]]></category>

		<guid isPermaLink="false">http://www.quirkey.com/blog/?p=486</guid>
		<description><![CDATA[Sammy.js is finally official because now we have a real dedicated website: http://sammyjs.org. It only took two years. Along with the website the logo I designed before JSConf.eu last year now has an official place to proudly be displayed. Since we&#8217;re a REAL project now, we&#8217;re also starting up the SWAG train, so logo stickers [...]]]></description>
			<content:encoded><![CDATA[	<p><a href="http://sammyjs.org"><img src="http://www.quirkey.com/skitch/Sammy.js___A_Small_Web_Framework_with_Class___RESTFul_Evented_JavaScript-20110127-114132.jpg" alt="sammyjs.org" width="550" height="386" /></a></p>

	<p>Sammy.js is finally official because now we have a real dedicated website: <a href="http://sammyjs.org" title="">http://sammyjs.org</a>. It only took two years.</p>

	<p>Along with the website the logo I designed before JSConf.eu last year now has an official place to proudly be displayed. Since we&#8217;re a <span class="caps">REAL</span> project now, we&#8217;re also starting up the <span class="caps">SWAG</span> train, so logo stickers are on their way.</p>

	<p>The biggest change with the new site is the <span class="caps">API</span> documentation has been <a href="http://sammyjs.org/docs/api/stable" title="">significantly cleaned up</a>. The text is still being generated from the code itself, but now we have easier navigation, the ability to keep multiple versions of the docs (generated per release) and probably the most fun &#8211; method level comments powered by Sammy users and contributors, <a href="http://disqus.com" title=""><span class="caps">DISQUS</span></a>. I&#8217;ve made good use of the method level comments featured in sites like <a href="http://apidock.com" title="">apidock</a> so I&#8217;m very excited to see if the community participates here.</p>

	<p>Sammy.js is growing up and its been so much fun to see how and where people use it. I don&#8217;t see that many big changes in the future for it before we push a real 1.0 (See a <a href="http://groups.google.com/group/sammyjs/browse_frm/thread/cd17332e9e82abc6" title="">brief roadmap on the mailing list</a>) and a big goal is to get push the big one oh before this year&#8217;s <a href="http://2011.jsconf.us" title="">JSConf in Portland.</a></p>
 ]]></content:encoded>
			<wfw:commentRss>http://www.quirkey.com/blog/2011/01/27/sammyjs-org/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Getting to know Sammy.js: Helpers</title>
		<link>http://www.quirkey.com/blog/2010/11/04/getting-to-know-sammy-js-helpers/</link>
		<comments>http://www.quirkey.com/blog/2010/11/04/getting-to-know-sammy-js-helpers/#comments</comments>
		<pubDate>Thu, 04 Nov 2010 12:07:08 +0000</pubDate>
		<dc:creator>AQ</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Sammy]]></category>
		<category><![CDATA[Software/Scripts]]></category>

		<guid isPermaLink="false">http://www.quirkey.com/blog/?p=475</guid>
		<description><![CDATA[For part of this month&#8217;s writing I&#8217;m going to write focused posts about features of Sammy.js that people may not know about or have used. In the end I hope to compile these into part of the new Sammy.js site. A question came up on the mailing list recently about overriding previously defined routes after [...]]]></description>
			<content:encoded><![CDATA[<p><em>For part of this month&#8217;s writing I&#8217;m going to write focused posts about features of Sammy.js that people may not know about or have used. In the end I hope to compile these into part of the new Sammy.js site.</em></p>
<p>A question came up on the <a href="http://groups.google.com/group/sammyjs/browse_frm/thread/8234ef63d20c99ae/580e66ac59a483cf">mailing list recently about overriding previously defined routes</a> after struggling thinking of how to do this with the current codebase, the answer was simple: Use helpers!</p>
<p>Coming from Sinatra or Rails the idea of <code>helpers</code> might be associated with just &#8220;view helpers&#8221; &#8211; methods added to the controller which are passed down to the view to help refactor/encapsulate common view logic. In Sammy.js helpers are really a way of refactoring common logic out of routes and into a reusable named method.</p>
<span id="more-475"></span>
<h3>Refactorin&#8217;</h3>
<p>In any app you&#8217;ll have startup code or code that needs to be run for every or multiple pages (routes). In Sammy this might looks like:</p>
<div class="highlight"><pre><span class="nx">$</span><span class="p">.</span><span class="nx">sammy</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span><br />
  <br />
  <span class="k">this</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;#/&#39;</span><span class="o">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span><br />
    <span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">params</span><span class="p">.</span><span class="nx">grid</span><span class="p">)</span> <span class="p">{</span><br />
      <span class="k">this</span><span class="p">.</span><span class="nx">$element</span><span class="p">().</span><span class="nx">addClass</span><span class="p">(</span><span class="s1">&#39;grid&#39;</span><span class="p">);</span><br />
    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span><br />
      <span class="k">this</span><span class="p">.</span><span class="nx">$element</span><span class="p">().</span><span class="nx">removeClass</span><span class="p">(</span><span class="s1">&#39;grid&#39;</span><span class="p">);</span><br />
    <span class="p">}</span><br />
    <span class="k">this</span><span class="p">.</span><span class="nx">partial</span><span class="p">(</span><span class="s1">&#39;index.html&#39;</span><span class="p">);</span><br />
  <span class="p">});</span><br />
  <br />
  <span class="k">this</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;#/user&#39;</span><span class="o">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span><br />
    <span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">params</span><span class="p">.</span><span class="nx">grid</span><span class="p">)</span> <span class="p">{</span><br />
      <span class="k">this</span><span class="p">.</span><span class="nx">$element</span><span class="p">().</span><span class="nx">addClass</span><span class="p">(</span><span class="s1">&#39;grid&#39;</span><span class="p">);</span><br />
    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span><br />
      <span class="k">this</span><span class="p">.</span><span class="nx">$element</span><span class="p">().</span><span class="nx">removeClass</span><span class="p">(</span><span class="s1">&#39;grid&#39;</span><span class="p">);</span><br />
    <span class="p">}</span><br />
    <span class="k">this</span><span class="p">.</span><span class="nx">partial</span><span class="p">(</span><span class="s1">&#39;user.html&#39;</span><span class="p">);</span><br />
  <span class="p">});</span><br />
  <br />
<span class="p">})</span><br />
</pre></div>
<p>A contrived example, but you can tell we&#8217;re doing almost the exactly same thing in each of the routes. A common JS convention and something you could do pretty easily here, would just be to extract the functionality out into a closure/function and call it for each route.</p>
<div class="highlight"><pre><span class="nx">$</span><span class="p">.</span><span class="nx">sammy</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span><br />
  <br />
  <span class="kd">var</span> <span class="nx">displayGrid</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">$element</span><span class="o">,</span> <span class="nx">display</span><span class="p">)</span> <span class="p">{</span><br />
    <span class="k">if</span> <span class="p">(</span><span class="nx">display</span><span class="p">)</span> <span class="p">{</span><br />
      <span class="nx">$element</span><span class="p">.</span><span class="nx">addClass</span><span class="p">(</span><span class="s1">&#39;grid&#39;</span><span class="p">);</span><br />
    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span><br />
      <span class="nx">$element</span><span class="p">.</span><span class="nx">removeClass</span><span class="p">(</span><span class="s1">&#39;grid&#39;</span><span class="p">);</span><br />
    <span class="p">}</span><br />
  <span class="p">};</span><br />
  <br />
  <span class="k">this</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;#/&#39;</span><span class="o">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span><br />
    <span class="nx">displayGrid</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">$element</span><span class="p">()</span><span class="o">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">params</span><span class="p">.</span><span class="nx">grid</span><span class="p">);</span><br />
    <span class="k">this</span><span class="p">.</span><span class="nx">partial</span><span class="p">(</span><span class="s1">&#39;index.html&#39;</span><span class="p">);</span><br />
  <span class="p">});</span><br />
  <br />
  <span class="k">this</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;#/user&#39;</span><span class="o">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span><br />
    <span class="nx">displayGrid</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">$element</span><span class="p">()</span><span class="o">,</span> <span class="k">this</span><span class="p">.</span><span class="nx">params</span><span class="p">.</span><span class="nx">grid</span><span class="p">);</span><br />
    <span class="k">this</span><span class="p">.</span><span class="nx">partial</span><span class="p">(</span><span class="s1">&#39;user.html&#39;</span><span class="p">);</span><br />
  <span class="p">});</span><br />
  <br />
<span class="p">})</span><br />
</pre></div>
<p>This works, it prevents global leakage by declaring it inside the app, and it gets rid of a number of lines of repetitive code. However, we&#8217;re still passing a bunch of route attributes into the closure. This is where helpers can shine.</p>
<div class="highlight"><pre><span class="nx">$</span><span class="p">.</span><span class="nx">sammy</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span><br />
  <br />
  <span class="k">this</span><span class="p">.</span><span class="nx">helpers</span><span class="p">({</span><br />
    <span class="nx">displayGrid</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span><br />
      <span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">params</span><span class="p">.</span><span class="nx">grid</span><span class="p">)</span> <span class="p">{</span><br />
        <span class="k">this</span><span class="p">.</span><span class="nx">$element</span><span class="p">().</span><span class="nx">addClass</span><span class="p">(</span><span class="s1">&#39;grid&#39;</span><span class="p">);</span><br />
      <span class="p">}</span> <span class="k">else</span> <span class="p">{</span><br />
        <span class="k">this</span><span class="p">.</span><span class="nx">$element</span><span class="p">().</span><span class="nx">removeClass</span><span class="p">(</span><span class="s1">&#39;grid&#39;</span><span class="p">);</span><br />
      <span class="p">}</span><br />
  <span class="p">});</span><br />
  <br />
  <span class="k">this</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;#/&#39;</span><span class="o">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span><br />
    <span class="k">this</span><span class="p">.</span><span class="nx">displayGrid</span><span class="p">();</span><br />
    <span class="k">this</span><span class="p">.</span><span class="nx">partial</span><span class="p">(</span><span class="s1">&#39;index.html&#39;</span><span class="p">);</span><br />
  <span class="p">});</span><br />
  <br />
  <span class="k">this</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;#/user&#39;</span><span class="o">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span><br />
    <span class="k">this</span><span class="p">.</span><span class="nx">displayGrid</span><span class="p">();</span><br />
    <span class="k">this</span><span class="p">.</span><span class="nx">partial</span><span class="p">(</span><span class="s1">&#39;user.html&#39;</span><span class="p">);</span><br />
  <span class="p">});</span><br />
  <br />
<span class="p">});</span><br />
</pre></div>
<p>This looks a lot cleaner to me. You might not love <code>this</code> but it makes some things really magical. By making <code>displayGrid</code> a helper it automagically has access to the context of the current route. That means that just like the route&#8217;s callback, it has access to everything in the <code>EventContext</code> including <code>params</code>, <code>redirect</code>, <code>render</code> and <em>other helpers</em>. This is important, because it basically allows you to extract common code from routes into helpers and then refactor those helpers even further into <em>other</em> helpers.</p>
<h3>stOOPid inheritance and mixins</h3>
<p>Helpers are actually just methods on the app&#8217;s <code>EventContext</code> prototype, and event though there&#8217;s no classical inheritance with <code>super</code>&#8217;s and all that jazz we can do some fun <span class="caps">OOP</span>-like magic.</p>
<p>In the example from the mailing list, we wanted to override an application&#8217;s existing route with a new route. Though the way routes are stored and handled makes it difficult on the app level, doing it on the helper level is EZ:</p>
<div class="highlight"><pre><span class="c">// initializing a new app</span><br />
<span class="kd">var</span> <span class="nx">app</span> <span class="o">=</span> <span class="nx">$</span><span class="p">.</span><span class="nx">sammy</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span><br />
  <br />
  <span class="k">this</span><span class="p">.</span><span class="nx">helpers</span><span class="p">({</span><br />
    <span class="c">// define a helper to load the index as the default behavior</span><br />
    <span class="nx">loadIndex</span><span class="o">:</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span><br />
      <span class="k">this</span><span class="p">.</span><span class="nx">partial</span><span class="p">(</span><span class="s1">&#39;index.html&#39;</span><span class="p">);</span><br />
    <span class="p">}</span><br />
  <span class="p">});</span><br />
  <br />
  <span class="k">this</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;#/&#39;</span><span class="o">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span><br />
    <span class="k">this</span><span class="p">.</span><span class="nx">loadIndex</span><span class="p">();</span><br />
  <span class="p">});</span><br />
<span class="p">});</span><br />
<br />
<span class="c">// override the specific helper, and hence the index route</span><br />
<span class="c">// we can also do this by calling `helpers()`</span><br />
<span class="nx">app</span><span class="p">.</span><span class="nx">helper</span><span class="p">(</span><span class="s1">&#39;loadIndex&#39;</span><span class="o">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span><br />
  <span class="k">this</span><span class="p">.</span><span class="nx">partial</span><span class="p">(</span><span class="s1">&#39;specialindex.html&#39;</span><span class="p">);</span><br />
<span class="p">});</span><br />
</pre></div>
<p><code>use()</code> is how Sammy includes a plugin in an app. A plugin is really just another app function, though, that get&#8217;s evaluated at the time you <code>use()</code> it. In fact, when you call <code>$.sammy()</code> you&#8217;re just creating a new instance of <code>Sammy.Application</code> and then calling <code>use()</code> on it with the app function. This is a simple way of doing &#8220;mixin&#8221; style inheritance. A plugin can do anything an app can, including and <em>especially</em> helpers. So with multiple apps we be all like tag team:  <a href="http://www.youtube.com/watch?v=Z-FPimCmbX8"><span class="caps">OOP</span> there it is</a></p>
<div class="highlight"><pre><span class="nx">$</span><span class="p">.</span><span class="nx">sammy</span><span class="p">(</span><span class="s1">&#39;#hiphop&#39;</span><span class="o">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span><br />
  <span class="k">this</span><span class="p">.</span><span class="nx">helpers</span><span class="p">({</span><br />
    <span class="nx">playCatchPhrase</span><span class="o">:</span> <span class="nx">$</span><span class="p">.</span><span class="nx">noop</span><br />
    <span class="c">// noop there it is </span><br />
    <span class="c">// this is sort of like an abstract method</span><br />
  <span class="p">});</span><br />
  <br />
  <span class="k">this</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;#/catchphrase&#39;</span><span class="o">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span><br />
    <span class="k">this</span><span class="p">.</span><span class="nx">playCatchPhrase</span><span class="p">();</span><br />
  <span class="p">})</span><br />
<span class="p">});</span><br />
<br />
<span class="kd">var</span> <span class="nx">atlanta</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span><br />
  <span class="k">this</span><span class="p">.</span><span class="nx">helper</span><span class="p">(</span><span class="s1">&#39;playCatchPhrase&#39;</span><span class="o">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span><br />
    <span class="nx">alert</span><span class="p">(</span><span class="s1">&#39;whoomp there it is!&#39;</span><span class="p">);</span><br />
  <span class="p">});</span><br />
<span class="p">};</span><br />
<br />
<span class="kd">var</span> <span class="nx">la</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span><br />
  <span class="k">this</span><span class="p">.</span><span class="nx">helper</span><span class="p">(</span><span class="s1">&#39;playCatchPhrase&#39;</span><span class="o">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span><br />
    <span class="nx">alert</span><span class="p">(</span><span class="s1">&#39;do the hump!&#39;</span><span class="p">);</span><br />
  <span class="p">});</span><br />
<span class="p">};</span><br />
<br />
<span class="nx">$</span><span class="p">.</span><span class="nx">sammy</span><span class="p">(</span><span class="s1">&#39;#hiphop&#39;</span><span class="p">).</span><span class="nx">use</span><span class="p">(</span><span class="nx">la</span><span class="p">);</span><br />
<span class="c">// get &#39;#/catchphrase&#39; //=&gt; &#39;do the hump!&#39;</span><br />
</pre></div>
<p>Thats still pretty simple, though combining these ideas is actually pretty powerful. Almost all of Sammy&#8217;s existing plugins are based on this simple approach. I&#8217;m hoping soon, it can get even more abstract and complex. Why not a <code>Sammy.Auth</code> that handles displaying/posting/and doing all the basic authentication? You could use helpers for most of the dirty work and then one could just override the defaults in their specific apps. You could even create <em>another</em> set of plugins that were different displays or authentication systems that override the simple base methods. Do it! ( <em>so I dont have to</em> )</p>]]></content:encoded>
			<wfw:commentRss>http://www.quirkey.com/blog/2010/11/04/getting-to-know-sammy-js-helpers/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sammy.js Tutorial finally updated for 0.6</title>
		<link>http://www.quirkey.com/blog/2010/11/02/sammy-js-tutorial-finally-updated-for-0-6/</link>
		<comments>http://www.quirkey.com/blog/2010/11/02/sammy-js-tutorial-finally-updated-for-0-6/#comments</comments>
		<pubDate>Tue, 02 Nov 2010 05:45:46 +0000</pubDate>
		<dc:creator>AQ</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Sammy]]></category>
		<category><![CDATA[Software/Scripts]]></category>

		<guid isPermaLink="false">http://www.quirkey.com/blog/?p=466</guid>
		<description><![CDATA[The title really says it all but this has been a long time coming. Since the RenderContext changes in 0.6 there were some incompatibilities between the code in the tutorial and what actually worked. It wasn&#8217;t just an easy swap of method names &#8211; I spent some actual time today rewriting some big chunks of [...]]]></description>
			<content:encoded><![CDATA[	<p>The title really says it all but this has been a long time coming. Since the RenderContext changes in 0.6 there were some incompatibilities between the code in the tutorial and what actually worked. It wasn&#8217;t just an easy swap of method names &#8211; I spent some actual time today rewriting some big chunks of the first tutorial and adding an introduction to the RenderContext. The example app (<a href="http://github.com/quirkey/the_json_store" title="">The <span class="caps">JSON </span>Store</a>) was also updated.</p>

	<p>I&#8217;ve been thinking about part <span class="caps">III</span> and beyond as well, but thats for another day. I hope at least this fixes a lot of the confusion for people delving into Sammy for the first time.</p>

	<p><a href="http://code.quirkey.com/sammy/tutorials/" title="">Check out the new tutorials here.</a></p>
 ]]></content:encoded>
			<wfw:commentRss>http://www.quirkey.com/blog/2010/11/02/sammy-js-tutorial-finally-updated-for-0-6/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Sammy 0.6: California Suite</title>
		<link>http://www.quirkey.com/blog/2010/09/02/sammy-0-6-california-suite/</link>
		<comments>http://www.quirkey.com/blog/2010/09/02/sammy-0-6-california-suite/#comments</comments>
		<pubDate>Thu, 02 Sep 2010 13:18:12 +0000</pubDate>
		<dc:creator>AQ</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Sammy]]></category>
		<category><![CDATA[Software/Scripts]]></category>

		<guid isPermaLink="false">http://www.quirkey.com/blog/?p=453</guid>
		<description><![CDATA[It&#8217;s a couple months in the making, but I&#8217;m happy to say that Sammy.js 0.6 is finally here. Check out the HISTORY and the Changes. I&#8217;m calling this release the California Suite in honor of my move to the West Coast and the fact that I did most of this coding on the plane back [...]]]></description>
			<content:encoded><![CDATA[<p><img src="http://img.skitch.com/20100831-11assdyxnsmqepn2aftj5mu4kr.png" alt="" /></p>
<p>It&#8217;s a couple months in the making, but I&#8217;m happy to say that <a href="http://code.quirkey.com/sammy">Sammy.js</a> 0.6 is finally here. Check out the <a href="http://github.com/quirkey/sammy/blob/master/HISTORY.md"><span class="caps">HISTORY</span></a> and the <a href="http://github.com/quirkey/sammy/compare/v0.5.4...v0.6.0">Changes</a>. I&#8217;m calling this release the California Suite in honor of my move to the West Coast and the fact that I did most of this coding on the plane back and forth. There are some awesome big new features that I&#8217;ve been using for a little while now and I can say are a big improvement over previous releases.</p>
<p><a href="http://github.com/quirkey/sammy/tarball/v0.6.0">Download it!</a></p>
<p>Before I get to that, I want to mention that work is in full swing on a new Sammy.js website with more documentation and other great stuff. I even have a real logo which I hope to share soon (stickers, anyone?). Before the site launches, though, I set up a <a href="http://github.com/quirkey/sammy/wiki/">new GitHub wiki</a> so that sammy.js users and developers can share projects and code that they&#8217;ve been working on.</p>
<p>On to the features!</p>
<span id="more-453"></span>
<h3>Context! Context! Context!</h3>
<p>The biggest complaint and frustration that I heard from people working with Sammy was about dealing with rendering complex views on the client. If you&#8217;re doing full client side applications or any amount of client side templating you&#8217;ve felt the pain of deeply nested callbacks and complex workarounds for interpolating data in an asynchronous environment. It&#8217;s all like, render this template, wait, first I need the data, hold up, I cant even render that yet I need to get this other template first. Here&#8217;s a common example of what I&#8217;m talking about:</p>
<div class="highlight"><pre><span class="k">this</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;#/&#39;</span><span class="o">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span><br />
  <span class="k">this</span><span class="p">.</span><span class="nx">partial</span><span class="p">(</span><span class="s1">&#39;index.mustache&#39;</span><span class="o">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">html</span><span class="p">)</span> <span class="p">{</span><br />
    <span class="nx">$</span><span class="p">(</span><span class="s1">&#39;#main&#39;</span><span class="p">).</span><span class="nx">html</span><span class="p">(</span><span class="nx">html</span><span class="p">);</span><br />
    <span class="nx">$</span><span class="p">.</span><span class="nx">getJSON</span><span class="p">(</span><span class="s1">&#39;items.json&#39;</span><span class="o">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">items</span><span class="p">)</span> <span class="p">{</span><br />
      <span class="k">this</span><span class="p">.</span><span class="nx">partial</span><span class="p">(</span><span class="s1">&#39;item.mustache&#39;</span><span class="o">,</span> <span class="nx">items</span><span class="o">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">item</span><span class="o">,</span> <span class="nx">i</span><span class="p">)</span> <span class="p">{</span><br />
        <span class="nx">$</span><span class="p">(</span><span class="s1">&#39;#main ul&#39;</span><span class="p">).</span><span class="nx">append</span><span class="p">(</span><span class="nx">item</span><span class="p">);</span><br />
      <span class="p">});</span><br />
    <span class="p">});</span><br />
  <span class="p">));</span><br />
<span class="p">});</span><br />
</pre></div>
<p>It&#8217;s not just nested callback&#8217;s that are the pain &#8211; its the knowing (or not knowing) when a template will be there or not. It&#8217;s also trying to deal with fetching data and fetching templates within the same context without a unified <span class="caps">API</span>. After kind of examining how other people are doing this, I took some queues from jQuery&#8217;s <span class="caps">API</span> as well as &#8216;promise&#8217; style programming and <a href="http://sexyjs.com/">Sexy.js</a>. The result is <code>Sammy.RenderContext</code>. You create a <code>RenderContext</code> by calling one of three methods within a route/<code>EventContext</code> &#8211; <code>load()</code> <code>render()</code> or <code>partial()</code>. Once you have a every method you chain to it is guaranteed to execute in the order that you chain it <em>regardless of it synchronicity</em>. This means that you can put an <code>appendTo()</code> after a <code>load()</code> and the content won&#8217;t be appended until its fetched asynchronously from a remote location. The content from the previous method in the chain is also passed along so you don&#8217;t have to constantly pull out references. The code above, translated to the <em>new way</em> looks like:</p>
<div class="highlight"><pre><span class="k">this</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;#/&#39;</span><span class="o">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span><br />
  <span class="k">this</span><span class="p">.</span><span class="nx">render</span><span class="p">(</span><span class="s1">&#39;index.mustache&#39;</span><span class="p">)</span><br />
      <span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="s1">&#39;#main&#39;</span><span class="p">)</span><br />
      <span class="p">.</span><span class="nx">render</span><span class="p">(</span><span class="s1">&#39;items.json&#39;</span><span class="p">)</span><br />
      <span class="p">.</span><span class="nx">renderEach</span><span class="p">(</span><span class="s1">&#39;item.mustache&#39;</span><span class="p">)</span><br />
      <span class="p">.</span><span class="nx">appendTo</span><span class="p">(</span><span class="s1">&#39;#main ul&#39;</span><span class="p">);</span><br />
<span class="p">});</span><br />
</pre></div>
<p>A wee bit nicer. Not only does it improve readability but it makes it much easier to do longer more involved client side templating without getting lost in a mire of order and context passing. RenderContext&#8217;s can also be invoked side by side in a single route for parallel execution of chains. Each chain is its own object and keeps its own state. I tried to keep the <span class="caps">API</span> concise but with just a few methods, I think most situations are covered:</p>
<div class="highlight"><pre><span class="nx">then</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">content</span><span class="o">,</span> <span class="nx">previous</span><span class="p">)</span> <span class="p">{})</span><br />
<span class="nx">next</span><span class="p">(</span><span class="nx">content</span><span class="p">);</span><br />
<span class="nx">wait</span><span class="p">();</span><br />
<span class="c">// Loading local or remote content</span><br />
<span class="nx">load</span><span class="p">(</span><span class="s1">&#39;item.template&#39;</span><span class="p">)</span><br />
<span class="nx">load</span><span class="p">(</span><span class="nx">$</span><span class="p">(</span><span class="s1">&#39;.item&#39;</span><span class="p">))</span><br />
<span class="c">// rendering templates</span><br />
<span class="nx">interpolate</span><span class="p">(</span><span class="s1">&#39;item.template&#39;</span><span class="o">,</span> <span class="p">{})</span><br />
<span class="nx">interpolate</span><span class="p">(</span><span class="nx">$</span><span class="p">(</span><span class="s1">&#39;.item&#39;</span><span class="p">)</span><span class="o">,</span> <span class="p">{})</span><br />
<span class="nx">render</span><span class="p">(</span><span class="s1">&#39;item.template&#39;</span><span class="o">,</span> <span class="p">{})</span><br />
<span class="nx">partial</span><span class="p">(</span><span class="s1">&#39;item.template&#39;</span><span class="o">,</span> <span class="p">{})</span><br />
<span class="nx">collect</span><span class="p">(</span><span class="nx">items</span><span class="o">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">item</span><span class="o">,</span> <span class="nx">i</span><span class="p">)</span> <span class="p">{})</span><br />
<span class="nx">renderEach</span><span class="p">(</span><span class="s1">&#39;item.template&#39;</span><span class="o">,</span> <span class="nx">items</span><span class="p">)</span><br />
<span class="c">// <span class="caps">DOM</span> Manipulation</span><br />
<span class="nx">swap</span><span class="p">()</span><br />
<span class="nx">appendTo</span><span class="p">(</span><span class="nx">$</span><span class="p">(</span><span class="nx">element</span><span class="p">))</span><br />
<span class="nx">prependTo</span><span class="p">(</span><span class="nx">$</span><span class="p">(</span><span class="nx">element</span><span class="p">))</span><br />
<span class="nx">replace</span><span class="p">(</span><span class="nx">$</span><span class="p">(</span><span class="nx">element</span><span class="p">))</span><br />
<span class="c">// Events</span><br />
<span class="nx">trigger</span><span class="p">(</span><span class="s1">&#39;name&#39;</span><span class="o">,</span> <span class="p">{})</span><br />
</pre></div>

<p>Along with the readability improvements, the <code>RenderContext</code> (specifically <code>load()</code>) allows for <span class="caps">DOM</span> style or pre-embedded templating. Meaning, templates don&#8217;t have to come from files, they can be <span class="caps">DOM</span> elements and embedded into <code>&lt;script&gt;</code> or hidden tags. This goes along with the two new templating engines added as well . . .</p>
<h3>Alchemy</h3>
<p>I thought I had this really novel idea. Why not use classes or other attributes of <span class="caps">DOM</span> elements to define how they&#8217;re tied to a <span class="caps">JSON</span> object? I worked on some prototypes and finally found a name and wrote some real code. It turns out, it was a pretty good idea, but also one that had been done before. 0.6 includes plugins for my own <code>Sammy.Meld</code> and the existing and by default more popular <a href="http://beebole.com/pure/">pure.js</a>.</p>
<p>The basic idea of both of these engines is that you take some data like this:</p>
<div class="highlight"><pre><span class="p">{</span><br />
  <span class="s2">&quot;post&quot;</span><span class="o">:</span> <span class="p">{</span><br />
    <span class="s2">&quot;title&quot;</span><span class="o">:</span> <span class="s2">&quot;My Post&quot;</span><span class="o">,</span><br />
    <span class="s2">&quot;body&quot;</span><span class="o">:</span> <span class="s2">&quot;Lorem ipsum dolor sit amet.&quot;</span><span class="o">,</span><br />
    <span class="s2">&quot;tags&quot;</span><span class="o">:</span> <span class="p">[</span><span class="s2">&quot;one&quot;</span><span class="o">,</span> <span class="s2">&quot;two&quot;</span><span class="o">,</span> <span class="s2">&quot;three&quot;</span><span class="p">]</span><span class="o">,</span><br />
    <span class="s2">&quot;meta&quot;</span><span class="o">:</span> <span class="p">{</span><br />
      <span class="s2">&quot;comments&quot;</span><span class="o">:</span> <span class="mi">5</span><span class="o">,</span><br />
      <span class="s2">&quot;time&quot;</span><span class="o">:</span> <span class="s2">&quot;Yesterday&quot;</span><br />
    <span class="p">}</span><br />
  <span class="p">}</span><br />
<span class="p">}</span><br />
</pre></div>
<p>And some <span class="caps">HTML</span> like this:</p>
<div class="highlight"><pre><span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">&quot;post&quot;</span><span class="nt">&gt;</span><br />
  <span class="nt">&lt;h2</span> <span class="na">class=</span><span class="s">&quot;title&quot;</span><span class="nt">&gt;&lt;/h2&gt;</span><br />
  <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">&quot;body&quot;</span><span class="nt">&gt;&lt;/div&gt;</span><br />
  <span class="nt">&lt;span</span> <span class="na">class=</span><span class="s">&quot;tags&quot;</span><span class="nt">&gt;&lt;/span&gt;</span><br />
  <span class="nt">&lt;ul</span> <span class="na">class=</span><span class="s">&quot;meta&quot;</span><span class="nt">&gt;</span><br />
    <span class="nt">&lt;li&gt;</span>Comments Count: <span class="nt">&lt;span</span> <span class="na">class=</span><span class="s">&quot;comments&quot;</span><span class="nt">&gt;&lt;/span&gt;&lt;/li&gt;</span><br />
    <span class="nt">&lt;li&gt;</span>Posted: <span class="nt">&lt;span</span> <span class="na">class=</span><span class="s">&quot;time&quot;</span><span class="nt">&gt;&lt;/span&gt;&lt;/li&gt;</span><br />
  <span class="nt">&lt;/ul&gt;</span><br />
<span class="nt">&lt;/div&gt;</span><br />
</pre></div>
<p>Meld them together and you should get something like:</p>
<div class="highlight"><pre><span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">&quot;post&quot;</span><span class="nt">&gt;</span><br />
  <span class="nt">&lt;h2</span> <span class="na">class=</span><span class="s">&quot;title&quot;</span><span class="nt">&gt;</span>My Post<span class="nt">&lt;/h2&gt;</span><br />
  <span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">&quot;body&quot;</span><span class="nt">&gt;</span>Lorem ipsum dolor sit amet.<span class="nt">&lt;/div&gt;</span><br />
  <span class="nt">&lt;span</span> <span class="na">class=</span><span class="s">&quot;tags&quot;</span><span class="nt">&gt;</span>one<span class="nt">&lt;/span&gt;</span><br />
  <span class="nt">&lt;span</span> <span class="na">class=</span><span class="s">&quot;tags&quot;</span><span class="nt">&gt;</span>two<span class="nt">&lt;/span&gt;</span><br />
  <span class="nt">&lt;span</span> <span class="na">class=</span><span class="s">&quot;tags&quot;</span><span class="nt">&gt;</span>three<span class="nt">&lt;/span&gt;</span><br />
  <span class="nt">&lt;ul</span> <span class="na">class=</span><span class="s">&quot;meta&quot;</span><span class="nt">&gt;</span><br />
    <span class="nt">&lt;li&gt;</span>Comments Count: <span class="nt">&lt;span</span> <span class="na">class=</span><span class="s">&quot;comments&quot;</span><span class="nt">&gt;</span>5<span class="nt">&lt;/span&gt;&lt;/li&gt;</span><br />
    <span class="nt">&lt;li&gt;</span>Posted: <span class="nt">&lt;span</span> <span class="na">class=</span><span class="s">&quot;time&quot;</span><span class="nt">&gt;</span>Yesterday<span class="nt">&lt;/span&gt;&lt;/li&gt;</span><br />
  <span class="nt">&lt;/ul&gt;</span><br />
<span class="nt">&lt;/div&gt;</span><br />
</pre></div>
<p>There are some clear benefits to this over traditional tag style (mustache, ejs) style templating. Namely, its just <span class="caps">HTML</span>. This means that you can include it in the <span class="caps">DOM</span> on the initial render and not have to go fetch it from the server. It also means that a designer can just design it and even use <em>lorem ipsum</em> if you want, and you don&#8217;t have to go through and <em>add</em> the templating language. There are some downsides, too. <span class="caps">DOM</span> manipulation even with jQuery&#8217;s speed is pretty much always going to be slower then just text interpolation. I&#8217;m working on improving the speed of Meld though caching and faster manipulations, but it ain&#8217;t easy. The other big downside is that complicated iteration or template logic is pretty hard to do in this style. Pure tries to get around this by using a third element called <code>directives</code> which are further instructions on how to meld the data and the markup. I forgo this extra ability to configure in Meld in favor of very simple transformations (ul,ol = lists) and a much smaller file size (<em>uncompressed</em> meld is only 4K). I&#8217;ve been using Meld on some personal projects and hope to test its worth in a real production environment very soon. You can see more examples of it&#8217;s power <a href="http://github.com/quirkey/sammy/blob/master/test/test_sammy_meld.js">in the tests</a></p>
<h3>What&#8217;s next?</h3>
<p>I&#8217;m still pushing to get Sammy.js to 1.0 in the very near future. I really don&#8217;t think theres that much between here and there. I&#8217;ll mention that I&#8217;ve finally been seriously coding with node and server side js and I&#8217;m not that happy with the current state of routing libs there. Server side sammy? Maybe.</p>
<h3>More</h3>
<p>There were a lot of smaller bug fixes and improvements beyond Meld and the RenderContext so I definitely encourage checking out the <a href="http://github.com/quirkey/sammy/blob/master/HISTORY.md">full list</a> and making the upgrade soon. Big thanks as always to everyone who helped with the release. Go out and make some apps!</p>]]></content:encoded>
			<wfw:commentRss>http://www.quirkey.com/blog/2010/09/02/sammy-0-6-california-suite/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Sammy is getting busy</title>
		<link>http://www.quirkey.com/blog/2010/04/30/sammy-is-getting-busy/</link>
		<comments>http://www.quirkey.com/blog/2010/04/30/sammy-is-getting-busy/#comments</comments>
		<pubDate>Fri, 30 Apr 2010 15:24:18 +0000</pubDate>
		<dc:creator>AQ</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Press]]></category>
		<category><![CDATA[Sammy]]></category>
		<category><![CDATA[Software/Scripts]]></category>

		<guid isPermaLink="false">http://www.quirkey.com/blog/?p=436</guid>
		<description><![CDATA[This week has been filled with a bunch of great news in the Sammy.js department. First of all, Sammy v0.5.4 has been released. Nothing too major, but just excited with a bunch of new contributors involved and some strange and vexing bugs fixed. More interesting, I was interviewed by The Changelog Show. Wynn and Adam [...]]]></description>
			<content:encoded><![CDATA[	<p>This week has been filled with a bunch of great news in the <a href="http://code.quirkey.com/sammy" title="">Sammy.js</a> department. First of all, <a href="http://groups.google.com/group/sammyjs/browse_frm/thread/7b7972e63ec7dcc1" title="">Sammy v0.5.4 has been released.</a> Nothing too major, but just excited with a bunch of new contributors involved and some strange and vexing bugs fixed.</p>

	<p>More interesting, <a href="thechangelog.com/post/553380723/episode-0-2-2-sammy-js-with-aaron-quint" title="">I was interviewed by The Changelog Show.</a> <a href="http://twitter.com/pengwynn" title="">Wynn</a> and <a href="http://twitter.com/adamstac" title="">Adam</a> are awesome hosts, and we talked about a lot of fun things including a good deal about Sammy and JSConf. Since I didnt really get to talk too much about Sammy at JSConf, it was a great way to share my current thoughts and some stories of the origins of Sammy.js. This also lead into a nice mention on <a href="http://5by5.tv/devshow/7" title="">The Dev Show</a> yesterday.</p>

	<p>I haven&#8217;t mentioned it here either, but I&#8217;ve also been making some major upgrades to my Sammy presentation app, <a href="http://github.com/quirkey/swinger" title="">Swinger</a>. I added slide sorting, incremental lists, and a ton more. This also includes having a fully useable hosted version for people to play with at <a href="http://swinger.quirkey.com/" title="">http://swinger.quirkey.com/</a></p>

	<p>I&#8217;m very excited about where Sammy is going and even more excited as I&#8217;m using it almost every day and getting to contribute back to the project and think about the stumbling blocks as I use it.</p>

	<p>I already have a basic plan laid out for the next release which is mainly focused on re-writing the <code>partial()</code> and template handling to make chaining multiple templates much much easier. You can <a href="http://github.com/quirkey/sammy/tree/render-context" title="">follow the work I&#8217;m doing on it on github.</a> The current status is that it works and passes the basic tests, but theres still a bit to go in terms of <span class="caps">API</span> and usability. I&#8217;m going to write a more detailed post about it very soon.</p>

 ]]></content:encoded>
			<wfw:commentRss>http://www.quirkey.com/blog/2010/04/30/sammy-is-getting-busy/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Making Bacon/Making Code: JSConf 2010</title>
		<link>http://www.quirkey.com/blog/2010/04/20/making-baconmaking-code-jsconf-2010/</link>
		<comments>http://www.quirkey.com/blog/2010/04/20/making-baconmaking-code-jsconf-2010/#comments</comments>
		<pubDate>Tue, 20 Apr 2010 13:39:45 +0000</pubDate>
		<dc:creator>AQ</dc:creator>
				<category><![CDATA[Conferences]]></category>
		<category><![CDATA[Food]]></category>
		<category><![CDATA[JavaScript]]></category>

		<guid isPermaLink="false">http://www.quirkey.com/blog/?p=426</guid>
		<description><![CDATA[To say JSConf was awesome would be an understatement. EPIC is definitely the word Not only did I have an amazing time, drinking beer with brilliant people, but the conference itself &#8211; the presentations, the organization &#8211; was simply unparalleled. I think I owe Chris a fair amount of beer. The JavaScript community is definitely [...]]]></description>
			<content:encoded><![CDATA[<p>To say <a href="http://jsconf.us/2010">JSConf</a> was awesome would be an understatement. <a href="http://search.twitter.com/search?q=jsconf+epic"><span class="caps">EPIC</span> is definitely the word</a> Not only did I have an amazing time, drinking beer with brilliant people, but the conference itself &#8211; the presentations, the organization &#8211; was simply unparalleled. I think I owe <a href="http://twitter.com/voodootikigod">Chris</a> a fair amount of beer. The JavaScript community is definitely the most fun and the most talented I&#8217;ve ever been privileged to be a part of.</p>
<h3>Making Bacon / Making Code</h3>
<p>So the story goes that over a couple drinks after an <span class="caps">NYC</span>.js meetup, I got into a little yelling match with Chris which ended in him saying &#8220;If you make bacon on stage at JSConf, I will make you the keynote.&#8221; Later that week I submitted this proposal (in <span class="caps">JSON</span>):</p>
<p>
<div class="highlight">
<pre>
{
  "name": "Aaron \"Fuck that, you don't know me\" Quint",
  "email": "aaron\@quirkey.com",
  "twitter": "aq",
  "location": "B-to-the-K-to-the-L-Y-N",
  "topic_title": "MAKING BACON <=> MAKING CODE",
  "topic_description": "For all the Cookbooks we have, and all we talk about bacon,  you'd think we could actually _make_ something. Its all BS. Have you ever taken a pork belly, trimmed it, salted it, let it cure and then smoked it.  Have you ever _made_ bacon? I have. I'll show you how. I'm no bacon expert and I'm no expert chef. I'm also no coding genius or javascript prodigy. I'm probably a better cook then you, and I probably have written some half-decent code. I probably can draw some sort of analogy between writing code and making bacon. Watch me try.",
  "claim_to_fame": "I'm not famous, I just do a couple things better then you do."
}
</pre>
</div>
<p>The dare turned into a reality. Somehow we were able to keep the fact that I wouldn&#8217;t be talking about Sammy.js a secret for over 3 months. I just kept telling people &#8220;its a <strong>suprise</strong>&#8221; Though I would have loved to have told everyone how awesome Sammy is, in the end, I think I managed to pack some good messages into this talk. After the rush of doing the talk, and getting a some laughs, I got the best feedback I could have asked for: A ton of people came to me afterwords and said &#8220;I&#8217;m going to make bacon now.&#8221; That makes me feel all warm and fuzzy inside. If you are one of those people, and you do end up making bacon, send me some pictures and I&#8217;ll link to them here. I also promised I&#8217;d link up a list of resources for those ready to plunge into the world of home made charcuterie.</p>
<h4>My Talk</h4>
<ul>
	<li><a href="http://swinger.quirkey.com/#/preso/aq-jsconf/display/1">Slides</a></li>
	<li><a href="http://bit.ly/9j7u3L">The Making Bacon Video</a></li>
</ul>
<h4>Books</h4>
<ul>
	<li><a href="http://www.amazon.com/gp/product/0393058298?ie=UTF8&#038;tag=quirkeycom-20&#038;linkCode=as2&#038;camp=1789&#038;creative=390957&#038;creativeASIN=0393058298">Charcuterie: The Craft of Salting, Smoking, and Curing</a> by Michael Ruhlman (the source of the recipe)</li>
	<li><a href="http://www.amazon.com/gp/product/0684800012?ie=UTF8&#038;tag=quirkeycom-20&#038;linkCode=as2&#038;camp=1789&#038;creative=390957&#038;creativeASIN=0684800012">On Food and Cooking: The Science and Lore of the Kitchen</a> by Harold McGee (the source of ultimate food science knowledge)</li>
	<li><a href="http://www.amazon.com/gp/product/0142001619?ie=UTF8&#038;tag=quirkeycom-20&#038;linkCode=as2&#038;camp=1789&#038;creative=390957&#038;creativeASIN=0142001619">Salt: A World History</a> by Mark Kurlansky (awesome historical facts about salt curing)</li>
	<li><a href="http://www.amazon.com/gp/product/0143038583?ie=UTF8&#038;tag=quirkeycom-20&#038;linkCode=as2&#038;camp=1789&#038;creative=390957&#038;creativeASIN=0143038583">The Omnivore&#8217;s Dilemma: A Natural History of Four Meals</a> by Michael Pollan (the history of industrial food)</li>
</ul>
<h4>Sources</h4>
<ul>
	<li><a href="http://www.butcher-packer.com/index.php?main_page=product_info&amp;cPath=237_12&amp;products_id=55&amp;zenid=2050b6fbc5c5f541a249b7caccb7da9b">Butcher/Packer</a> Pink Salt!</li>
	<li><a href="http://www.sausagemaker.com/">The Sausage Maker.com</a> For pink salt, meat hooks, sausage casings, etc.</li>
	<li><a href="http://www.lospaisanosmeatmarket.com/">Los Paisanos</a> My butcher in Brooklyn.</li>
</ul>
<h4>On the web</h4>
<ul>
	<li><a href="http://blog.ruhlman.com/">Ruhlman&#8217;s blog</a></li>
	<li><a href="http://twitter.com/ruhlman">@Ruhlman on twitter</a></li>
	<li><a href="http://www.ted.com/talks/lang/eng/dan_barber_how_i_fell_in_love_with_a_fish.html" title="video">Dan barber at Ted</a></li>
</ul>
<p>I really hope people actually do go ahead with this. It&#8217;s fun and very rewarding. For nerds of any kind, making artisanal foods from scratch provides another way for us to &#8220;take things apart&#8221;. Really, we&#8217;re just <em>refactoring</em> our food chain.</p>]]></content:encoded>
			<wfw:commentRss>http://www.quirkey.com/blog/2010/04/20/making-baconmaking-code-jsconf-2010/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>Sammy 0.5: Something for Everyone</title>
		<link>http://www.quirkey.com/blog/2010/02/15/sammy-0-5-something-for-everyone/</link>
		<comments>http://www.quirkey.com/blog/2010/02/15/sammy-0-5-something-for-everyone/#comments</comments>
		<pubDate>Mon, 15 Feb 2010 19:06:24 +0000</pubDate>
		<dc:creator>AQ</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Sammy]]></category>
		<category><![CDATA[Software/Scripts]]></category>

		<guid isPermaLink="false">http://www.quirkey.com/blog/?p=411</guid>
		<description><![CDATA[I&#8217;m pleased to announce the next major release of Sammy.js, 0.5.0. I&#8217;ll go over what I think are the most import changes, but you can check out the HISTORY or just cut to the chase and download it. jQuery 1.4.1 One of the big events I was waiting for in order to release this new [...]]]></description>
			<content:encoded><![CDATA[<p><img src="/blog/uploads/sammy-something-for-everyone.jpg" alt="Something for everyone" /></p>
<p>I&#8217;m pleased to announce the next major release of <a href="http://code.quirkey.com/sammy">Sammy.js</a>, 0.5.0. I&#8217;ll go over what I think are the most import changes, but you can check out the <a href="http://github.com/quirkey/sammy/blob/master/HISTORY.md"><span class="caps">HISTORY</span></a> or just cut to the chase and <a href="http://github.com/quirkey/sammy/tarball/v0.5.0">download it</a>.</p>
<h3>jQuery 1.4.1</h3>
<p>One of the big events I was waiting for in order to release this new version was the <a href="http://jquery14.com">release of jQuery 1.4.1</a>. Besides being a good leap and jump faster then previous versions, the latest jQuery added support for cross-browser bubbling of the <code>submit</code> event. This might not sound like a big deal, but Sammy handles <code>post/put/delete</code> routes by binding to forms and their <code>submit</code> events. In previous versions of Sammy, if a form was dynamically added to the page (i.e. by a <code>partial</code> or <code>get</code> route), you (or the app) would fire a <code>changed</code> event, which would tell the app to search for all newly added forms and bind to their <code>submit</code> events. Using the power of jQuery 1.4.1, Sammy can now just listen for submit events that will bubble up to the applications element and from their dispatch the route. In general this is a lot cleaner and will make it easier for beginners as it just <em>works</em>.</p>
<h3>Chain of fools</h3>
<p>From user requests, and to fulfill my own desires, I&#8217;ve tried make Sammy more adaptable to different styles of coding/app creation. The first thing I realized why not make Sammy app definitions chain-able? It&#8217;s a style of development that jQuery developers are already used to, and it looks pretty swanky, too. With 0.5, all the app modifying methods are now chain-able:</p>
<div class="highlight"><pre>  <br />
<br />
<span class="c">// classic style:</span><br />
<span class="nx">$</span><span class="p">.</span><span class="nx">sammy</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span><br />
  <span class="k">this</span><span class="p">.</span><span class="nx">use</span><span class="p">(</span><span class="nx">Sammy</span><span class="p">.</span><span class="nx">Mustache</span><span class="p">);</span><br />
  <span class="k">this</span><span class="p">.</span><span class="nx">use</span><span class="p">(</span><span class="nx">Sammy</span><span class="p">.</span><span class="nx">Session</span><span class="p">);</span><br />
  <br />
  <span class="k">this</span><span class="p">.</span><span class="nx">before</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span><br />
    <span class="c">// &#8230;</span><br />
  <span class="p">});</span><br />
  <br />
  <span class="k">this</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;#/&#39;</span><span class="o">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span><br />
    <span class="c">// &#8230;</span><br />
  <span class="p">});</span><br />
  <br />
  <span class="k">this</span><span class="p">.</span><span class="nx">bind</span><span class="p">(</span><span class="s1">&#39;run&#39;</span><span class="o">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span><br />
    <span class="c">// &#8230;</span><br />
  <span class="p">});</span><br />
  <br />
<span class="p">})</span><br />
<br />
<span class="c">// New chain style:</span><br />
<span class="nx">$</span><span class="p">.</span><span class="nx">sammy</span><span class="p">()</span><br />
  <span class="p">.</span><span class="nx">use</span><span class="p">(</span><span class="nx">Sammy</span><span class="p">.</span><span class="nx">Mustache</span><span class="p">)</span><br />
  <span class="p">.</span><span class="nx">use</span><span class="p">(</span><span class="nx">Sammy</span><span class="p">.</span><span class="nx">Session</span><span class="p">)</span><br />
  <span class="p">.</span><span class="nx">before</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span> <br />
    <span class="c">// .</span><br />
  <span class="p">})</span><br />
  <span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;#/&#39;</span><span class="o">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span><br />
    <span class="c">// &#8230;</span><br />
  <span class="p">})</span><br />
  <span class="p">.</span><span class="nx">bind</span><span class="p">(</span><span class="s1">&#39;run&#39;</span><span class="o">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span><br />
    <span class="c">// &#8230;</span><br />
  <span class="p">});</span><br />
    <br />
</pre></div>
<h3>Sammy()</h3>
<p>Once just a namespace, <code>Sammy()</code> is now a function (and its aliased to $.sammy). The <code>Sammy()</code> method provides access to the new Sammy.apps object and hence allows you to access the different Sammy applications you&#8217;ve added to the page without having to define additional global vars. Finding and extending is all based on @element_selector@s so those should be unique per-application. It also provides a quicker syntax for defining an app bound to an <code>element_selector</code>.</p>
<div class="highlight"><pre><span class="c">// Old way</span><br />
<span class="c">// we&#39;re forced to make app a global so we can access it </span><br />
<span class="c">// outside of this closure</span><br />
<span class="nx">app</span> <span class="o">=</span> <span class="nx">$</span><span class="p">.</span><span class="nx">sammy</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span><br />
  <span class="k">this</span><span class="p">.</span><span class="nx">element_selector</span> <span class="o">=</span> <span class="s1">&#39;#myapp&#39;</span><span class="o">;</span><br />
  <span class="c">//&#8230;</span><br />
<span class="p">})</span><br />
<span class="c">// equivalent to</span><br />
<span class="nx">app</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Sammy</span><span class="p">.</span><span class="nx">Application</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span><br />
  <span class="k">this</span><span class="p">.</span><span class="nx">element_selector</span> <span class="o">=</span> <span class="s1">&#39;#myapp&#39;</span><span class="o">;</span><br />
  <span class="c">//&#8230;</span><br />
<span class="p">});</span><br />
<br />
<span class="c">// <span class="caps">NEW</span> <span class="caps">WAY</span></span><br />
<span class="nx">$</span><span class="p">.</span><span class="nx">sammy</span><span class="p">(</span><span class="s1">&#39;#myapp&#39;</span><span class="o">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span><br />
  <span class="c">//&#8230;</span><br />
<span class="p">});</span><br />
<span class="c">// equivalent to Sammy(&#39;#myapp&#39;, function() {})</span><br />
<br />
<span class="c">// No need to assign it, the app can be looked up by element selector</span><br />
<span class="nx">$</span><span class="p">.</span><span class="nx">sammy</span><span class="p">(</span><span class="s1">&#39;#myapp&#39;</span><span class="p">)</span> <span class="c">//=&gt; Sammy.Application</span><br />
</pre></div>
<p>There are some cool use-cases for this, including being able to iterate over all the Sammy apps in play and extend them.</p>
<h3><code>any</code> way you want it</h3>
<p>Sammy 0.5 adds the new <code>any</code> <em>pseudo</em>-verb which allows you to easily add a route that will match against any verb:</p>
<div class="highlight"><pre>  <br />
<span class="nx">$</span><span class="p">.</span><span class="nx">sammy</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span><br />
  <br />
  <span class="k">this</span><span class="p">.</span><span class="nx">any</span><span class="p">(</span><span class="s1">&#39;#/&#39;</span><span class="o">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span><br />
    <span class="k">this</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">&quot;I&#39;m up for anything&quot;</span><span class="p">);</span><br />
  <span class="p">});</span><br />
  <br />
  <span class="c">// also equivalent</span><br />
  <span class="k">this</span><span class="p">.</span><span class="nx">route</span><span class="p">(</span><span class="s1">&#39;#/&#39;</span><span class="o">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{});</span><br />
  <br />
<span class="p">});</span><br />
</pre></div>
<p>This was actually the first step of another way to define Sammy applications. The new <code>mapRoutes()</code> method allows you to define any number of routes as 2D Array.</p>
<div class="highlight"><pre><span class="nx">$</span><span class="p">.</span><span class="nx">sammy</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span><br />
  <br />
  <span class="k">this</span><span class="p">.</span><span class="nx">runIndex</span> <span class="o">=</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span><br />
    <span class="k">this</span><span class="p">.</span><span class="nx">partial</span><span class="p">(</span><span class="s1">&#39;index.template&#39;</span><span class="p">);</span><br />
  <span class="p">};</span><br />
  <br />
  <span class="k">this</span><span class="p">.</span><span class="nx">mapRoutes</span><span class="p">([</span><br />
    <span class="c">// each element in the array represents the arguments sent to route()</span><br />
    <span class="p">[</span><span class="s1">&#39;get&#39;</span><span class="o">,</span> <span class="s1">&#39;#/user&#39;</span><span class="o">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span><br />
      <span class="k">this</span><span class="p">.</span><span class="nx">partial</span><span class="p">(</span><span class="s1">&#39;user.template&#39;</span><span class="p">);</span><br />
    <span class="p">}]</span><span class="o">,</span><br />
    <span class="c">// leaving out the verb assumes the verb is &#39;any&#39;</span><br />
    <span class="p">[</span><span class="sr">/\/alert$/</span><span class="o">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span><br />
      <span class="nx">alert</span><span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">params</span><span class="p">[</span><span class="s1">&#39;alert&#39;</span><span class="p">]);</span><br />
    <span class="p">}]</span><span class="o">,</span><br />
    <span class="c">// passing a string instead of a callback assigns the method with that</span><br />
    <span class="c">// name from the application.</span><br />
    <span class="p">[</span><span class="s1">&#39;get&#39;</span><span class="o">,</span> <span class="s1">&#39;#/&#39;</span><span class="o">,</span> <span class="s1">&#39;runIndex&#39;</span><span class="p">]</span><br />
  <span class="p">]);</span><br />
  <br />
<span class="p">});</span><br />
</pre></div>
<p>I personally like the method syntax better, but there are some cool uses for this &#8211; You could even load your routes from multiple files and add them to the application using <span class="caps">JSON</span>.</p>
<h3>Filters</h3>
<p><code>before</code> filters are very useful for extracting common functionality out of your routes. However, I&#8217;ve found myself writing this pretty often:</p>
<div class="highlight"><pre><span class="nx">$</span><span class="p">.</span><span class="nx">sammy</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span><br />
  <br />
  <span class="k">this</span><span class="p">.</span><span class="nx">before</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span><br />
    <span class="c">// only run if the path is not the index</span><br />
    <span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">path</span> <span class="o">!=</span> <span class="s1">&#39;#/&#39;</span><span class="p">)</span> <span class="p">{</span><br />
      <span class="c">//&#8230; do something</span><br />
    <span class="p">}</span><br />
  <span class="p">})</span><br />
  <br />
<span class="p">});</span><br />
</pre></div>
<p>Taking some hints from Rails, I&#8217;ve added options to <code>before</code> filters. The above example could be rewritten:</p>
<div class="highlight"><pre><span class="nx">$</span><span class="p">.</span><span class="nx">sammy</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span><br />
  <br />
  <span class="k">this</span><span class="p">.</span><span class="nx">before</span><span class="p">({</span><span class="nx">except</span><span class="o">:</span> <span class="s1">&#39;#/&#39;</span><span class="p">}</span><span class="o">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span><br />
    <span class="c">//&#8230; do something</span><br />
  <span class="p">})</span><br />
  <br />
<span class="p">});</span><br />
</pre></div>
<p>The filters can match against <code>path</code> (as a string or RegExp) and <code>verb</code> and you can define them in the positive (<code>only</code>) or negative (<code>except</code>). The method that does the matching is exposed as <code>contextMatchesOptions</code> so you can use it outside of <code>before()</code></p>
<p>I&#8217;ve also found myself doing a lot of wrapping entire route callbacks in an asynchronous check for something (usually a login). The new <code>around</code> filters make this easy. <code>around</code> takes a single argument which is a neatly packed function that contains the full execution path of the route being accessed. This includes additional filters and the route callback itself. This also means you can entirely halt the execution by never running the passed callback.</p>
<div class="highlight"><pre><span class="nx">$</span><span class="p">.</span><span class="nx">sammy</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span><br />
  <br />
  <span class="k">this</span><span class="p">.</span><span class="nx">around</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">callback</span><span class="p">)</span> <span class="p">{</span><br />
    <span class="c">// `this` here is the Sammy.EventContext</span><br />
    <span class="c">// just like before, etc</span><br />
    <span class="nx">$</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;/session&#39;</span><span class="o">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span><br />
      <span class="nx">callback</span><span class="p">();</span><br />
    <span class="p">});</span><br />
  <span class="p">});</span><br />
<br />
<span class="p">})</span><br />
</pre></div>
<h3>Lots more</h3>
<p>Theres actually a fair amount more to cover in Sammy 0.5, but I think I&#8217;ll be doing more short &#8216;Whats new&#8217; posts soon. Check the <a href="http://github.com/quirkey/sammy/blob/master/HISTORY.md"><span class="caps">HISTORY</span></a> for a full rundown of changes.</p>
<h3>Thanks</h3>
<p>Special thanks goes out to everyone who helped with ideas, commits and testing for this release including Lena Herrmann, Jinzhu, dpree, Jeff O&#8217;Connell, Todd Willey, Tim Caswell, and Frank Prößdorf (endor).</p>]]></content:encoded>
			<wfw:commentRss>http://www.quirkey.com/blog/2010/02/15/sammy-0-5-something-for-everyone/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Coming to a town near you</title>
		<link>http://www.quirkey.com/blog/2010/02/09/coming-to-a-town-near-you/</link>
		<comments>http://www.quirkey.com/blog/2010/02/09/coming-to-a-town-near-you/#comments</comments>
		<pubDate>Tue, 09 Feb 2010 12:00:50 +0000</pubDate>
		<dc:creator>AQ</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Talks]]></category>
		<category><![CDATA[Travel]]></category>

		<guid isPermaLink="false">http://www.quirkey.com/blog/?p=408</guid>
		<description><![CDATA[I&#8217;m very excited to announce some engagements coming up in the next couple of months. First and closest, I&#8217;ll be giving a talk today (Tues. Feb. 9th 2010) at my hometown Ruby Brigade, nyc.rb The talk will be about Resque and resque-status. Currently the event is &#8216;sold out&#8217; but if you ping the list or [...]]]></description>
			<content:encoded><![CDATA[	<p>I&#8217;m very excited to announce some engagements coming up in the next couple of months. First and closest, I&#8217;ll be giving a talk today (Tues. Feb. 9th 2010) at my hometown Ruby Brigade, <a href="http://nycruby.org/wiki/" title="">nyc.rb</a> The talk will be about <a href="http://github.com/defunkt/resque" title="">Resque</a> and <a href="http://github.com/quirkey/resque-status" title="">resque-status</a>. Currently the event is &#8216;sold out&#8217; but if you ping the list or someone in #irc before, you might be able to get a last minute spot. My slides are ready to go, so I&#8217;ll post them as soon as the talk is over.</p>

	<p>Second, I&#8217;m headed back to Edinburgh to speak at <a href="http://scottishrubyconference.com/" title="">the Scottish Ruby Conference.</a> I love this city, and the conference last year was very much above par. I&#8217;m excited to say I&#8217;ll be talking about JavaScript at a Ruby Conference. I&#8217;ve been working this talk out in my head for a long time, through lessons learned and taught to my colleagues and clients. There are also a lot of other great looking talks, including Tim Bray, Alexander Lang, Scott Chacon. Actually, the whole conference looks pretty incredible. I guarantee fun. As of writing this, there are still tickets available, <a href="http://scottishrubyconference.eventwax.com/scottish-ruby-conference-2010/register" title="">so register now</a>.</p>

	<p>Third, and possibly most exciting, I&#8217;m very proud <a href="http://jsconf.posterous.com/announcing-aaron-quinta" title="">to be chosen to speak</a> at <a href="http://jsconf.us/2010" title="">JSConf 2010.</a> I heard nothing but &#8220;AWESOME&#8221; about last years event, and I kept hitting myself for missing it. This year the esteemed <a href="http://twitter.com/voodootikigod" title="">Chris Williams</a> is putting together what promises to be the best techincal conference ever. I can&#8217;t even say how excited I am to be a part of it. The status is <a href="http://jsconf.posterous.com/the-soon-to-be-awkward-moment" title="">that the conference is already sold out,</a> but I would follow <a href="http://twitter.com/jsconf" title="">@jsconf</a> with a watchful eye to see if there are any announcements. Chris is also a lover of beer, so I cant promise anything, but some very very rare bottles might sway his favor.</p>

	<p>There are some other proposals out there as well, but these two confs were all I did this year, I&#8217;d be pretty happy.</p>
 ]]></content:encoded>
			<wfw:commentRss>http://www.quirkey.com/blog/2010/02/09/coming-to-a-town-near-you/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Sammy 0.4: Here&#8217;s looking at you</title>
		<link>http://www.quirkey.com/blog/2010/01/04/sammy-0-4-heres-looking-at-you/</link>
		<comments>http://www.quirkey.com/blog/2010/01/04/sammy-0-4-heres-looking-at-you/#comments</comments>
		<pubDate>Mon, 04 Jan 2010 16:16:10 +0000</pubDate>
		<dc:creator>AQ</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Sammy]]></category>

		<guid isPermaLink="false">http://www.quirkey.com/blog/?p=399</guid>
		<description><![CDATA[It&#8217;s been a good while in the making, and I&#8217;m proud to announce the next major release of Sammy.js. Also, I&#8217;ve published Part II of the Sammy Tutorial. Part II introduces post routes as well as some of the new features of Sammy 0.4. I&#8217;ll swing through some of the biggest changes and new hotness [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s been a good while in the making, and I&#8217;m proud to announce the next major release of <a href="http://code.quirkey.com/sammy">Sammy.js.</a> Also, I&#8217;ve published <a href="http://code.quirkey.com/sammy/tutorials/json_store_part2.html">Part II of the Sammy Tutorial.</a> Part II introduces <code>post</code> routes as well as some of the new features of Sammy 0.4.</p>
<p>I&#8217;ll swing through some of the biggest changes and new hotness &#8211; see the <a href="http://github.com/quirkey/sammy/blob/master/HISTORY"><span class="caps">HISTORY</span></a> or the <a href="http://github.com/quirkey/sammy/commits/master">Commits</a> for a full list and more detail.</p>
<span id="more-399"></span>
<h3>LocationProxy</h3>
<p>I&#8217;ve always thought the poller implementation that monitors the hash/location for changes was a little bit of a hack. CodeOfficer also had brought up the pain of having a poller per-app when you have multiple or many Sammy applications on a single page. As more browser&#8217;s support it I also wanted to make use of the native &#8216;onhashchange&#8217; event which when bound to, completely eliminates the need for polling. I attempted to do this all in one fell swoop, by decoupling the location monitoring into an entirely separate object: <code>Sammy.HashLocationProxy</code>. The <code>HashLocationProxy</code> is setup for each app by default. It tries to make use of the &#8216;onhashchange&#8217; event where available, and where it isn&#8217;t it gracefully falls back to ol&#8217; fashioned polling. The big difference, however, is there is only a single global poller per page no matter how many apps you have.</p>
<p>The <code>HashLocationProxy</code> also defines a spec for other location proxies to be created. There&#8217;s also a <code>DataLocationProxy</code> which derives its location from a <code>jQuery.data</code> attribute.</p>
<h3>Storage and Session</h3>
<p>The newest and most visibly awesome part of the new release is a new suite of plugins and prototypes: <code>Sammy.Store</code>, <code>Sammy.Storage</code> and <code>Sammy.Session</code>. As part of 0.3 I introduced <code>Sammy.Cache</code> which was really a first attempt at what <code>Sammy.Storage</code> does. <code>Sammy.Store</code> is an single access point and <span class="caps">API</span> for all the various browser based storage methods, including HTML5 <span class="caps">DOM</span> Storage and Cookies. It provides a unified way of dealing with these as Key/Value stores. As an extra bonus, it also conforms to Key Value Observing, triggering jQuery events when values change. Heres a little example:</p>
<div class="highlight"><pre><span class="c">// Cookies</span><br />
<span class="kd">var</span> <span class="nx">cookie</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Sammy</span><span class="p">.</span><span class="nx">Store</span><span class="p">({</span><span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;mycookie&#39;</span><span class="o">,</span> <span class="nx">type</span><span class="o">:</span> <span class="s1">&#39;cookie&#39;</span><span class="p">});</span><br />
<span class="nx">cookie</span><span class="p">.</span><span class="nx">set</span><span class="p">(</span><span class="s1">&#39;foo&#39;</span><span class="o">,</span> <span class="s1">&#39;bar&#39;</span><span class="p">);</span> <span class="c">//=&gt; &quot;bar&quot;</span><br />
<span class="nx">cookie</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;foo&#39;</span><span class="p">);</span> <span class="c">//=&gt; &quot;bar&quot;</span><br />
<span class="nx">cookie</span><span class="p">.</span><span class="nx">keys</span><span class="p">();</span> <span class="c">//=&gt; [&quot;foo&quot;]</span><br />
<span class="c">// HTML5 localStorage (only works in certain browsers)</span><br />
<span class="kd">var</span> <span class="nx">local</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">Sammy</span><span class="p">.</span><span class="nx">Store</span><span class="p">({</span><span class="nx">name</span><span class="o">:</span> <span class="s1">&#39;mylocal&#39;</span><span class="o">,</span> <span class="nx">type</span><span class="o">:</span> <span class="s1">&#39;local&#39;</span><span class="p">});</span><br />
<span class="nx">local</span><span class="p">.</span><span class="nx">fetch</span><span class="p">(</span><span class="s1">&#39;foo&#39;</span><span class="o">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span><br />
  <span class="k">return</span> <span class="s1">&#39;bar&#39;</span><span class="o">;</span><br />
<span class="p">});</span> <span class="c">//=&gt; &quot;bar&quot;</span><br />
<span class="c">// Only sets if not set.</span><br />
<span class="nx">local</span><span class="p">.</span><span class="nx">fetch</span><span class="p">(</span><span class="s1">&#39;foo&#39;</span><span class="o">,</span> <span class="kd">function</span><span class="p">()</span> <span class="p">{</span><br />
  <span class="k">return</span> <span class="s1">&#39;baz!&#39;</span><span class="o">;</span><br />
<span class="p">});</span> <span class="c">//=&gt; &quot;bar&quot;</span><br />
</pre></div>
<p>The <a href="http://code.quirkey.com/sammy/tutorials/json_store_part2.html">latest chapter of the Sammy tutorial</a> also covers <code>Sammy.Session</code></p>
<h3>More Plugins</h3>
<p>There are also a number of other less glamorous but new and awesome plugins.</p>
<ul>
	<li><code>Sammy.Mustache</code> Provides support for the Mustache templating framework, thanks to <a href="http://github.com/janl/mustache.js">Mustache.js</a></li>
	<li><code>Sammy.JSON</code> is a simple wrapper around json2.js</li>
	<li><code>Sammy.NestedParams</code>: Adds full [tested!] support for Rails/Rack style nested params to Sammy form handling. (Even though this was part of the 0.3.1 release, I never mentioned it here)</li>
</ul>
<h3>Thanks</h3>
<p>Thanks to everyone who helped with this release through testing, ideas, or putting Sammy in production and telling me what&#8217;s wrong with it.</p>]]></content:encoded>
			<wfw:commentRss>http://www.quirkey.com/blog/2010/01/04/sammy-0-4-heres-looking-at-you/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Wejetset City Notes Interactive: Notes from Sammy.js in Production</title>
		<link>http://www.quirkey.com/blog/2009/12/16/wejetset-city-notes-interactive-notes-from-sammy-js-in-production/</link>
		<comments>http://www.quirkey.com/blog/2009/12/16/wejetset-city-notes-interactive-notes-from-sammy-js-in-production/#comments</comments>
		<pubDate>Wed, 16 Dec 2009 16:50:51 +0000</pubDate>
		<dc:creator>AQ</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Sammy]]></category>

		<guid isPermaLink="false">http://www.quirkey.com/blog/?p=388</guid>
		<description><![CDATA[Last week I had the pleasure of launching a big new feature set into production for one of my favorite clients, Wejetset. The excitement was greatly enhanced by the fact that City Notes Interactive makes full use of my own special framework, Sammy.js. City Notes and the other features deployed were an almost ideal project. [...]]]></description>
			<content:encoded><![CDATA[<img src="http://img.skitch.com/20091216-nt27x3jx17jc8drh7x51aandhh.jpg" alt="wejetset - city notes"/><p>Last week I had the pleasure of launching a big new feature set into production for one of my favorite clients, <a href="http://www.wejetset.com">Wejetset.</a> The excitement was greatly enhanced by the fact that <a href="http://www.wejetset.com/city_notes">City Notes Interactive</a> makes full use of my own special framework, <a href="http://code.quirkey.com/sammy">Sammy.js.</a></p>
<p>City Notes and the other features deployed were an almost ideal project. The design and direction was an awesome back-and-forth collaboration between myself, Tom Ran of <a href="http://thescoutmag.com">The Scout</a> fame, and the face and brains behind Wejetset, Taj Reid. I could probably talk forever about how much fun it is to work with those guys, but in this post I&#8217;d rather dive deeper into the challenges and takeaways in the actual code.</p>
<span id="more-388"></span>
<p>I knew right from the beginning that Sammy would be a good fit for this. The question was how. Sammy let me think about the construction of the app in terms of routes and instantly gave me a way to create perma-links to specific notes and even specific filters.</p>
<h3>Templating</h3>
<p>One of the first decisions I made was to go with server-side templating. As much as I am and have been a proponent of pushing everything client-side, for this specific app it made much less sense. Specifically, there are other places throughout the site where I&#8217;m using the same templates and the benefits of re-using them were just too strong. Also, this gives the extra bonus of making the site a little more google friendly. In fact, without JavaScript the most recent notes still display and can link to the right destinations.</p>
<h3>Forms</h3>
<p>One thing that I wanted to streamline as much as possible is handling forms &#8211; posting them to the server and handling the responses without leaving the page. I came up with a useful method &#8211; <code>postFormDirectly()</code> &#8211; that handles the post route and submits it directly to the server, handling the response and sending it back to a callback.</p>
<p>Heres an example call, for positing the form to create city notes.</p>
<div class="highlight"><pre><span class="k">this</span><span class="p">.</span><span class="nx">postFormDirectly</span><span class="p">(</span><span class="s1">&#39;/city_notes&#39;</span><span class="o">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">response</span><span class="p">)</span> <span class="p">{</span> <br />
  <span class="k">if</span> <span class="p">(</span><span class="nx">response</span><span class="p">.</span><span class="nx">status</span> <span class="o">==</span> <span class="s1">&#39;success&#39;</span><span class="p">)</span> <span class="p">{</span><br />
    <span class="k">this</span><span class="p">.</span><span class="nx">redirect</span><span class="p">(</span><span class="s1">&#39;#/&#39;</span><span class="p">);</span><br />
  <span class="p">}</span><br />
<span class="p">});</span><br />
</pre></div>
<p>Instantly, you can tell that a lot is abstracted and changed from a traditional route. Here we&#8217;re routing on an actual <span class="caps">URI</span> as opposed to just an anchor. This has the added benefit of allowing the form to work without JS. (<em>As an aside, I&#8217;ve personally found a key to making degradable and unit testable sites is to first make the process work (albeit without any flair) without JS and then add the code to push the interactions and the single page-ness.</em>)</p>
<p>To give a little more insight, heres the implementation:</p>
<div class="highlight"><pre><span class="k">this</span><span class="p">.</span><span class="nx">postFormDirectly</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">path</span><span class="o">,</span> <span class="nx">callback</span><span class="p">)</span> <span class="p">{</span><br />
  <span class="kd">var</span> <span class="nx">app</span> <span class="o">=</span> <span class="k">this</span><span class="o">;</span><br />
  <span class="nx">app</span><span class="p">.</span><span class="nx">post</span><span class="p">(</span><span class="nx">path</span><span class="o">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">context</span><span class="p">)</span> <span class="p">{</span><br />
    <span class="kd">var</span> <span class="nx">context</span> <span class="o">=</span> <span class="k">this</span><span class="o">,</span><br />
        <span class="nx">post_path</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">path</span><span class="o">,</span> <br />
        <span class="nx">wrapped_callback</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">response</span><span class="p">)</span> <span class="p">{</span><br />
          <span class="nx"><span class="caps">WJS</span></span><span class="p">.</span><span class="nx">handleResponse</span><span class="p">(</span><span class="nx">response</span><span class="o">,</span> <span class="nx">context</span><span class="p">.</span><span class="nx">params</span><span class="o">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">r</span><span class="p">)</span> <span class="p">{</span><br />
            <span class="k">if</span> <span class="p">(</span><span class="nx">$</span><span class="p">.</span><span class="nx">isFunction</span><span class="p">(</span><span class="nx">callback</span><span class="p">))</span> <span class="p">{</span><br />
              <span class="nx">callback</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="nx">context</span><span class="o">,</span> <span class="p">[</span><span class="nx">r</span><span class="p">]);</span><br />
            <span class="p">}</span><br />
          <span class="p">});</span><br />
        <span class="p">};</span><br />
    <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">post_path</span><span class="p">.</span><span class="nx">match</span><span class="p">(</span><span class="sr">/js$/</span><span class="p">))</span> <span class="p">{</span> <span class="nx">post_path</span> <span class="o">=</span> <span class="nx">post_path</span> <span class="o">+</span> <span class="s1">&#39;?format=js&#39;</span><span class="o">;</span> <span class="p">}</span><br />
    <span class="k">this</span><span class="p">.</span><span class="nx">params</span><span class="p">[</span><span class="s1">&#39;$form&#39;</span><span class="p">].</span><span class="nx">find</span><span class="p">(</span><span class="s1">&#39;:input&#39;</span><span class="p">).</span><span class="nx">trigger</span><span class="p">(</span><span class="s1">&#39;clear-errors&#39;</span><span class="p">);</span><br />
    <span class="k">this</span><span class="p">.</span><span class="nx">params</span><span class="p">[</span><span class="s1">&#39;$form&#39;</span><span class="p">].</span><span class="nx">ajaxSubmit</span><span class="p">({</span><br />
      <span class="nx">url</span><span class="o">:</span> <span class="nx">post_path</span><span class="o">,</span><br />
      <span class="nx">dataType</span><span class="o">:</span> <span class="s1">&#39;json&#39;</span><span class="o">,</span><br />
      <span class="nx">success</span><span class="o">:</span> <span class="nx">wrapped_callback</span><span class="o">,</span><br />
      <span class="nx">error</span><span class="o">:</span> <span class="nx">wrapped_callback</span><br />
    <span class="p">}).</span><span class="nx">trigger</span><span class="p">(</span><span class="s1">&#39;show-loading&#39;</span><span class="p">);</span><br />
  <span class="p">});</span><br />
<span class="p">};</span><br />
</pre></div>
<p>Lets take a little walk through. First and formost, we&#8217;re just adding a <code>post</code> route to our Sammy app. The contents of this route allow us to use jquery.form&#8217;s nifty <code>ajaxSubmit</code> to send the form to the server without reloading the page. We&#8217;re creating a response callback for the ajax request called <code>wrapped_callback</code> which takes the response from the server, passes it to <code>handleResponse</code> which then in turn calls our passed callback if it exists. <code>handleResponse</code> does a lot, too, but I&#8217;m not going to post the contents here (though I might make it into a plugin &#8230;). All you need to know is that the response from the server is <span class="caps">JSON</span> and looks something like:</p>
<div class="highlight"><pre><span class="p">{</span><span class="s2">&quot;status&quot;</span><span class="o">:</span> <span class="s2">&quot;success&quot;</span><span class="o">,</span> <span class="s2">&quot;message&quot;</span><span class="o">:</span> <span class="s2">&quot;You&#39;re note was posted successfuly.&quot;</span><span class="p">}</span><br />
</pre></div>
<p><code>handleResponse</code> displays the little flash message and also highlights the form if there are errors. I use this pattern on a number of projects and it seems to work pretty well.</p>
<p>One neat Sammy tidbit you might not have known about, in post &amp; put routes, there is always a &#8216;$form&#8217; param which is a jQuery object containing the <span class="caps">HTML</span> form that submitted to the route. Very useful for cases like above.</p>
<h3>Modals</h3>
<p>If you play around with the app, you&#8217;ll notice that we make pretty good use of modal windows for actions (submit/share/email to friend). The cool thing about using Sammy for this is they&#8217;re just routes, so refreshing the page or linking jumps directly to them. I also wrote a little jQuery extension that I found extremely useful for them:</p>
<div class="highlight"><pre><span class="nx">$</span><span class="p">.</span><span class="nx">fn</span><span class="p">.</span><span class="nx">findOrAppend</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">selector</span><span class="o">,</span> <span class="nx">element</span><span class="p">)</span> <span class="p">{</span><br />
  <span class="kd">var</span> <span class="nx">$this</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="k">this</span><span class="p">)</span><span class="o">,</span> <br />
      <span class="nx">$el</span> <span class="o">=</span> <span class="nx">$this</span><span class="p">.</span><span class="nx">find</span><span class="p">(</span><span class="nx">selector</span><span class="p">);</span><br />
  <span class="k">if</span> <span class="p">(</span><span class="nx">$el</span><span class="p">.</span><span class="nx">length</span> <span class="o">&gt;</span> <span class="mi">0</span><span class="p">)</span> <span class="k">return</span> <span class="nx">$el</span><span class="o">;</span> <br />
  <span class="c">// el doesnt exist so lets make it</span><br />
  <span class="k">if</span> <span class="p">(</span><span class="k">typeof</span> <span class="nx">element</span> <span class="o">==</span> <span class="s1">&#39;undefined&#39;</span><span class="p">)</span> <span class="p">{</span><br />
    <span class="c">// figure out how to build the element from the selector</span><br />
    <span class="kd">var</span> <span class="nx">parts</span> <span class="o">=</span> <span class="nx">selector</span><span class="p">.</span><span class="nx">split</span><span class="p">(</span><span class="s1">&#39; &#39;</span><span class="p">);</span><br />
    <span class="nx">$el</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="s2">&quot;&lt;div&gt;&quot;</span><span class="p">);</span><br />
    <span class="k">if</span> <span class="p">(</span><span class="nx">parts</span><span class="p">.</span><span class="nx">length</span> <span class="o">==</span> <span class="mi">1</span><span class="p">)</span> <span class="p">{</span><br />
      <span class="c">// single selector so just added</span><br />
      <span class="nx">$el</span><span class="p">.</span><span class="nx">addSelector</span><span class="p">(</span><span class="nx">selector</span><span class="p">);</span><br />
    <span class="p">}</span> <span class="k">else</span> <span class="p">{</span><br />
      <span class="c">// selector with multiple depth so we just want the last selector</span><br />
      <span class="nx">$el</span><span class="p">.</span><span class="nx">addSelector</span><span class="p">(</span><span class="nx">parts</span><span class="p">.</span><span class="nx">pop</span><span class="p">());</span><br />
      <span class="c">// find this down the parts</span><br />
      <span class="nx">$this</span> <span class="o">=</span> <span class="nx">$this</span><span class="p">.</span><span class="nx">findOrAppend</span><span class="p">(</span><span class="nx">parts</span><span class="p">.</span><span class="nx">join</span><span class="p">(</span><span class="s1">&#39; &#39;</span><span class="p">));</span><br />
    <span class="p">}</span><br />
  <span class="p">}</span> <span class="k">else</span> <span class="p">{</span><br />
    <span class="c">// we provided a specific element</span><br />
    <span class="nx">$el</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="nx">element</span><span class="p">);</span><br />
  <span class="p">}</span><br />
  <span class="c">// append it</span><br />
  <span class="nx">$this</span><span class="p">.</span><span class="nx">append</span><span class="p">(</span><span class="nx">$el</span><span class="p">);</span><br />
  <span class="c">// return it</span><br />
  <span class="k">return</span> <span class="nx">$el</span><span class="o">;</span><br />
<span class="p">};</span><br />
</pre></div>
<p><code>findOrAppend()</code> takes a selector (I used it mostly with #ids) and creates a series of nested divs (if needed) that matches that selector.</p>
<p>For example, given <span class="caps">HTML</span>:</p>
<div class="highlight"><pre><span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">&quot;container&quot;</span><span class="nt">&gt;</span><br />
  <span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">&quot;main&quot;</span><span class="nt">&gt;&lt;/div&gt;</span><br />
<span class="nt">&lt;/div&gt;</span><br />
</pre></div>
<p>And we wanted to replace the contents of an element #submit_modal inside of it:</p>
<div class="highlight"><pre><span class="kd">var</span> <span class="nx">$modal</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="s1">&#39;body&#39;</span><span class="p">).</span><span class="nx">findOrAppend</span><span class="p">(</span><span class="s1">&#39;#main #submit_modal&#39;</span><span class="p">);</span><br />
</pre></div>
<p>The first time its called, it actually creates the neccesary #submit_modal div and returns it. However, if it exists already, it will just find it using <code>$.fn.find()</code> and return it.</p>
<p>For modals, this allows me to ensure that the container exists first, then replace it with the contents of the modal that I&#8217;m fetching from the server.</p>
<div class="highlight"><pre><span class="k">this</span><span class="p">.</span><span class="nx">helpers</span><span class="p">({</span><br />
  <span class="c">// &#8230;</span><br />
  <span class="nx">showModal</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">path</span><span class="o">,</span> <span class="nx">selector</span><span class="o">,</span> <span class="nx">callback</span><span class="p">)</span> <span class="p">{</span><br />
    <span class="kd">var</span> <span class="nx">context</span> <span class="o">=</span> <span class="k">this</span><span class="o">;</span><br />
    <span class="k">this</span><span class="p">.</span><span class="nx">showLoading</span><span class="p">();</span><br />
    <span class="k">this</span><span class="p">.</span><span class="nx">loadNotesInBackground</span><span class="p">();</span><br />
    <span class="k">this</span><span class="p">.</span><span class="nx">partial</span><span class="p">(</span><span class="nx">path</span><span class="o">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">form</span><span class="p">)</span> <span class="p">{</span><br />
      <span class="kd">var</span> <span class="nx">$el</span> <span class="o">=</span> <span class="nx">context</span><span class="p">.</span><span class="nx">$element</span><span class="p">()</span><br />
                <span class="p">.</span><span class="nx">findOrAppend</span><span class="p">(</span><span class="nx">selector</span><span class="p">);</span><br />
      <span class="kd">var</span> <span class="nx">$close</span> <span class="o">=</span> <span class="nx">$</span><span class="p">(</span><span class="s1">&#39;&lt;img src=&quot;/images/button_remove.gif&quot; alt=&quot;close&quot; class=&quot;close_modal&quot; /&gt;&#39;</span><span class="p">);</span>                    <br />
      <span class="nx">$el</span><span class="p">.</span><span class="nx">hide</span><span class="p">().</span><span class="nx">html</span><span class="p">(</span><span class="nx">form</span><span class="p">);</span><br />
      <span class="nx">$close</span><span class="p">.</span><span class="nx">prependTo</span><span class="p">(</span><span class="nx">$el</span><span class="p">).</span><span class="nx">click</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span><br />
        <span class="nx">$el</span><span class="p">.</span><span class="nx">slideUp</span><span class="p">(</span><span class="mi">200</span><span class="p">);</span><br />
        <span class="nx">context</span><span class="p">.</span><span class="nx">redirect</span><span class="p">(</span><span class="s1">&#39;#&#39;</span><span class="o">,</span> <span class="nx">context</span><span class="p">.</span><span class="nx">conditionsToURL</span><span class="p">());</span><br />
      <span class="p">});</span><br />
      <span class="k">if</span> <span class="p">(</span><span class="nx">callback</span><span class="p">)</span> <span class="p">{</span> <span class="nx">callback</span><span class="p">.</span><span class="nx">apply</span><span class="p">(</span><span class="nx">context</span><span class="o">,</span> <span class="p">[</span><span class="nx">$el</span><span class="p">]);</span> <span class="p">}</span><br />
      <span class="c">// bind error handlers</span><br />
      <span class="nx">context</span><span class="p">.</span><span class="nx">bindFormErrorHandlers</span><span class="p">();</span><br />
      <span class="nx">context</span><span class="p">.</span><span class="nx">hideLoading</span><span class="p">();</span><br />
      <span class="nx">$el</span><span class="p">.</span><span class="nx">slideDown</span><span class="p">();</span><br />
      <span class="nx">$</span><span class="p">(</span><span class="s1">&#39;#main&#39;</span><span class="p">).</span><span class="nx">slideTo</span><span class="p">();</span><br />
    <span class="p">});</span><br />
  <span class="p">}</span><br />
  <span class="c">//&#8230;</span><br />
<span class="p">});</span><br />
</pre></div>
<p>Here I have a helper that fetches the view/template from the server using <code>partial()</code> and then situates its content using <code>findOrAppend()</code>. It also does me the favor of adding the little close icon in the upper right corner. A typical use is for the login screen:</p>
<div class="highlight"><pre><span class="k">this</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">&#39;#/login&#39;</span><span class="o">,</span> <span class="kd">function</span><span class="p">(</span><span class="nx">context</span><span class="p">)</span> <span class="p">{</span><br />
 <span class="k">this</span><span class="p">.</span><span class="nx">showModal</span><span class="p">(</span><span class="s1">&#39;/account/login&#39;</span><span class="o">,</span> <span class="s1">&#39;#main #login_signup.modal&#39;</span><span class="p">)</span><br />
<span class="p">});</span><br />
</pre></div>
<h3>Analytics</h3>
<p>It has to be said as well that I&#8217;m really excited about the burgeoning Sammy.js community. I&#8217;m lucky enough to have some other really smart individuals working on Sammy projects and sharing some of their code through plugins. Thanks to <a href="http://britg.com/">Brit Gardner</a> and his <a href="http://github.com/britg/sammy-google-analytics">Sammy.GoogleAnalytics</a> plugin, adding analytics to the app was as easy as dropping in the file and adding one line to my app. That felt really really good. I hope more people will start sharing some plugins soon.</p>
<h3>A lot more</h3>
<p>There were a lot more discoveries over the months building this app then I can really share in a little blog post but needless to say, I&#8217;m going to try to bring the usefull and reusable stuff back into Sammy and plugins for everyone to use. If you want to hear more about it or have specific questions, dont hesitate to ping me on <span class="caps">IRC</span> or twitter or email the <a href="http://groups.google.com/group/sammyjs">Sammy mailing list.</a></p>]]></content:encoded>
			<wfw:commentRss>http://www.quirkey.com/blog/2009/12/16/wejetset-city-notes-interactive-notes-from-sammy-js-in-production/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Sammy.js: Tutorial &#8211; The JSON Store, Part I</title>
		<link>http://www.quirkey.com/blog/2009/10/12/sammy-js-tutorial-the-json-store-part-i/</link>
		<comments>http://www.quirkey.com/blog/2009/10/12/sammy-js-tutorial-the-json-store-part-i/#comments</comments>
		<pubDate>Mon, 12 Oct 2009 15:00:21 +0000</pubDate>
		<dc:creator>AQ</dc:creator>
				<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Sammy]]></category>

		<guid isPermaLink="false">http://www.quirkey.com/blog/?p=378</guid>
		<description><![CDATA[Its a week late, but as promised I&#8217;ve started working on a series of tutorials for Sammy.js. The first series is based around a simple E-commerce front end with Sammy, &#8216;The JSON Store&#8217;. I&#8217;m starting out really basic, so if you&#8217;ve already dabbled with Sammy, this might be old hat, but you should breeze through [...]]]></description>
			<content:encoded><![CDATA[	<p>Its a week late, but as promised <a href="http://code.quirkey.com/sammy/tutorials/json_store_part1.html" title="">I&#8217;ve started working on a series of tutorials for Sammy.js.</a> The first series is based around a simple E-commerce front end with Sammy, &#8216;The <span class="caps">JSON </span>Store&#8217;. I&#8217;m starting out <em>really</em> basic, so if you&#8217;ve already dabbled with Sammy, this might be old hat, but you should breeze through quickly as you could learn a trick or two. For the more intermediate and advanced users, don&#8217;t worry, I have some ideas and things in progress for you as well.</p>

	<p>Quick note, I decided to use github pages instead of this here blog to post the tutorials. In the end, its just easier to post lots of inline code <span class="caps">AND</span> it will be easier to maintain with updates as the Sammy <span class="caps">API</span> changes.</p>

	<p>I hope you enjoy it! I&#8217;m always appreciative of feedback and constructive criticism, so fire away.</p>
 ]]></content:encoded>
			<wfw:commentRss>http://www.quirkey.com/blog/2009/10/12/sammy-js-tutorial-the-json-store-part-i/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

