<?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>Thu, 02 Sep 2010 20:02:16 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<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>1</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>0</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[Sammy]]></category>
		<category><![CDATA[Software/Scripts]]></category>
		<category><![CDATA[jQuery]]></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>0</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[Sammy]]></category>
		<category><![CDATA[jQuery]]></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[Sammy]]></category>
		<category><![CDATA[Software/Scripts]]></category>
		<category><![CDATA[jQuery]]></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[Sammy]]></category>
		<category><![CDATA[jQuery]]></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>35</slash:comments>
		</item>
		<item>
		<title>Headed out: What I&#8217;ve been up to June + Early July &#8217;09</title>
		<link>http://www.quirkey.com/blog/2009/07/15/headed-out-what-ive-been-up-to-june-early-july-09/</link>
		<comments>http://www.quirkey.com/blog/2009/07/15/headed-out-what-ive-been-up-to-june-early-july-09/#comments</comments>
		<pubDate>Wed, 15 Jul 2009 13:50:06 +0000</pubDate>
		<dc:creator>AQ</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Geekery]]></category>
		<category><![CDATA[Ruby]]></category>
		<category><![CDATA[Sammy]]></category>
		<category><![CDATA[Travel]]></category>

		<guid isPermaLink="false">http://www.quirkey.com/blog/?p=330</guid>
		<description><![CDATA[I&#8217;m headed out to Japan for Ruby Kaigi and some real vacation and touring today. I&#8217;m teeming with excitement and nerves and in the interest of tying up some loose ends and making myself feel a little more ready for the trip, here&#8217;s another list of fun things happening/in progress. Sinatra-Sammy: Inspired half by potential [...]]]></description>
			<content:encoded><![CDATA[	<p>I&#8217;m headed out to Japan for <a href="http://rubykaigi.org/2009/en" title="">Ruby Kaigi</a> and some real vacation and touring today. I&#8217;m teeming with excitement and nerves and in the interest of tying up some loose ends and making myself feel a little more ready for the trip, here&#8217;s another list of fun things happening/in progress.</p>

	<ul>
		<li><a href="http://github.com/quirkey/sinatra-sammy" title="">Sinatra-Sammy:</a> Inspired half by potential usefulness and half by a dare from <a href="http://twitter.com/binary42" title="">binary42</a> at the first meeting of <span class="caps">NYC</span>.js, sinatra-sammy is a sinatra module/plugin that includes sammy.js makes multi-page apps appear to be single page (with deep-linking etc) while maintaining the <span class="caps">SEO</span> and other benefits of a multi-paged, normal app. Make sense? No? Yeah, OK. I&#8217;m working on putting up a good example, for now you can clone the repo and checkout the included test app.</li>
		<li>Speaking of <span class="caps">NYC</span>.js, I was honored to be the first speaker and did a little presentation about Sammy. <a href="http://quirkey.com/sammy-presentations/nyc.js_june3/slides.html" title="">Slides are viewable here</a></li>
		<li><a href="http://code.quirkey.com/vegas" title="">Vegas</a> + <a href="http://code.quirkey.com/gembox" title="">Gembox</a> are now windows friendly. It took a bunch of hacking, specifically around the daemon-ization (Kernel.fork is not natively implemented on win32) but windows users can now use Gembox just like their Unix based brethren. Windows users can now also, and should, make use of Vegas for creating Rack based executables.</li>
		<li>I&#8217;m giving an updated version of the talk I gave at GoGaRuCo &#8220;Sinatra: The Framework Within&#8221; at Ruby Kaigi. I&#8217;ve been hacking on a secret and useful project and hopefully I can wrap it up on the plane and present it at the conference.</li>
		<li>I got a new camera. I&#8217;ll be posting a lot of drool worthy food photography on <a href="http://flickr.com/photos/katandaq/" title="">flickr.</a></li>
	</ul>

	<p>For anybody attending RubyKaigi, please come find me and lets hack/talk/eat ramen.</p>
 ]]></content:encoded>
			<wfw:commentRss>http://www.quirkey.com/blog/2009/07/15/headed-out-what-ive-been-up-to-june-early-july-09/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Sammy.js hits a new milestone (0.2.0)</title>
		<link>http://www.quirkey.com/blog/2009/06/12/sammyjs-hits-a-new-milestone-020/</link>
		<comments>http://www.quirkey.com/blog/2009/06/12/sammyjs-hits-a-new-milestone-020/#comments</comments>
		<pubDate>Fri, 12 Jun 2009 17:40:15 +0000</pubDate>
		<dc:creator>AQ</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Sammy]]></category>
		<category><![CDATA[jQuery]]></category>

		<guid isPermaLink="false">http://www.quirkey.com/blog/?p=325</guid>
		<description><![CDATA[Thanks to the support and help of an awesome community, Sammy.js hit 0.2.0 on Monday. You can see the full release notes here and the API doc has been updated to reflect the changes. My favorite feature from this update might be the simplest. Rendering partials now uses a special swap() method on Sammy.Application. By [...]]]></description>
			<content:encoded><![CDATA[<p>Thanks to the support and help of an awesome community, <a href="http://code.quirkey.com/sammy">Sammy.js</a> hit 0.2.0 on Monday. You can see the <a href="http://groups.google.com/group/sammyjs/browse_thread/thread/add71f66703fe74f">full release notes here</a> and the <a href="http://code.quirkey.com/sammy/docs/api.html">API doc</a> has been updated to reflect the changes.</p>

<p>My favorite feature from this update might be the simplest. </p>

<p>Rendering partials now uses a special <code>swap()</code> method on <code>Sammy.Application</code>. By default it just uses jQuery's <code>html()</code> method to swap out the old content of <code>$element</code> with the new content. The power though, is you easily override this to provide a cool transition when a new partial is rendered.</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="meta meta_function meta_function_js"><span class="support support_class support_class_js">this</span>.<span class="entity entity_name entity_name_function entity_name_function_js">swap</span> <span class="keyword keyword_operator keyword_operator_js">=</span> <span class="storage storage_type storage_type_function storage_type_function_js">function</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_begin punctuation_definition_parameters_begin_js">(</span><span class="variable variable_parameter variable_parameter_function variable_parameter_function_js">content</span><span class="punctuation punctuation_definition punctuation_definition_parameters punctuation_definition_parameters_end punctuation_definition_parameters_end_js">)</span></span> <span class="meta meta_brace meta_brace_curly meta_brace_curly_js">{</span>
    <span class="storage storage_type storage_type_js">var</span> width <span class="keyword keyword_operator keyword_operator_js">=</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="support support_class support_class_js">window</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">.width</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="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><span class="keyword keyword_operator keyword_operator_js">$</span>element<span class="meta meta_brace meta_brace_round meta_brace_round_js">()</span>
      <span class="support support_function support_function_js support_function_js_jquery">.wrapInner</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>&lt;div class="inner"&gt;&lt;/div&gt;<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_round meta_brace_round_js">)</span>
      <span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js">.</span><span class="support support_function support_function_js support_function_js_jquery">children</span><span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_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_other entity_other_attribute-name entity_other_attribute-name_class entity_other_attribute-name_class_css"><span class="punctuation punctuation_definition punctuation_definition_attribute-name punctuation_definition_attribute-name_css">.</span>inner</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_function punctuation_section_function_js">)</span>
        <span class="support support_function support_function_js support_function_js_jquery">.animate</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>queue: <span class="constant constant_language constant_language_boolean constant_language_boolean_false constant_language_boolean_false_js">false</span><span class="meta meta_delimiter meta_delimiter_object meta_delimiter_object_comma meta_delimiter_object_comma_js">, </span>left: <span class="string string_quoted string_quoted_double string_quoted_double_js"><span class="punctuation punctuation_definition punctuation_definition_string punctuation_definition_string_begin punctuation_definition_string_begin_js">"</span>-<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> width<span class="meta meta_brace meta_brace_curly meta_brace_curly_js">}</span><span class="meta meta_delimiter meta_delimiter_object meta_delimiter_object_comma meta_delimiter_object_comma_js">, </span><span class="constant constant_numeric constant_numeric_js">400</span><span class="meta meta_brace meta_brace_round meta_brace_round_js">)</span>
        <span class="meta meta_delimiter meta_delimiter_method meta_delimiter_method_period meta_delimiter_method_period_js">.</span><span class="support support_function support_function_js support_function_js_jquery">remove</span><span class="punctuation punctuation_section punctuation_section_function punctuation_section_function_js">()</span>
        <span class="support support_function support_function_js support_function_js_jquery">.end</span><span class="meta meta_brace meta_brace_round meta_brace_round_js">()</span>
      <span class="support support_function support_function_js support_function_js_jquery">.html</span><span class="meta meta_brace meta_brace_round meta_brace_round_js">(</span>content<span class="meta meta_brace meta_brace_round meta_brace_round_js">)</span>
      <span class="support support_function support_function_js support_function_js_jquery">.css</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>left: width<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="support support_function support_function_js support_function_js_jquery">.animate</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>left: <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>0px<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>width: width<span class="meta meta_brace meta_brace_curly meta_brace_curly_js">}</span><span class="meta meta_delimiter meta_delimiter_object meta_delimiter_object_comma meta_delimiter_object_comma_js">, </span><span class="constant constant_numeric constant_numeric_js">400</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="punctuation punctuation_terminator punctuation_terminator_statement punctuation_terminator_statement_js">;</span>
  
  <span class="variable variable_language variable_language_js">this</span><span class="support support_function support_function_js support_function_js_jquery">.get</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>#/user/:name<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="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>partial<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>name.erb<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>name: <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>name<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_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>...
</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>

<p>Now, when you go to '#/user/aq' or similar, it will use the swap method to do a nifty transition, instead of ye old <code>html()</code>.</p>

<p>Theres more examples and Sammy on the way. Come join the mailing list or hang out in irc to learn or contribute.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.quirkey.com/blog/2009/06/12/sammyjs-hits-a-new-milestone-020/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>What I&#8217;ve been up to: The End o&#8217; May Edition</title>
		<link>http://www.quirkey.com/blog/2009/05/29/what-ive-been-up-to-the-end-o-may-edition/</link>
		<comments>http://www.quirkey.com/blog/2009/05/29/what-ive-been-up-to-the-end-o-may-edition/#comments</comments>
		<pubDate>Fri, 29 May 2009 14:59:08 +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=321</guid>
		<description><![CDATA[Another busy couple of weeks and a lot more &#8230; Stuff! Two weeks ago I released Sammy and since then its been getting a lot of great feedback. It was mentioned in a github rebase and Nick Plante wrote a great post on DDJ. I&#8217;m really impressed with what people have done with it so [...]]]></description>
			<content:encoded><![CDATA[	<p>Another busy couple of weeks and a lot more &#8230; Stuff!</p>

	<ul>
		<li>Two weeks ago <a href="http://www.quirkey.com/blog/2009/05/15/introducing-sammy-the-tiny-but-swingin-javascript-framework/" title="">I released Sammy</a> and since then its been getting a lot of great feedback. It was mentioned in a <a href="http://github.com/blog/433-github-rebase-21" title="">github rebase</a> and <a href="http://dobbscodetalk.com/index.php?option=com_myblog&#038;show=Sammy---A-jQuery-Web-Framework.html&#038;Itemid=29" title="">Nick Plante wrote a great post on <span class="caps">DDJ</span>.</a> I&#8217;m really impressed with what people have done with it so far. <a href="http://twitter.com/langalex" title="">Alex Lang,</a> especially, has fulfilled a vision I had by embedding <a href="http://github.com/langalex/couchdb_example_wiki/tree/4edff3ed2750a19bf57e74d19dc3e9153e461762/couchapp" title="">Sammy as the client controller for a couch app.</a> Also make sure to check out his <a href="http://github.com/langalex/boom_amazing/tree/master" title="">Boom Amazing</a> presentation tool using Sammy as the proxy for controlling a slideshow contained in a massive <span class="caps">SVG</span>. I&#8217;m crossing my fingers that they&#8217;ll be a video of his <a href="http://railswaycon.com/" title="">RailsWayCon</a> presentation. Sammy also has <a href="http://groups.google.com/group/sammyjs" title="">a mailing list now</a> and (hopefully) soon a dedicated <span class="caps">IRC</span> room.</li>
	</ul>

	<ul>
		<li><a href="http://code.quirkey.com/gembox" title="">Gembox</a> was <a href="http://www.rubyinside.com/rdoc-some-alternative-ways-of-looking-at-documentation-1785.html" title="">featured as a great tool for viewing RDocs on RubyInside.</a> This inspired a little flurry of activity and commits with more to come. Thanks to <a href="http://twitter.com/lenary" title="lenary">Samuel Elliot </a> Gembox works in passenger pane.</li>
	</ul>

	<ul>
		<li>EngineYard finally posted <a href="http://www.engineyard.com/blog/community/scotland-on-rails/" title="">the videos</a> from <a href="http://scotlandonrails.com" title="">Scotland on Rails</a> and you can <a href="http://scotland-on-rails.s3.amazonaws.com/2A02_AaronQuint-SOR.mp4" title="">view my talk in full quicktime glory.</a> Really you should just take the whole weekend and watch all the videos. <span class="caps">LOTS</span> of fantastic talks.</li>
	</ul>

	<ul>
		<li><a href="http://www.goruco.com" title="">Goruco</a> is tomorrow! If you&#8217;re attending and reading this, please come find me. I&#8217;ll probably be milling around with a bearded dude (<a href="http://twitter.com/mrb_bk" title="">@mrb_bk</a>).</li>
	</ul>
 ]]></content:encoded>
			<wfw:commentRss>http://www.quirkey.com/blog/2009/05/29/what-ive-been-up-to-the-end-o-may-edition/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
<enclosure url="http://scotland-on-rails.s3.amazonaws.com/2A02_AaronQuint-SOR.mp4" length="195213333" type="video/mp4" />
		</item>
		<item>
		<title>Introducing Sammy: The tiny but swingin&#8217; JavaScript Framework</title>
		<link>http://www.quirkey.com/blog/2009/05/15/introducing-sammy-the-tiny-but-swingin-javascript-framework/</link>
		<comments>http://www.quirkey.com/blog/2009/05/15/introducing-sammy-the-tiny-but-swingin-javascript-framework/#comments</comments>
		<pubDate>Fri, 15 May 2009 15:42:37 +0000</pubDate>
		<dc:creator>AQ</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[JavaScript]]></category>
		<category><![CDATA[Sammy]]></category>
		<category><![CDATA[Sinatra]]></category>
		<category><![CDATA[Software/Scripts]]></category>

		<guid isPermaLink="false">http://www.quirkey.com/blog/?p=308</guid>
		<description><![CDATA[After a couple months of off-hours hacking, I present to you Sammy. Sammy is an easy to use JavaScript framework that allows you to build simple front end applications using &#8216;routes&#8217; and &#8216;events&#8217;. It&#8217;s also very tiny. Using the YUI Compression its only 7Kb. Get Started Watch a Screencast (iPhone) Read the Introduction Read the [...]]]></description>
			<content:encoded><![CDATA[	<p>After a couple months of off-hours hacking, I present to you <a href="http://code.quirkey.com/sammy" title="">Sammy.</a> Sammy is an easy to use JavaScript framework that allows you to build simple front end applications using &#8216;routes&#8217; and &#8216;events&#8217;. It&#8217;s also very tiny. Using the <span class="caps">YUI </span>Compression its only 7Kb.</p>

	<h3>Get Started</h3>

	<ul>
		<li><a href="http://s3.amazonaws.com/sammy-js/screencasts/sammy-screencasts-01/sammy-screencasts-01.mov" title="">Watch a Screencast</a> (<a href="http://s3.amazonaws.com/sammy-js/screencasts/sammy-screencasts-01/sammy-screencasts-01-iPhone.m4v" title="">iPhone</a>)</li>
		<li><a href="http://code.quirkey.com/sammy" title="">Read the Introduction</a></li>
		<li><a href="http://code.quirkey.com/sammy/docs/index.html" title="">Read the Docs</a></li>
		<li><a href="http://twitter.com/sammy_js" title="">Follow @sammy_js</a></li>
		<li><a href="http://groups.google.com/group/sammyjs" title="">Join the mailing list</a></li>
	</ul>

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

	<h3>The Story</h3>

	<p>About three months ago, when I was knee deep in hacking and playing with <a href="http://sinatrarb.com" title="">Sinatra</a> I had this weird moment as I woke up one morning: &#8220;What if I could build Sinatra in JavaScript?&#8221; At that point it was just a challenge &#8211; I had just started doing almost full-time JS for a client and it seemed like a fun project.</p>

	<p>As I started to actually implement it (slowly in short spurts on the weekends), I realized that using the power of JavaScript&#8217;s closures and jQuery&#8217;s powerful event system, this could be something more then just a &#8216;clone&#8217;. It could actually be . . . useful!</p>

	<p>With that in mind, I set out to actually make is usable. I cleaned up the code, I wrote some <a href="http://github.com/quirkey/sammy/tree/master/examples" title="">example implementations</a>, and most importantly &#8211; I <a href="http://code.quirkey.com/sammy/docs/index.html" title="">documented the shit out of it.</a></p>

	<p>I&#8217;m pretty excited about it (can&#8217;t you tell?) especially about its possible uses for structuring applications on the front-end for <span class="caps">RES</span>Tful Databases and services. Embed it in a <a href="http://github.com/jchris/couchapp/tree" title="">CouchApp</a> to build an entire application in JavaScript while having access to a full range of documents/querying abilities.</p>

	<h3>The Future</h3>

	<p>I&#8217;m going to continue refining and adding examples. Please feel free to email me or contact me through github with questions/feedback.</p>

	<p>Happy Friday!</p>
 ]]></content:encoded>
			<wfw:commentRss>http://www.quirkey.com/blog/2009/05/15/introducing-sammy-the-tiny-but-swingin-javascript-framework/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
<enclosure url="http://s3.amazonaws.com/sammy-js/screencasts/sammy-screencasts-01/sammy-screencasts-01.mov" length="197" type="video/quicktime" />
<enclosure url="http://s3.amazonaws.com/sammy-js/screencasts/sammy-screencasts-01/sammy-screencasts-01-iPhone.m4v" length="12437032" type="video/x-m4v" />
		</item>
	</channel>
</rss>
