<?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; Sammy</title>
	<atom:link href="http://www.quirkey.com/blog/category/sammy/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>#-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>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>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>What I&#8217;ve been up to: The last forever (Oct, Nov 09)</title>
		<link>http://www.quirkey.com/blog/2009/12/09/what-ive-been-up-to-the-last-forever-oct-nov-09/</link>
		<comments>http://www.quirkey.com/blog/2009/12/09/what-ive-been-up-to-the-last-forever-oct-nov-09/#comments</comments>
		<pubDate>Wed, 09 Dec 2009 20:09:37 +0000</pubDate>
		<dc:creator>AQ</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Life]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Sammy]]></category>

		<guid isPermaLink="false">http://www.quirkey.com/blog/?p=385</guid>
		<description><![CDATA[The two week trip to California was nothing less than a great success. A fine blend of business and pleasure (with an emphasis on the relaxing). Highlights included: Going to RubyConf without actually going. Eating and drinking fine food and wine in Napa/Sonoma for 4 days non-stop. (Full list of vineyards and restaurants with menus [...]]]></description>
			<content:encoded><![CDATA[	<p>The two week trip to California was nothing less than a great success. A fine blend of business and pleasure (with an emphasis on the relaxing).</p>

	<p>Highlights included:</p>

	<ul>
		<li>Going to RubyConf without actually going.</li>
		<li>Eating and drinking fine food and wine in Napa/Sonoma for 4 days non-stop. (Full list of vineyards and restaurants with menus on request).</li>
		<li>Spending time with my lovely wife.</li>
		<li>Seeing friends I don&#8217;t get to see enough.</li>
	</ul>

	<p>Though this blog may tell a different story, I actually have been writing a lot of code as well:</p>

	<ul>
		<li>Most notably, the production, public-facing Sammy.js application I&#8217;ve been working so diligently on finally launched: <a href="http://www.wejetset.com/city_notes" title="">Wejetset City Notes Interactive.</a> I learned a ton writing and deploying it, and I promise to share a bunch of those lessons, soon.</li>
		<li>With the help of <a href="http://rvm.beginrescueend.com/" title="">the amazing rvm</a> I&#8217;ve started getting all my gems tested and working on Ruby 1.9. I think everyone should be doing the same, so if people are interested in my approach, maybe I&#8217;ll write a tutorial.</li>
		<li>I&#8217;ve even been porting other peoples gems to 1.9. Specifically <a href="http://github.com/quirkey/oauth/tree/1.9-nodeps" title="">I have a fork of the oauth gem</a> that works on Ruby 1.9.1 without any dependencies. It should be merged and released to the master oauth gem shortly.</li>
		<li>It&#8217;s been a long time coming, but I&#8217;ve been <a href="http://github.com/quirkey/qadmin/commits/master" title="">working on a big rewrite of qadmin</a> thats being used in production in a couple places. Its a lot easier to configure and extend and really just needs to have its documentation thoroughly updated before I can do a real release.</li>
		<li>I&#8217;ve also <a href="http://portfolio.quirkey.com" title="">updated my portfolio</a> to include links to my talks and some other new projects.</li>
	</ul>

	<p>I&#8217;m hoping to get some more blogging done and <span class="caps">OSS</span> releases out in the next couple of days so stay tuned!</p>

 ]]></content:encoded>
			<wfw:commentRss>http://www.quirkey.com/blog/2009/12/09/what-ive-been-up-to-the-last-forever-oct-nov-09/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>
		<item>
		<title>Sammy 0.3.0 Released: I gotta right to swing!</title>
		<link>http://www.quirkey.com/blog/2009/09/30/sammy-0-3-0-released-i-gotta-right-to-swing/</link>
		<comments>http://www.quirkey.com/blog/2009/09/30/sammy-0-3-0-released-i-gotta-right-to-swing/#comments</comments>
		<pubDate>Wed, 30 Sep 2009 14:57:57 +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=371</guid>
		<description><![CDATA[I&#8217;m very happy to announce the next major release of Sammy.js. I&#8217;ve been working on this for over a month and the result has been a lot more changes then I expected but over all a smaller, cleaner core code base. Here&#8217;s a quick run through of the biggest changes. See HISTORY or the Commits [...]]]></description>
			<content:encoded><![CDATA[<p><img src="/blog/uploads/igottarighttoswing.jpg" alt="Sammy 0.3.0: I gotta right to swing!" /></p>


	<p>I&#8217;m very happy to announce the next major release of <a href="http://code.quirkey.com/sammy">Sammy.js.</a> I&#8217;ve been working on this for over a month and the result has been a lot more changes then I expected but over all a smaller, cleaner core code base. Here&#8217;s a quick run through of the biggest changes. See <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-371"></span>
	<h3>Plugins</h3>

	<p>The biggest change, that resulted in a lot of little changes is <code>Sammy.Application#use()</code> which allows you to package and resuse application level code into &#8216;Plugins&#8217;. See the <a href="http://code.quirkey.com/sammy/docs/plugins.html">documentation on plugins for more detail.</a> This also marks the start of an official selection of plugins, with two as part of this release and more on the way.</p>

<p>The default template system that used $.srender internally has been extracted out into a plugin. To enable <em>almost</em> the exact same functionality:</p>

<pre class="textmate-source"><span class="source source_js source_js_jquery"><span class="comment comment_line comment_line_double-slash comment_line_double-slash_js"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_js">//</span> somewhere in your HTML (after sammy.js): 
</span><span class="comment comment_line comment_line_double-slash comment_line_double-slash_js"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_js">//</span> &lt;script src="plugins/sammy.template.js" type="text/javascript"&gt;&lt;/script&gt;
</span><span class="keyword keyword_operator keyword_operator_js">$</span><span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js">.</span>sammy<span class="meta meta_brace meta_brace_round meta_brace_round_js">(</span><span class="storage storage_type storage_type_js">function</span><span class="meta meta_brace meta_brace_round meta_brace_round_js">()</span> <span class="meta meta_brace meta_brace_curly meta_brace_curly_js">{</span>
  <span class="comment comment_line comment_line_double-slash comment_line_double-slash_js"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_js">//</span> include the Sammy.Template plugin
</span>  <span class="variable variable_language variable_language_js">this</span><span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js">.</span>use<span class="meta meta_brace meta_brace_round meta_brace_round_js">(</span>Sammy<span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js">.</span>Template<span class="meta meta_brace meta_brace_round meta_brace_round_js">)</span><span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span>
  
<span class="meta meta_brace meta_brace_curly meta_brace_curly_js">}</span><span class="meta meta_brace meta_brace_round meta_brace_round_js">)</span><span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span></span></pre>

	<h3>Events</h3>

	<p>Sammy.Application&#8217;s bind() and trigger() methods now use jQuery&#8217;s namespacing to bind to Events. This means that Sammy.Application can now easily catch events that bubble to it like &#8216;click&#8217; or &#8216;focus&#8217;. The big awesomeness is that the callbacks for these bind() methods are always evaluated within a Sammy.EventContext so that even events triggered from outside the app can be handled in the same way as internal events.</p>

  <pre class="textmate-source"><span class="source source_js source_js_jquery"><span class="storage storage_type storage_type_js">var</span> app <span class="keyword keyword_operator keyword_operator_js">=</span> <span class="keyword keyword_operator keyword_operator_js">$</span><span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js">.</span>sammy<span class="meta meta_brace meta_brace_round meta_brace_round_js">(</span><span class="storage storage_type storage_type_js">function</span><span class="meta meta_brace meta_brace_round meta_brace_round_js">()</span> <span class="meta meta_brace meta_brace_curly meta_brace_curly_js">{</span>

    <span class="variable variable_language variable_language_js">this</span><span class="support support_function support_function_js support_function_js_jquery">.bind</span><span class="meta meta_brace meta_brace_round meta_brace_round_js">(</span><span class="string string_quoted string_quoted_single string_quoted_single_js"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_js">'</span>custom-event<span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_js">'</span></span><span class="meta meta_delimiter meta_delimiter_object meta_delimiter_object_comma meta_delimiter_object_comma_js">, </span><span class="storage storage_type storage_type_js">function</span><span class="meta meta_brace meta_brace_round meta_brace_round_js">()</span> <span class="meta meta_brace meta_brace_curly meta_brace_curly_js">{</span>
      <span class="comment comment_line comment_line_double-slash comment_line_double-slash_js"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_js">//</span> this == Sammy.EventContext
  </span>    <span class="support support_function support_function_js">alert</span><span class="meta meta_brace meta_brace_round meta_brace_round_js">(</span><span class="string string_quoted string_quoted_single string_quoted_single_js"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_js">'</span>Custom Event<span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_js">'</span></span> <span class="keyword keyword_operator keyword_operator_js">+</span> <span class="variable variable_language variable_language_js">this</span><span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js">.</span>params<span class="meta meta_brace meta_brace_square meta_brace_square_js">[</span><span class="string string_quoted string_quoted_single string_quoted_single_js"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_js">'</span>wha<span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_js">'</span></span><span class="meta meta_brace meta_brace_square meta_brace_square_js">]</span><span class="meta meta_brace meta_brace_round meta_brace_round_js">)</span><span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span>
    <span class="meta meta_brace meta_brace_curly meta_brace_curly_js">}</span><span class="meta meta_brace meta_brace_round meta_brace_round_js">)</span><span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span>

  <span class="meta meta_brace meta_brace_curly meta_brace_curly_js">}</span><span class="meta meta_brace meta_brace_round meta_brace_round_js">)</span><span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span>

  <span class="comment comment_line comment_line_double-slash comment_line_double-slash_js"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_js">//</span> the app is by default bound to 'body'
  </span><span class="support support_class support_class_js support_class_js_jquery">$</span><span class="punctuation punctuation_section punctuation_section_class punctuation_section_class_js">(</span><span class="meta meta_selector meta_selector_jquery"><span class="punctuation punctuation_definition punctuation_definition_selector punctuation_definition_selector_begin punctuation_definition_selector_begin_js">'</span><span class="meta meta_selector meta_selector_css"><span class="entity entity_name entity_name_tag entity_name_tag_css">body</span></span><span class="punctuation punctuation_definition punctuation_definition_selector punctuation_definition_selector_end punctuation_definition_selector_end_js">'</span></span><span class="punctuation punctuation_section punctuation_section_class punctuation_section_class_js">)</span><span class="support support_function support_function_js support_function_js_jquery">.trigger</span><span class="meta meta_brace meta_brace_round meta_brace_round_js">(</span><span class="string string_quoted string_quoted_single string_quoted_single_js"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_js">'</span>custom-event<span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_js">'</span></span><span class="meta meta_delimiter meta_delimiter_object meta_delimiter_object_comma meta_delimiter_object_comma_js">, </span><span class="meta meta_brace meta_brace_curly meta_brace_curly_js">{</span>wha: <span class="string string_quoted string_quoted_single string_quoted_single_js"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_js">'</span>ZUH?!<span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_end punctuation_definition_string_end_js">'</span></span><span class="meta meta_brace meta_brace_curly meta_brace_curly_js">}</span><span class="meta meta_brace meta_brace_round meta_brace_round_js">)</span><span class="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span>
  <span class="comment comment_line comment_line_double-slash comment_line_double-slash_js"><span class="punctuation punctuation_definition punctuation_definition_comment punctuation_definition_comment_js">//</span>=&gt; system alert ZUH?!
  </span></span></pre>

	<h3>Cleanup</h3>

	<p>With the advent of plugins, Sammy Core is now even smaller (8.9k minified). This is also possible because I&#8217;ve removed the former &#8216;classical&#8217; inheritence code in favor of prototypal inheritence, which is a big win in terms of cleanlieness and global scope leakage.</p>


	<h3>See Also</h3>


	<p>I mentioned this on twitter, but I&#8217;m working on some new tutorials and screencasts about Sammy. If you have ideas/suggestions, dont hesitate to let me know. The first one should be up next week. I&#8217;m going to try to do them bi-weekly, we&#8217;ll see how that goes <img src='http://www.quirkey.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>


	<p>Again, I&#8217;ve tried to be as thorough with inline <span class="caps">API</span> docs as I could so any changes should be in the clear. Thanks again to everyone who helped with this release and has supported Sammy recently!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.quirkey.com/blog/2009/09/30/sammy-0-3-0-released-i-gotta-right-to-swing/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Sammy.js, CouchDB, and the new web architecture</title>
		<link>http://www.quirkey.com/blog/2009/09/15/sammy-js-couchdb-and-the-new-web-architecture/</link>
		<comments>http://www.quirkey.com/blog/2009/09/15/sammy-js-couchdb-and-the-new-web-architecture/#comments</comments>
		<pubDate>Tue, 15 Sep 2009 13:44:38 +0000</pubDate>
		<dc:creator>AQ</dc:creator>
				<category><![CDATA[CouchDB]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[jQuery]]></category>
		<category><![CDATA[Sammy]]></category>

		<guid isPermaLink="false">http://www.quirkey.com/blog/?p=359</guid>
		<description><![CDATA[UPDATE: My slides and a protected instance (will open up for play soon) or swinger, available here I&#8217;ll be honest. When I created Sammy.js, It was more of an academic exercise then a means to an end. I had ideas for how it could be useful, and had some immediate uses for it, but the [...]]]></description>
			<content:encoded><![CDATA[	<p><em><span class="caps">UPDATE</span>: My slides and a protected instance (will open up for play soon) or swinger, available <a href="http://c.ixxr.net/swinger/_design/swinger/index.html#/preso/jqcon_09/display/1" title="">here</a> </em></p>

	<p>I&#8217;ll be honest. When I created <a href="http://code.quirkey.com/sammy" title="">Sammy.js,</a> It was more of an academic exercise then a means to an end. I had ideas for how it could be useful, and had some immediate uses for it, but the initial thought was &#8216;recreating Sinatra&#8217;s <span class="caps">API</span> in JavaScript&#8217;. Little did I know &#8211; with a little introduction and the work of some clever individuals, its real value would be revealed.</p>

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

	<p>We&#8217;re at the dawn of a new age on the web, or maybe or horizon, or a precipice; the metaphor doesn&#8217;t matter, the point is, things are changing. Specifically, as browsers become more and more powerful, as developers we&#8217;re given new opportunities to rethink how we architect web applications. Whether or not some of the predictions of &#8216;the death of the traditional desktop&#8217; are correct &#8211; whether or not the near future desktop is just the browser &#8211; we now have the power, without proprietary technologies (flash, etc) to create truly desktop like experiences on the web. Thats nothing mind-blowing, we&#8217;ve seen it coming for a little while now.</p>

	<p>Ok, then: let me <em>blow your mind.</em></p>

	<p>Because of the great power that modern browsers provide us as Javascript developers a new paradigm of web development is arising. Lets take a look at the current/traditional model:</p>

	<p><img src="http://img.skitch.com/20090915-6xfj7cp1kx6w884tqw29yk2k4.jpg" alt="Old Way" /></p>

	<p>Here we have a traditional stack. The &#8216;power&#8217; of the application lies on the server: our development platform of choice (Rails, <span class="caps">PHP</span>, etc) sits on top of our database of choice (probably relational, probably <span class="caps">SQL</span>). This server platform renders finished <span class="caps">HTML</span> and maybe decorates those pages with the use of our JS library and our application specific code (Your $(hit)). In this model we&#8217;re using probably at least 3 different programming languages and almost fully on the speed and reliability of our servers for getting data to the user. There&#8217;s probably also at least 3 steps in either direction between data and the user:</p>

	<ul>
		<li>User clicks a link on a page or follows a <span class="caps">URL</span></li>
		<li>The request is sent to the server</li>
		<li>App receives request passes it on to Model/ORM layer</li>
		<li><span class="caps">ORM</span> requests the data from the Database</li>
		<li>Database returns the data to the <span class="caps">ORM</span></li>
		<li><span class="caps">ORM</span> returns the data in a parse-able form to the App</li>
		<li>App converts it into user-readable format and displays it to user</li>
	</ul>

	<p>Obviously, Rails and most other languages frameworks abstract a lot of this away, so we don&#8217;t really have to think in all these steps. They&#8217;re there, though.</p>

	<p><img src="http://img.skitch.com/20090915-c8trr5mh7ukbhg6eukptwsuq3r.jpg" alt="The New Way" /></p>

	<p>Welcome to the new world. <span class="caps">HTTP </span>Databases and <span class="caps">JSON </span>Storage. The simple act of making the database and the browser more powerful on either end has destroyed the need for the middle tier. In the new architecture, Our database (JSON/HTTP based: <a href="http://couchdb.org" title="">CouchDB</a>, <a href="http://getcloudkit.com" title="">Cloudkit</a>) serves data as <span class="caps">JSON</span> directly to the browser. On the browser side we create a much smaller/tighter &#8216;controller&#8217; layer with JavaScript. This handles the directing of the user to the right place, the displaying of the data to the user, and the conversion of user interaction into state + data. This middle piece is jQuery + Sammy.js.</p>

	<p>In my presentation at jQuery Conf this past weekend (<a href="http://c.ixxr.net/swinger/_design/swinger/index.html#/preso/jqcon_09/display/1" title="">slides available here</a>) I demonstrated this concept in a rather meta-tastic way. The presentation tool I used was called <a href="http://github.com/quirkey/swinger" title="">Swinger</a> and it was written using CouchDB, <a href="http://github.com/couchapp/couchapp" title="">CouchApp,</a> and Sammy.js. The application logic was contained in a single JS file that used a Sammy application to do all the routing, getting data in and out of CouchDB and displaying it in a particularly pretty way. The coolest part about this whole thing is that even beyond taking out the middle layer, this implementation removes the traditional static file serving model, too. With the power of CouchApp and _attachments, the javascript and <span class="caps">HTML</span> files needed to serve the application are served directly out of the database. Its like CouchDB and Sammy.js were made for each other. Think about the new steps for this architecture:</p>

	<ul>
		<li>User clicks a link on the page or follows a <span class="caps">URL</span></li>
		<li>Data is requested via <span class="caps">AJAX</span> from the server</li>
		<li>The server proxies to the database or processes the request directly</li>
		<li>The data is returned to Sammy.js as <span class="caps">JSON</span></li>
		<li>Sammy.js uses the data it needs and displays it to the user</li>
	</ul>

	<p>There are a number really amazing and exciting things to note here. First, notice how the application is written in JavaScript <span class="caps">AND</span> the data is JavaScript. The <span class="caps">JSON</span> store might actually be written in another language (CouchDB is Erlang, Cloudkit is Ruby) but we don&#8217;t really ever have to touch those. Personally, I really like JavaScript. Sure, I miss some of Ruby&#8217;s syntax and niceties, but I&#8217;ll give that up pretty quickly for something that still shares some of the similar good features (closures, loose typing) and has a ubiquitous deployment environment (the browser). Second, the end result is probably similar if not better to the end user, as we eliminate the need to reload the page at every request, resulting in a better perceived speed.</p>

	<p>One of the provisions I gave for my talk is that &#8220;I&#8217;m less concerned with speed than awesomeness&#8221;. That rings pretty true here. I don&#8217;t have an architecture like this running in production and getting hit like twitter. I can&#8217;t really speak yet to how well it &#8216;scales&#8217; or how it preforms under load. <span class="caps">I CAN</span> tell you about how awesome it is and how easy and fun it was to develop swinger with Sammy. That&#8217;s really all <em>I</em> need to know right now.</p>
 ]]></content:encoded>
			<wfw:commentRss>http://www.quirkey.com/blog/2009/09/15/sammy-js-couchdb-and-the-new-web-architecture/feed/</wfw:commentRss>
		<slash:comments>41</slash:comments>
		</item>
	</channel>
</rss>

