<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
 
 <title>Recursive</title>
 <link href="http://recursive-design.com/feed/" rel="self"/>
 <link href="http://recursive-design.com/"/>
 <updated>2012-08-11T12:40:24-07:00</updated>
 <id>http://recursive-design.com/</id>
 <author>
   <name>Recursive</name>
   <email>mail@recursive-design.com</email>
 </author>

 
 <entry>
   <title>ExtJS Custom Templates, data-binding and interactivity</title>
   <link href="http://recursive-design.com/javascript/2012/08/11/extjs-templates"/>
   <updated>2012-08-11T00:00:00-07:00</updated>
   <id>http://recursive-design.com/javascript/2012/08/11/extjs-templates</id>
   <content type="html">&lt;p&gt;This is the second part in a series of articles on the strengths and weakness of Sencha Touch and ExtJS MVC. &lt;a href='/javascript/2012/08/06/sencha-events/'&gt;Part 1 shows the general approach for writing re-usable robust code&lt;/a&gt; This article delves into the weaknesses of this approach, particularly when using ExtJS custom templates. &lt;a href='http://extdesenv.com/extensions/decouple-controller-and-view-in-sencha-mvc/'&gt;You might want to read this great complimentary article by a different author first.&lt;/a&gt;&lt;/p&gt;

&lt;h2 id='sticking_point_custom_templates'&gt;sticking point: custom templates&lt;/h2&gt;

&lt;p&gt;Productivity in ExtJS comes from composing existing widgets. However, I find myself with many custom templates.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='coffeescript'&gt;    &lt;span class='nx'&gt;Ext&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;define&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;Yap.view.Feed&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
        &lt;span class='nv'&gt;extend: &lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;Ext.view.View&amp;#39;&lt;/span&gt;
        &lt;span class='nv'&gt;itemSelector: &lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;div.entry&amp;#39;&lt;/span&gt;
        &lt;span class='nv'&gt;config:&lt;/span&gt;
            &lt;span class='nv'&gt;cls: &lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;feedlist&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
            &lt;span class='nv'&gt;store: &lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;Feeds&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;

        &lt;span class='nv'&gt;tpl: &lt;/span&gt;&lt;span class='nx'&gt;Ext&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;create&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;Ext.XTemplate&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;
&lt;span class='s2'&gt;          &amp;lt;tpl for=&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&amp;gt;&lt;/span&gt;
&lt;span class='s2'&gt;            &amp;lt;div class=&amp;quot;&lt;/span&gt;&lt;span class='nx'&gt;feed&lt;/span&gt;&lt;span class='o'&gt;-&lt;/span&gt;&lt;span class='nx'&gt;entry&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;&amp;gt;&lt;/span&gt;
&lt;span class='s2'&gt;              ...&lt;/span&gt;
&lt;span class='s2'&gt;            &amp;lt;/div&amp;gt;&lt;/span&gt;
&lt;span class='s2'&gt;          &amp;lt;/tpl&amp;gt;&lt;/span&gt;
&lt;span class='s2'&gt;          &amp;quot;&amp;quot;&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;It is nice that I can populate this view by putting data in a store, so I am happy up until the point the user needs to interact with my view. The standard way of mapping a user action to a controller function is to use the ref system in the controller. The problem is that this means changes to the view break the controller. Lets see an approach of referencing just the widget in the ref system:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='coffeescript'&gt;    &lt;span class='nx'&gt;Ext&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;define&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;Yap.controller.Controller&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;Sencha&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;controllerCompatibility&lt;/span&gt;
      &lt;span class='nv'&gt;extend: &lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;Ext.app.Controller&amp;quot;&lt;/span&gt;
      &lt;span class='nv'&gt;views: &lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;View&amp;#39;&lt;/span&gt; &lt;span class='p'&gt;],&lt;/span&gt;

      &lt;span class='nv'&gt;events:&lt;/span&gt;
        &lt;span class='nv'&gt;feed: &lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;start&amp;#39;&lt;/span&gt;

      &lt;span class='nv'&gt;config:&lt;/span&gt;
        &lt;span class='nv'&gt;control:&lt;/span&gt;
          &lt;span class='nv'&gt;view:&lt;/span&gt;
            &lt;span class='nv'&gt;itemtap: &lt;/span&gt;  &lt;span class='s1'&gt;&amp;#39;itemTapToPress&amp;#39;&lt;/span&gt;
            &lt;span class='nv'&gt;itemclick: &lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;itemClickToPress&amp;#39;&lt;/span&gt;

      &lt;span class='nv'&gt;itemTapToPress: &lt;/span&gt;&lt;span class='nf'&gt;(_1, _2, _3, record, e) -&amp;gt;&lt;/span&gt; &lt;span class='nx'&gt;@onItemPress&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;record&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;e&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
      &lt;span class='nv'&gt;itemClickToPress: &lt;/span&gt;&lt;span class='nf'&gt;(_1, record, _2, _3, e) -&amp;gt;&lt;/span&gt; &lt;span class='nx'&gt;@onItemPress&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;record&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;e&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;

      &lt;span class='nv'&gt;onItemPress: &lt;/span&gt;&lt;span class='nf'&gt;(record, e) -&amp;gt;&lt;/span&gt;
        &lt;span class='nv'&gt;elTarget = &lt;/span&gt;&lt;span class='nx'&gt;Ext&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;get&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;e&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;target&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
        
        &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;elTarget&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='o'&gt;is&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;.add&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt;
          &lt;span class='nx'&gt;alert&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;add&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
        
        &lt;span class='k'&gt;else&lt;/span&gt; &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;elTarget&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='o'&gt;is&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;.comment&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;))&lt;/span&gt;
          &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;onComment&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;record&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;comment&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
        
        &lt;span class='p'&gt;...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;An alternative that I would prefer is to actually listen for events in the view itself and then fire up events to the controller. This can be done in Sench Touch, but not in ExtJS. It does not solve the problems outlined, but at least all responsibility for view changes exists in one file.&lt;/p&gt;

&lt;p&gt;Note that the above code does work in both Sencha Touch and in ExtJS by normalizing the difference between click and tap. Since there are multiple elements that can be clicked, we are forced to know about the DOM to determine where the click came from.&lt;/p&gt;

&lt;p&gt;I could certainly use an onclick handler to fire an event, but I also want to automatically fire up the record of data as above. The best I can really do is fire an id and then lookup the record from its id. But this is just read-only information. After all of this effort, I still cannot modify the view without writing code that knows about the DOM. We have these limitations because custom ExtJS templates are dumb strings.&lt;/p&gt;

&lt;h2 id='components_not_templates'&gt;Components, not templates&lt;/h2&gt;

&lt;p&gt;If instead of using custom templates we use ExtJS components we can achieve dom manipulation from controllers that have no knowledge of the DOM or the components. Lets take a look at a function that creates such a button component:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='coffeescript'&gt;    &lt;span class='nv'&gt;eventedButton = &lt;/span&gt;&lt;span class='nf'&gt;(event, text) -&amp;gt;&lt;/span&gt;
      &lt;span class='c1'&gt;# make sure that button gets pressed from an event fire&lt;/span&gt;
      &lt;span class='c1'&gt;# uses our button override&lt;/span&gt;
      &lt;span class='c1'&gt;# for example this allows the application to start with a button pressed by firing an event&lt;/span&gt;
      &lt;span class='nv'&gt;listener = &lt;/span&gt;&lt;span class='p'&gt;{}&lt;/span&gt;
      &lt;span class='nx'&gt;listener&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='nx'&gt;event&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='o'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;doToggle&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt; &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='o'&gt;!&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;pressed&lt;/span&gt;

      &lt;span class='p'&gt;{&lt;/span&gt;
        &lt;span class='nv'&gt;ui: &lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;link&amp;#39;&lt;/span&gt;
        &lt;span class='nv'&gt;text: &lt;/span&gt;&lt;span class='nx'&gt;text&lt;/span&gt;
        &lt;span class='nv'&gt;handler: &lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='nx'&gt;Yap&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;fire&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;event&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
        &lt;span class='nv'&gt;eventListeners: &lt;/span&gt;&lt;span class='nx'&gt;listener&lt;/span&gt;
        &lt;span class='nv'&gt;allowDepress: &lt;/span&gt;&lt;span class='kc'&gt;false&lt;/span&gt;
        &lt;span class='nv'&gt;enableToggle: &lt;/span&gt;&lt;span class='kc'&gt;true&lt;/span&gt;
      &lt;span class='p'&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Our component fires an event when clicked and listens for the same event. The benefit of firing and listening to the same event is that when the page is re-loaded a controller will restore the application state by firing an event corresponding to the button previously pressed. But the point is that a controller can simply fire an event, and the DOM will end up changing.&lt;/p&gt;

&lt;p&gt;In a view, I have something like the following for the buttons:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='coffeescript'&gt;      &lt;span class='nv'&gt;xtype: &lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;toolbar&amp;#39;&lt;/span&gt;
      &lt;span class='nv'&gt;ui: &lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;plain&amp;#39;&lt;/span&gt;
      &lt;span class='nv'&gt;cls: &lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;viewport-main-toolbar&amp;#39;&lt;/span&gt;
      &lt;span class='nv'&gt;items: &lt;/span&gt;&lt;span class='p'&gt;[{&lt;/span&gt;
        &lt;span class='nv'&gt;xtype: &lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;textfield&amp;#39;&lt;/span&gt;
        &lt;span class='nv'&gt;width: &lt;/span&gt;&lt;span class='mi'&gt;180&lt;/span&gt; 
      &lt;span class='p'&gt;}&lt;/span&gt;
      &lt;span class='p'&gt;,&lt;/span&gt;   
        &lt;span class='nx'&gt;eventedButton&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;event1&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;Text1&amp;#39;&lt;/span&gt;
      &lt;span class='p'&gt;,&lt;/span&gt;
        &lt;span class='nx'&gt;eventedButton&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;event2&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;Text2&amp;#39;&lt;/span&gt;
      &lt;span class='p'&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;I can turn these buttons into a full tabs implementation if I have a component named event1 and event2.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='coffeescript'&gt;      &lt;span class='nx'&gt;Yap&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;UI&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;activateTab&lt;/span&gt; &lt;span class='o'&gt;::&lt;/span&gt; &lt;span class='nf'&gt;(Str) -&amp;gt;&lt;/span&gt; &lt;span class='nx'&gt;Any&lt;/span&gt;
      &lt;span class='nv'&gt;Yap.UI.activateTab = &lt;/span&gt;&lt;span class='nf'&gt;(tabname) -&amp;gt;&lt;/span&gt;
        &lt;span class='nx'&gt;unless&lt;/span&gt; &lt;span class='nv'&gt;tabnames = &lt;/span&gt;&lt;span class='nx'&gt;Yap&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;UI&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;registeredTabs&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='nx'&gt;tabname&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt;
          &lt;span class='k'&gt;throw&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;unregistered tab: #{tabname}&amp;quot;&lt;/span&gt;
        &lt;span class='k'&gt;for&lt;/span&gt; &lt;span class='nx'&gt;other_tabname&lt;/span&gt; &lt;span class='k'&gt;in&lt;/span&gt; &lt;span class='nx'&gt;tabnames&lt;/span&gt;
          &lt;span class='nx'&gt;unless&lt;/span&gt; &lt;span class='nx'&gt;other_tabname&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='nx'&gt;tabname&lt;/span&gt;
            &lt;span class='nx'&gt;Ext&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;getCmp&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;other_tabname&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;hide&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt;
        &lt;span class='nx'&gt;Ext&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;getCmp&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;tabname&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;show&lt;/span&gt;&lt;span class='p'&gt;()&lt;/span&gt;

      &lt;span class='nv'&gt;Yap.UI.registeredTabs = &lt;/span&gt;&lt;span class='p'&gt;{}&lt;/span&gt;
      &lt;span class='nv'&gt;Yap.UI.registerTabs = &lt;/span&gt;&lt;span class='nf'&gt;(tabnames) -&amp;gt;&lt;/span&gt;
        &lt;span class='k'&gt;for&lt;/span&gt; &lt;span class='nx'&gt;tabname&lt;/span&gt; &lt;span class='k'&gt;in&lt;/span&gt; &lt;span class='nx'&gt;tabnames&lt;/span&gt;
          &lt;span class='nx'&gt;Yap&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;UI&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;registeredTabs&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='nx'&gt;tabname&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;tabnames&lt;/span&gt;

      &lt;span class='nx'&gt;Yap&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;UI&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;registerTabs&lt;/span&gt; &lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;event1&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;event2&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This is great, we have isolated components both properly updating their state and communicating with the world through events. but the data we are using to create multiple components is static. This brings us back to our custom templates that use dynamic data from a store and are automatically updated when a store changes.&lt;/p&gt;

&lt;p&gt;So we can see a solution to data-binding in ExtJS: avoid custom templates and figure out how to hookup arbitrary components to the datachange of a store. But we can&amp;#8217;t write HTML, we have to use just components for any element that requires interaction. And I don&amp;#8217;t feel like figuring out the code to make this work: at this point I would be doing a lot of work that a framework is supposed to be doing for me and I have to work with a new abstraction instead of plain html.&lt;/p&gt;

&lt;p&gt;ExtJS is powerful because of its re-usable components, but custom templates with interaction means we are not hitting the sweet spot of the framework. I see a few ways forward:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;as mentioned, discover a way to use just components, and never any templates&lt;/li&gt;

&lt;li&gt;enhance data binding with a small add-on like &lt;a href='http://www.rivetsjs.com'&gt;rivets.js&lt;/a&gt;. Find another add-on or build a library to enhance view-controller communication to be DOM independent.&lt;/li&gt;

&lt;li&gt;Use an entirely different framework in place of custom templates.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id='stay_tuned'&gt;Stay Tuned!&lt;/h2&gt;

&lt;p&gt;A follow up article on solving these issues by injecting an entirely different framework into ExtJS.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Robust, reusable Sencha Touch and ExtJS code</title>
   <link href="http://recursive-design.com/javascript/2012/08/06/sencha-events"/>
   <updated>2012-08-06T00:00:00-07:00</updated>
   <id>http://recursive-design.com/javascript/2012/08/06/sencha-events</id>
   <content type="html">&lt;h1 id='summary'&gt;Summary&lt;/h1&gt;

&lt;p&gt;We can make non-view code compatible between Sencha Touch &amp;amp; ExtJS by developing a compatibility layer specialized for our application. Events help de-couple controllers from views, allowing controllers to be re-used, and they can also be adapted to automatically restore application state.&lt;/p&gt;

&lt;h1 id='why_sencha_touch__extjs'&gt;Why Sencha Touch &amp;amp; ExtJS&lt;/h1&gt;

&lt;p&gt;The motivation for using these frameworks is to have managed re-usable UI components.&lt;/p&gt;

&lt;p&gt;Sencha Touch really takes advantage of this to provide widgets that look native, are efficiently created and destroyed, and use full-screen layouts. Sencha Touch is well optimized for mobile and is one of the few proven mobile web development toolkits.&lt;/p&gt;

&lt;p&gt;ExtJS has some powerful components like a grid view and a tree view. Once you are using Sencha Touch, ExtJS becomes attractive for re-using code.&lt;/p&gt;

&lt;p&gt;We are getting ready to release some applications that use these frameworks. We do not yet have much man power behind these efforts (but you can &lt;a href='http://tunein.yap.tv/jobs.html'&gt;help remedy that&lt;/a&gt;), so we need to use these frameworks in productive ways.&lt;/p&gt;

&lt;h1 id='writing_robust_and_reusable_sencha_touchextjs'&gt;Writing robust and re-usable Sencha Touch/ExtJS&lt;/h1&gt;

&lt;p&gt;There is a big toolkit at your disposal and multiple ways to write code with the same functionality. What I am looking for are best practices that will lead to robust and flexible code that is re-usable.&lt;/p&gt;

&lt;h2 id='code_reuse_between_frameworks'&gt;Code re-use between frameworks&lt;/h2&gt;

&lt;p&gt;These frameworks have a lot of API compatibility. Sencha Touch has many advancements not yet present in ExtJS. My understanding is that internally ExtJS underwent big changes for 4.0, some of which were to pave the way for compatibility with Sencha Touch. Unfortunately, the performance of the new release was unexpectedly poor. Now much of the development effort is focused on improving ExtJS performance and API compatibility with Sencha Touch keeps getting delayed. So to achieve compatibility we need to take matters into our own hands.&lt;/p&gt;

&lt;p&gt;True universal compatibility might be an impossible task. But If I just tackle the compatibility issues that my application needs, it does not seem that hard to achieve.&lt;/p&gt;

&lt;h3 id='models_and_stores'&gt;Models and Stores&lt;/h3&gt;

&lt;p&gt;Models and Stores are the most compatible between the two frameworks. The main difference appears to be that a lot of functionality that you would specify at the top level of an ExtJS model. I have one function that will do a proper translation called &lt;code&gt;Sencha.modelCompatibility&lt;/code&gt;. Note that the code samples given in this blog are in coffee script.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='coffeescript'&gt;    &lt;span class='nx'&gt;Ext&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;define&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;Yap.model.Country&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;Sencha&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;modelCompatibility&lt;/span&gt;&lt;span class='p'&gt;({&lt;/span&gt;
      &lt;span class='nv'&gt;extend: &lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;Ext.data.Model&amp;quot;&lt;/span&gt;
      &lt;span class='nv'&gt;config:&lt;/span&gt;
        &lt;span class='nv'&gt;idProperty: &lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;_id&amp;quot;&lt;/span&gt;
        &lt;span class='nv'&gt;fields: &lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;
            &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='nv'&gt;name: &lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;_id&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;                &lt;span class='nx'&gt;type&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;int&amp;#39;&lt;/span&gt;     &lt;span class='p'&gt;}&lt;/span&gt;
            &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='nv'&gt;name: &lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;code&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;               &lt;span class='nx'&gt;type&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;string&amp;#39;&lt;/span&gt;  &lt;span class='p'&gt;}&lt;/span&gt;
            &lt;span class='p'&gt;{&lt;/span&gt; &lt;span class='nv'&gt;name: &lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;name&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;               &lt;span class='nx'&gt;type&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;string&amp;#39;&lt;/span&gt;  &lt;span class='p'&gt;}&lt;/span&gt;
    &lt;span class='p'&gt;}))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Here are our definitions, note there is one for Store also:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='coffeescript'&gt;    &lt;span class='nb'&gt;window&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nv'&gt;Sencha = &lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;
      &lt;span class='nv'&gt;isTouch = &lt;/span&gt;&lt;span class='o'&gt;!!&lt;/span&gt;&lt;span class='nx'&gt;Ext&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;getVersion&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;touch&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;&lt;span class='o'&gt;?&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;version&lt;/span&gt;&lt;span class='o'&gt;?&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;match&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='sr'&gt;/2\./&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
      &lt;span class='p'&gt;{&lt;/span&gt;
        &lt;span class='nv'&gt;isTouch: &lt;/span&gt;&lt;span class='nx'&gt;isTouch&lt;/span&gt;
        &lt;span class='nv'&gt;isExtJS: &lt;/span&gt;&lt;span class='o'&gt;!&lt;/span&gt;&lt;span class='nx'&gt;isTouch&lt;/span&gt;
      &lt;span class='p'&gt;})()&lt;/span&gt;

    &lt;span class='nv'&gt;Sencha.modelCompatibility =&lt;/span&gt;
      &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='nx'&gt;Sencha&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;isTouch&lt;/span&gt; &lt;span class='k'&gt;then&lt;/span&gt; &lt;span class='nf'&gt;(x) -&amp;gt;&lt;/span&gt; &lt;span class='nx'&gt;x&lt;/span&gt; &lt;span class='k'&gt;else&lt;/span&gt;
        &lt;span class='nf'&gt;(classConfig) -&amp;gt;&lt;/span&gt;
          &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='nv'&gt;cfg = &lt;/span&gt;&lt;span class='nx'&gt;classConfig&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;config&lt;/span&gt;
            &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='nv'&gt;fs = &lt;/span&gt;&lt;span class='nx'&gt;cfg&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;fields&lt;/span&gt;
              &lt;span class='nv'&gt;classConfig.fields = &lt;/span&gt;&lt;span class='nx'&gt;fs&lt;/span&gt;
              &lt;span class='k'&gt;delete&lt;/span&gt; &lt;span class='nx'&gt;cfg&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;fields&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt;
          &lt;span class='nx'&gt;classConfig&lt;/span&gt;

    &lt;span class='nv'&gt;Sencha.storeCompatibility =&lt;/span&gt;
      &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='nx'&gt;Sencha&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;isTouch&lt;/span&gt; &lt;span class='k'&gt;then&lt;/span&gt; &lt;span class='nf'&gt;(x) -&amp;gt;&lt;/span&gt; &lt;span class='nx'&gt;x&lt;/span&gt; &lt;span class='k'&gt;else&lt;/span&gt;
        &lt;span class='nf'&gt;(classConfig) -&amp;gt;&lt;/span&gt;
          &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='nx'&gt;classConfig&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;config&lt;/span&gt;
            &lt;span class='k'&gt;for&lt;/span&gt; &lt;span class='nx'&gt;lifted&lt;/span&gt; &lt;span class='k'&gt;in&lt;/span&gt; &lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;model&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;proxy&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt;
              &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='nv'&gt;val = &lt;/span&gt;&lt;span class='nx'&gt;classConfig&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;config&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='nx'&gt;lifted&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt;
                &lt;span class='nx'&gt;classConfig&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='nx'&gt;lifted&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;val&lt;/span&gt;
                &lt;span class='k'&gt;delete&lt;/span&gt; &lt;span class='nx'&gt;classConfig&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;config&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='nx'&gt;lifted&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt;
          &lt;span class='nx'&gt;classConfig&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;That was pretty easy!&lt;/p&gt;

&lt;h3 id='controllerview_compatibility'&gt;Controller/View compatibility&lt;/h3&gt;

&lt;p&gt;I have never tried to make a view compatible between the 2 frameworks. Mobile &amp;amp; desktop require different views most of the time. Even when the views are similar they are generally using components that do not easily translate between the 2 frameworks.&lt;/p&gt;

&lt;p&gt;This brings us to controllers. While models and stores need properties to be moved under &lt;code&gt;config&lt;/code&gt;, some of the controller aspects need some involved translation.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='coffeescript'&gt;    &lt;span class='nv'&gt;Sencha.controllerCompatibility =&lt;/span&gt;
      &lt;span class='nf'&gt;(classConfig) -&amp;gt;&lt;/span&gt;
        &lt;span class='nv'&gt;compatibleRefs = &lt;/span&gt;&lt;span class='nf'&gt;(classConfig) -&amp;gt;&lt;/span&gt;
           &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='nv'&gt;touchRefs = &lt;/span&gt;&lt;span class='nx'&gt;classConfig&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;config&lt;/span&gt;&lt;span class='o'&gt;?&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;refs&lt;/span&gt;
              &lt;span class='nv'&gt;classConfig.refs =&lt;/span&gt;
                &lt;span class='k'&gt;for&lt;/span&gt; &lt;span class='nx'&gt;ref&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;selector&lt;/span&gt; &lt;span class='k'&gt;of&lt;/span&gt; &lt;span class='nx'&gt;touchRefs&lt;/span&gt;
                  &lt;span class='p'&gt;{&lt;/span&gt;&lt;span class='nx'&gt;ref&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt;&lt;span class='nx'&gt;ref&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;selector&lt;/span&gt;&lt;span class='o'&gt;:&lt;/span&gt;&lt;span class='nx'&gt;selector&lt;/span&gt;&lt;span class='p'&gt;}&lt;/span&gt;
              &lt;span class='k'&gt;delete&lt;/span&gt; &lt;span class='nx'&gt;classConfig&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;config&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;refs&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt;

        &lt;span class='nv'&gt;classConfig = &lt;/span&gt;&lt;span class='nx'&gt;makeEventHistory&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;classConfig&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
        &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='o'&gt;!&lt;/span&gt;&lt;span class='nx'&gt;Sencha&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;isTouch&lt;/span&gt;
          &lt;span class='nx'&gt;compatibleRefs&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;classConfig&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
          &lt;span class='nv'&gt;classConfig.getApplication = &lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt; &lt;span class='nx'&gt;@application&lt;/span&gt;

          &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='nx'&gt;classConfig&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;config&lt;/span&gt;&lt;span class='o'&gt;?&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;control&lt;/span&gt;
            &lt;span class='nv'&gt;oldInit = &lt;/span&gt;&lt;span class='nx'&gt;classConfig&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;init&lt;/span&gt;
            &lt;span class='nv'&gt;classConfig.init = &lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;
              &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='nx'&gt;@config&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;control&lt;/span&gt;
                &lt;span class='nv'&gt;control = &lt;/span&gt;&lt;span class='p'&gt;{}&lt;/span&gt;
                &lt;span class='k'&gt;for&lt;/span&gt; &lt;span class='nx'&gt;selector&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;eventDispatch&lt;/span&gt; &lt;span class='k'&gt;of&lt;/span&gt; &lt;span class='nx'&gt;@config&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;control&lt;/span&gt;
                  &lt;span class='nv'&gt;dispatch = &lt;/span&gt;&lt;span class='p'&gt;{}&lt;/span&gt;
                  &lt;span class='k'&gt;for&lt;/span&gt; &lt;span class='nx'&gt;event&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;fn&lt;/span&gt; &lt;span class='k'&gt;of&lt;/span&gt; &lt;span class='nx'&gt;eventDispatch&lt;/span&gt;
                    &lt;span class='nx'&gt;dispatch&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='nx'&gt;event&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='nx'&gt;fn&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt;
                    &lt;span class='kc'&gt;undefined&lt;/span&gt;
                  &lt;span class='nx'&gt;control&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='nx'&gt;selector&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nx'&gt;dispatch&lt;/span&gt;
                  &lt;span class='kc'&gt;undefined&lt;/span&gt;
                &lt;span class='nx'&gt;console&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;log&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;control&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
                &lt;span class='nx'&gt;@application&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;control&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;control&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='kc'&gt;undefined&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
                &lt;span class='k'&gt;delete&lt;/span&gt; &lt;span class='nx'&gt;@config&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;control&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt;

              &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='nx'&gt;oldInit&lt;/span&gt;
                &lt;span class='nx'&gt;oldInit&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;apply&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;arguments&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
              &lt;span class='k'&gt;else&lt;/span&gt;
                &lt;span class='nx'&gt;@callParent&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;arguments&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;

        &lt;span class='nx'&gt;classConfig&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The code is almost all the code we needed to re-use code between our applications. Our API calls use the same code and go through the same &lt;code&gt;Ext.data.JsonP.request&lt;/code&gt; function for both frameworks. We have a few overrides elsewhere and a few if Sencha.isTouch, statements, but this makes it possible to re-use everything but views. &lt;code&gt;makeEventHistory&lt;/code&gt; in the code sample is an enhancement that leads us to the discussion of robust code.&lt;/p&gt;

&lt;h2 id='controllers_views_and_robust_code_reuse'&gt;Controllers, Views, and robust code re-use&lt;/h2&gt;

&lt;p&gt;We have already stated that view-reuse is a non-starter. That create a big problem for controllers because they are often written in a way that deeply couples them to the view. I do not think there is something fundamentally wrong with this approach, but one just needs to figure out how to still re-use code. One appraoch would be to have small view-controllers that know about the view and then communicate to other re-usable (controller) code. I think this is similar to what &lt;a href='http://deftjs.org'&gt;deftJS&lt;/a&gt; (an ExtJS/Sencha Touch extension) does.&lt;/p&gt;

&lt;p&gt;My issue with this approach and with the normal controller approach is that the view references are inherently fragile and a poor way to communicate between views and controllers. Sencha Touch:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='coffeescript'&gt;    &lt;span class='nv'&gt;refs: &lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;
        &lt;span class='p'&gt;{&lt;/span&gt;
            &lt;span class='s1'&gt;&amp;#39;mydiv&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;:&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;div.my&amp;#39;&lt;/span&gt;
        &lt;span class='p'&gt;}&lt;/span&gt;
    &lt;span class='p'&gt;],&lt;/span&gt;

    &lt;span class='nv'&gt;control: &lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;
      &lt;span class='nv'&gt;mydiv: &lt;/span&gt;&lt;span class='p'&gt;{&lt;/span&gt;
        &lt;span class='nv'&gt;onTap: &lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;myTapFn&amp;#39;&lt;/span&gt;
      &lt;span class='p'&gt;}&lt;/span&gt;
    &lt;span class='p'&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Views change frequently, and every change risks silently breaking a DOM query used by both the controller DOM references and their associated control functions. Even if we have 100% test coverage and are confident we can correct all breakages, DOM queries are an unnecessarily complex approach to communicating with a view.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;DOM queries are an indicator that the javascript framework is not high-level enough.&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Fortunately we have a great tool at our disposal for communicating between the view and the controller: events.&lt;/p&gt;

&lt;h3 id='communicating_through_events'&gt;Communicating through events&lt;/h3&gt;

&lt;p&gt;Our controllers and our views can listen for and fire events. We can create a controller that has no knowledge of the DOM by firing an event from the view.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='coffeescript'&gt;    &lt;span class='nx'&gt;Ext&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;define&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;Yap.view.stuff&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt;
      &lt;span class='nv'&gt;extend: &lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;Ext.dataview.List&amp;quot;&lt;/span&gt;
      &lt;span class='nv'&gt;config:&lt;/span&gt;
        &lt;span class='nv'&gt;store        : &lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;Stuff&amp;#39;&lt;/span&gt;
        &lt;span class='nv'&gt;listeners:&lt;/span&gt;
          &lt;span class='nv'&gt;select: &lt;/span&gt;&lt;span class='nf'&gt;(list, record) -&amp;gt;&lt;/span&gt; &lt;span class='nx'&gt;Yap&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;app&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;fireEvent&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;choose-item&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;record&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;I was very happy with this code. On the controller side we fill up a store with data, render the view, and then listen for an event that gives us the selection back. We have achieved 2-way data-binding, and we can swap out different views and re-use our controller between Sencha Touch and ExtJS. This Sencha Touch view (some more config options emitted) is producing a full-screen list that looks native, no styling required on my part.&lt;/p&gt;

&lt;h3 id='changing_the_url_hash_based_on_events'&gt;changing the url hash based on events&lt;/h3&gt;

&lt;p&gt;Developing a UI becomes very tedious when a long sequence of clicks are required to reach the point in the UI that is being worked on. Since I am already firing events, I set the events as the url hash. Refreshing the browser fires the latest event, getting me close to the point in the UI that I was previously at. There is a limitation to this: a refreshed event must be able to recover all the state required. So I register all events that work with this principle: other events will not change the hash.&lt;/p&gt;

&lt;p&gt;In controller I just register an event and a callback:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='coffeescript'&gt;    &lt;span class='nx'&gt;Ext&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;define&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;Yap.controller.Controller&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;Sencha&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;controllerCompatibility&lt;/span&gt;
      &lt;span class='nv'&gt;extend: &lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;Ext.app.Controller&amp;quot;&lt;/span&gt;
      &lt;span class='nv'&gt;events:&lt;/span&gt;
        &lt;span class='nv'&gt;start: &lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;onStart&amp;#39;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The above mentioned makeEventHistory processes this:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='coffeescript'&gt;    &lt;span class='c1'&gt;# enhancement, not compatibility&lt;/span&gt;
    &lt;span class='c1'&gt;#&lt;/span&gt;
    &lt;span class='c1'&gt;# in config, specify an event map in the format of the normal config routes key&lt;/span&gt;
    &lt;span class='c1'&gt;#&lt;/span&gt;
    &lt;span class='c1'&gt;# The events will be listened to (getApplication().on), and the location hash will be changed to match the event.&lt;/span&gt;
    &lt;span class='c1'&gt;# Now add a catch-all route that fires events from the location hash.&lt;/span&gt;
    &lt;span class='c1'&gt;# This makes debugging a lot easier: refresh your browser to get back to where you were.&lt;/span&gt;
    &lt;span class='c1'&gt;# But this also means you need to figure out what to do if a fired event expects data.&lt;/span&gt;
    &lt;span class='nv'&gt;makeEventHistory = &lt;/span&gt;&lt;span class='nf'&gt;(classConfig) -&amp;gt;&lt;/span&gt;
      &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='nv'&gt;events = &lt;/span&gt;&lt;span class='nx'&gt;classConfig&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;config&lt;/span&gt;&lt;span class='o'&gt;?&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;events&lt;/span&gt;
        &lt;span class='k'&gt;throw&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='s2'&gt;&amp;quot;did not expect before&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='nx'&gt;classConfig&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;before&lt;/span&gt;

        &lt;span class='c1'&gt;# whenever an event is triggered, change the hash location&lt;/span&gt;
        &lt;span class='c1'&gt;# Conveniently, a page refresh takes us back to where we were.&lt;/span&gt;
        &lt;span class='c1'&gt;# However, if there was data with the event, on refresh it will be empty&lt;/span&gt;
        &lt;span class='nv'&gt;hist_ev_map = &lt;/span&gt;&lt;span class='p'&gt;{}&lt;/span&gt;
        &lt;span class='k'&gt;for&lt;/span&gt; &lt;span class='nx'&gt;ev&lt;/span&gt; &lt;span class='k'&gt;of&lt;/span&gt; &lt;span class='nx'&gt;events&lt;/span&gt;
          &lt;span class='nx'&gt;hist_ev_map&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='nf'&gt;(_1,_2,event) -&amp;gt;&lt;/span&gt;
            &lt;span class='nb'&gt;window&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nv'&gt;location.hash = &lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;!/&amp;#39;&lt;/span&gt; &lt;span class='o'&gt;+&lt;/span&gt; &lt;span class='p'&gt;((&lt;/span&gt;&lt;span class='nx'&gt;event&lt;/span&gt; &lt;span class='o'&gt;||&lt;/span&gt; &lt;span class='nx'&gt;_2&lt;/span&gt;&lt;span class='p'&gt;).&lt;/span&gt;&lt;span class='nx'&gt;info&lt;/span&gt;&lt;span class='o'&gt;?&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;eventName&lt;/span&gt; &lt;span class='o'&gt;||&lt;/span&gt; &lt;span class='nx'&gt;ev&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
          &lt;span class='kc'&gt;undefined&lt;/span&gt;

        &lt;span class='c1'&gt;# There is probably a way to do this without overriding init&lt;/span&gt;
        &lt;span class='nv'&gt;oldInit = &lt;/span&gt;&lt;span class='nx'&gt;classConfig&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;init&lt;/span&gt;
        &lt;span class='nv'&gt;classConfig.init = &lt;/span&gt;&lt;span class='o'&gt;-&amp;gt;&lt;/span&gt;
          &lt;span class='nx'&gt;@getApplication&lt;/span&gt;&lt;span class='p'&gt;().&lt;/span&gt;&lt;span class='kc'&gt;on&lt;/span&gt; &lt;span class='nx'&gt;hist_ev_map&lt;/span&gt;
          &lt;span class='nv'&gt;events.scope = &lt;/span&gt;&lt;span class='err'&gt;@&lt;/span&gt;
          &lt;span class='nx'&gt;@getApplication&lt;/span&gt;&lt;span class='p'&gt;().&lt;/span&gt;&lt;span class='kc'&gt;on&lt;/span&gt; &lt;span class='nx'&gt;events&lt;/span&gt;
          &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='nx'&gt;oldInit&lt;/span&gt;
            &lt;span class='nx'&gt;oldInit&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;apply&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='k'&gt;this&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='nx'&gt;arguments&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
          &lt;span class='k'&gt;else&lt;/span&gt;
            &lt;span class='nx'&gt;@callParent&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nx'&gt;arguments&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;

        &lt;span class='k'&gt;delete&lt;/span&gt; &lt;span class='nx'&gt;classConfig&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;config&lt;/span&gt;&lt;span class='p'&gt;[&lt;/span&gt;&lt;span class='s1'&gt;&amp;#39;events&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;]&lt;/span&gt;
      &lt;span class='nx'&gt;classConfig&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Now we just need to use the url hash on startup. In an initialization function we need something like this:&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='coffeescript'&gt;    &lt;span class='nx'&gt;Yap&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;fire&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='nb'&gt;window&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;location&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;hash&lt;/span&gt;&lt;span class='p'&gt;.&lt;/span&gt;&lt;span class='nx'&gt;slice&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='mi'&gt;3&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt; &lt;span class='o'&gt;||&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;default&amp;#39;&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;I created this to ease my development, but I am keeping it in for our production applications. Most users won&amp;#8217;t notice most of the time, but if the refresh their browser or click the back button it should put them close to where they were.&lt;/p&gt;

&lt;h1 id='stay_tuned'&gt;Stay Tuned!&lt;/h1&gt;

&lt;p&gt;In &lt;a href='/javascript/2012/08/11/extjs-templates/'&gt;the next post&lt;/a&gt; in this series I discuss the limitations of this approach of communicating through events.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Forward Authentication</title>
   <link href="http://recursive-design.com/devops/2012/07/23/forward-authentication"/>
   <updated>2012-07-23T00:00:00-07:00</updated>
   <id>http://recursive-design.com/devops/2012/07/23/forward-authentication</id>
   <content type="html">&lt;h1 id='the_magic_of_forwarded_authentication'&gt;The magic of forwarded authentication&lt;/h1&gt;

&lt;p&gt;I have been using ssh for a long time, and on my local system I have passwords on all my RSA keys. I use ssh-agent to not have to type my password multiple times a day.&lt;/p&gt;

&lt;p&gt;In production (AWS) most transfers are between instances and S3 but every now and then we need to transfer information in between instances. This is generally awkward, for security reasons our ssh private keys are not installed in production.&lt;/p&gt;

&lt;p&gt;Enter authentication forwarding. It is enabled by passing the -A switch to open ssh, here is the man page in all it&amp;#8217;s glory.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Enables forwarding of the authentication agent connection. This
can also be specified on a per-host basis in a configuration file.

Agent forwarding should be enabled with caution. Users with the
ability to bypass file permissions on the remote host (for the
agent&amp;#39;s UNIX-domain socket) can access the local agent through the
forwarded connection. An attacker cannot obtain key material from
the agent, however they can perform operations on the keys that
enable them to authenticate using the identities loaded into the
agent.&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id='example'&gt;Example&lt;/h2&gt;

&lt;p&gt;An example will help clarify the use case. Let&amp;#8217;s say you can connect from your dev system to server-1 and server-2. You need to move big files between the two production systems and you could achieve simply by using a command like the following on server-2:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;scp -rC server-1:src dest&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Unfortunately there is no ssh key setup between the two servers. The solution is simple, from your dev system execute:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;ssh -A user@server-2 &amp;#39;scp -rC server-1:src dest&amp;#39;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This will take your key on dev and make it available on server-2 for the duration of that command. Your key does not actually leave your system, rather the authentication related operations are proxied back from server-2 to dev.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Put Your Apron On</title>
   <link href="http://recursive-design.com/devops/2012/07/11/put-your-apron-on"/>
   <updated>2012-07-11T00:00:00-07:00</updated>
   <id>http://recursive-design.com/devops/2012/07/11/put-your-apron-on</id>
   <content type="html">&lt;h1 id='invisible_deployments'&gt;Invisible deployments&lt;/h1&gt;

&lt;p&gt;At yap.TV we are fans of continuous deployments, we want to be able to deploy to production anytime code is ready.&lt;/p&gt;

&lt;h1 id='our_current_setup'&gt;Our current setup&lt;/h1&gt;

&lt;p&gt;We deploy our code on &lt;a href='http://aws.amazon.com/ec2/' title='AWS EC2'&gt;EC2&lt;/a&gt; and use &lt;a href='http://www.opscode.com/chef/' title='Chef'&gt;Chef&lt;/a&gt; in a solo chef configuration.&lt;/p&gt;

&lt;p&gt;At this time we are doing deployments in place with versioning and rollback. We deploy a new versions of our applications on the existing servers. We use various versioning mechanisms depending on the technology (ruby, scala, ejabberd). We have the ability to revert to earlier versions but we had seldom needed to do that over the last years.&lt;/p&gt;

&lt;h2 id='elb_based_deployment'&gt;ELB based deployment&lt;/h2&gt;

&lt;p&gt;For a long time we have used Amazon&amp;#8217;s Elastic Load Balancers (ELB) in front of our API servers. The deployment mechanism involves:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;remove a server from the ELB&lt;/li&gt;

&lt;li&gt;run the chef recipes&lt;/li&gt;

&lt;li&gt;run local tests to make sure that all the services have restarted and reconnected to shared resources in the system&lt;/li&gt;

&lt;li&gt;add back the server in the load balancer&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;We have a script to automate most of the steps however that script is still driven by a human.&lt;/p&gt;

&lt;h2 id='limitations'&gt;Limitations&lt;/h2&gt;

&lt;p&gt;There are a couple of limitations with this approach. First of all the ELBs rudely drop connections as soon as you remove an instance from the load balancer, &lt;a href='https://forums.aws.amazon.com/thread.jspa?threadID=61278' title='(see Eric Hammond&amp;apos;s thread)'&gt;see Eric Hammond&amp;#8217;s thread&lt;/a&gt; . This means that with the approach above you will drop the existing API connections. This is mitigated by the fact that we have smart clients that retry connections, however we would like to eliminate the cases in which we knowingly drop connections.&lt;/p&gt;

&lt;p&gt;Second of all it is hard to continue to automate this approach. Right now we have multiple AWS keys using different privilege levels through &lt;a href='http://aws.amazon.com/iam/' title='IAM'&gt;IAM&lt;/a&gt;. The production servers have read only access to the EC2 information however they do not have write access. We have been very reluctant to expose write access to the management infrastructure.&lt;/p&gt;

&lt;h1 id='enter_apron'&gt;Enter Apron&lt;/h1&gt;

&lt;p&gt;Apron is series of scripts that keep your Chef from getting dirty during the deployment process. It is doing this by routing traffic away from the system being updated without requiring access to the management infrastructure. We present the basic mechanisms here but the exact integration will depend on your specific setup.&lt;/p&gt;

&lt;p&gt;Apron pushes the routing logic to the local system being deployed. Each system has a buddy, this buddy is defined in a configuration file when running chef. Each server routes traffic to its buddy before starting deployment and then accepts traffic when it is done. This uses the built in command iptables. We have this working on Natty and Pangolin in production.&lt;/p&gt;

&lt;p&gt;There are 3 simple scripts that need to be integrated in your deployment process. Before deployment the local server should start to deploy traffic to his buddy using apron-on.sh.&lt;/p&gt;
&lt;script src='https://gist.github.com/3091346.js?file=apron-on.sh'&gt;
&lt;/script&gt;
&lt;p&gt;After the deployment and local testing you want to re-accept traffic using apron-off.sh&lt;/p&gt;
&lt;script src='https://gist.github.com/3091346.js?file=apron-off.sh'&gt;
&lt;/script&gt;
&lt;p&gt;Should things go wrong you can look at things with apron-show.sh&lt;/p&gt;
&lt;script src='https://gist.github.com/3091346.js?file=apron-show.sh'&gt;
&lt;/script&gt;
&lt;h1 id='next_steps'&gt;Next steps&lt;/h1&gt;

&lt;p&gt;We are looking for ways to make the system more robust. The deployment needs to happen sequentially and we may leverage other existing mechanisms to enforce that, for example &lt;a href='http://zookeeper.apache.org/' title='Zookeeper'&gt;Zookeeper&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Additionally we will enhance our monitoring script to detect failures. One option is to expose real IP addresses in the service monitoring phases and report mismatches between the server we connect to and the server actually serving the page.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Javascript Frameworks And Data Binding</title>
   <link href="http://recursive-design.com/javascript/2012/06/11/javascript-frameworks-and-data-binding"/>
   <updated>2012-06-11T00:00:00-07:00</updated>
   <id>http://recursive-design.com/javascript/2012/06/11/javascript-frameworks-and-data-binding</id>
   <content type="html">&lt;h1 id='ui_widgets'&gt;UI Widgets&lt;/h1&gt;

&lt;p&gt;One approach to frameworks is to try to find the one with the best set of UI widgets that fit your needs. UI widgets have powerful abstractions, but at some point we need to extend them, compose them, or create entirely new widgets, so I am looking for a foundational framework that a UI can be built with from the ground up or used to integrate with UI widgets.&lt;/p&gt;

&lt;h2 id='jquery'&gt;jQuery&lt;/h2&gt;

&lt;p&gt;jQuery and other similar libraries largely insulate the programmer from browser inconsitencies and add convenience for DOM and event interaction. It is possible to build a UI with only jQuery, but in my experience this is not a productive option because jQuery apropriately concerns itself with only the lowest level of abstractions. JQuery plugins and UI Widgets tend to be very opaque data containers that are tied to the DOM. It can be difficult to communicate with the data they are holding or otherwise extend them for new use cases. jQuery is not an MVC framework, although you can try to use it in that style.&lt;/p&gt;

&lt;h1 id='mvc_frameworks'&gt;MVC frameworks&lt;/h1&gt;

&lt;p&gt;MVC frameworks crucially separate out the data from the UI. Data is accesible in the models rather than being retrieved directly from the DOM. This is crucial for an interactive UI because the display of data (always a string) is different than the actual data. When data changes we need to interact with the real data, not a display of it. Traditionally we might have interacted with the data by querying the server for even a minor update. However, a much more responsive application can be built if we have access to the data client side and can optimistically make changes in the UI before ever hearing back an OK from the server.&lt;/p&gt;

&lt;h2 id='backbonejs'&gt;Backbone.js&lt;/h2&gt;

&lt;p&gt;The original and very popular javascript MVC framework is &lt;a href='http://backbonejs.org'&gt;Backbone.js&lt;/a&gt;. I have used Backbone.js on a few projects now, and I believe it is definitely better to use Backbone than to not use it. The good part of Backbone is that it structures your data into models and collections separate from (but bound to) the UI with good REST integration. However, in my experience the UI integration is not good enough. There is too much boilerplate from its lack of 2-way data binding. In Backbone you have to wire your templates to re-render when data changes. You also have to retrieve your data back out of your forms to put it in your models/collections. This boilerplate data binding is tedious for the experienced, but also ends up being a stumbling block for less advanced programmers that lets them write bad code.&lt;/p&gt;

&lt;p&gt;Let me explain the point about less advanced programmers. Normally I am of the mindset that you need to focus on hiring better and teaching your team how to code better. However, in a client heavy interactive app we may have UI focused programmers. They may be capable of creating great UIs but do not always create the best engineering quality code. This could be because they are an experienced CSS designers that just recently learned javascript. But it can also be because they care deeply about the end result, and the code that it takes to get there is not as interesting to them. There are probably good UI programmers that would be great to have on your team, but that you could struggle with to guide them to create high quality code (code that is understandable, low defect, and easy to extend in the future). In my opinion, Backbone asks for too many unecessary decisions and boilerplate code from inexperienced programmers that can easily lead to low quality code.&lt;/p&gt;

&lt;h2 id='knockout__knockback'&gt;Knockout / Knockback&lt;/h2&gt;

&lt;p&gt;&lt;a href='http://knockoutjs.com'&gt;Knockout&lt;/a&gt; is one of the original frameworks with good 2-way data binding. Knockout is a bit lacking as a feature complete framework. There is a project called &lt;a href='http://kmalakoff.github.com/knockback/'&gt;Knockback.js&lt;/a&gt; that brings in rich models from Backbone.js. However, while Knockback seems feature complete it is a heavyweight in size and there is still some boilerplate to declare powerful 2-way data bindings.&lt;/p&gt;

&lt;h2 id='more_frameworks_with_2way_data_binding'&gt;more frameworks with 2-way data binding&lt;/h2&gt;

&lt;p&gt;The remaining framework options I know of with 2-way data binding are then &lt;a href='http://angularjs.org'&gt;Angularjs&lt;/a&gt;, &lt;a href='http://emberjs.com'&gt;Ember.js&lt;/a&gt;, &lt;a href='http://batmanjs.org'&gt;Batman.js&lt;/a&gt;, &lt;a href='canjs.us'&gt;CanJS&lt;/a&gt;, and &lt;a href='http://elabs.se/blog/33-why-serenade-js'&gt;Serenade.js&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Another intriguing option is &lt;a href='http://derbyjs.com'&gt;Derby.js&lt;/a&gt; and &lt;a href='http://meteor.com/'&gt;Meteor&lt;/a&gt;, which tries to bring data-binding all the way to the server side. Derby.js is designed to work with a server-side nodejs server, so although it may be possible to integrate with a non-node setup, I will wait for a clear demonstration of that before trying it out. Batman.js does target running on the server side also, but should work on the client side with other backends.&lt;/p&gt;

&lt;h2 id='event_binding'&gt;Event Binding&lt;/h2&gt;

&lt;p&gt;One difference in frameworks is their approach is event binding. CanJS uses CSS selectors for event binding:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;var Todos = can.Control({
    &amp;#39;init&amp;#39; : function(){}
  },
  &amp;#39;li click&amp;#39; : function( li, event ) {
    console.log( &amp;#39;You clicked&amp;#39;, li.text() )
  }
})&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This keeps logic out of the view, which has benefits. However, this means you have to make sure your css selector always matches the view html. For that reason, I prefer other approaches to event handling.&lt;/p&gt;

&lt;h2 id='templating'&gt;Templating&lt;/h2&gt;

&lt;p&gt;One difference between these frameworks is how they do templating. Angularjs, KnockoutJS, and Batman.js templates are valid html. Templating then involves using existing custom tags, setting tag attributes, and some creation of custom tags. I have personally never been a big fan of tag-based templating. However, for client-heavy templates it begins to make some sense. I used to think of templates as generated and read-only. Assign some values to some variable, stick them into your templates, its easy, why try and pretend we are using html? I still think this makes sense when you are writing a stateless webapp. However, when you begin to bind interactivity to templates you quickly run into new issues.&lt;/p&gt;

&lt;p&gt;In Ember.js actions can be bound in the template:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;a href=&amp;quot;#&amp;quot; {action &amp;quot;edit&amp;quot; on=&amp;quot;click&amp;quot;}&amp;gt;Edit&amp;lt;/a&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;An Ember View can also listen for events. The problem for me with Ember style views is that the basics need to abandon html to be concise. For example, Emberjs has its own checkbox function&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;{view Ember.Checkbox checkedBinding=&amp;quot;todo.done&amp;quot;}&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;compared with angularjs (Batman.js and Knockout are similar)&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;input type=&amp;quot;checkbox&amp;quot; ng-model=&amp;quot;todo.done&amp;quot;&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The Emberjs version is not verbose. But the html version is easier to understand, especially for a designer because we only added the binding, we did not use any additional abstractions. I would like an ember-style version:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;input type=&amp;quot;checkbox&amp;quot; {checked=todo.done}&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;However, without knowledge of the tag, Ember-style templates probably need to special case checked to figure out the correct behavior. For server side templating this wouldn not matter: I could do something like this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;input type=&amp;quot;checkbox&amp;quot; {todo.done ? &amp;quot;checked=checked&amp;quot; : &amp;quot;&amp;quot;}&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;There is no updating, so we can just make sure to get it right the first time. But for automatic 2-way data binding this will not work unless we have a construct to recognize which part of the expression is a data binding (todo.done), and which part is just for generating the proper html. So things quickly get more complicated unless we make the choice of abandoning html for functions or having our template language have knowledge about the DOM (a benefit of having templates that are valid HTML).&lt;/p&gt;

&lt;p&gt;Another approach to templating is to use a thin abstraction over html to make writing HTML nicer. As an example, the &lt;a href='http://joosy.ws/'&gt;Joosy framework&lt;/a&gt; defaults to using HAML. As a creator of the &lt;a href='https://github.com/gregwebs/hamlet.rb'&gt;Hamlet templating language&lt;/a&gt;, I don&amp;#8217;t like HAML-inspired syntax. Hamlet gets rid of closing tags and lets you insert values into your HTML. HTML is actually pretty good once you get rid of the closing tags and add a few conveniences. The additional abstractions beyond that makes us learn something new for no reason.&lt;/p&gt;

&lt;p&gt;For my javascript templates, I first create them server-side (&lt;a href='http://www.yesodweb.com'&gt;Yesod&lt;/a&gt; or Rails) with Hamlet. In addition to being a more convenient way to write HTML, it also lets me stick data into them server side if I find it more convenient. On top of that, I can still do client-side templating with something like Mustache, and obviously valid html templates of Angularjs/Knockout/Batman.js work very well. Serenade.js uses a css-selector style abstraction for its template languages, so it isn&amp;#8217;t forcing you to learn anything new if you are used to CSS, just to use css selectors rather than tags.&lt;/p&gt;

&lt;h2 id='2way_databinding_by_example'&gt;2-way Data-binding by example&lt;/h2&gt;

&lt;p&gt;I am truly impressed with the revolutionary hassle-free data binding of Angularjs. You can use plain-old javascript attributes for bound data instead of &lt;code&gt;get&lt;/code&gt; and &lt;code&gt;set&lt;/code&gt;. Their boilerplate-free usage of dependency injection means your code will always be easy to test.&lt;/p&gt;

&lt;p&gt;To see how pain free the AngularJS data binding is, lets look at some examples of computed properties. A computed property is made up of one or more other bound properties.&lt;/p&gt;

&lt;p&gt;We want to have a full name in a view that automatically changes when the first or last name of the person changes:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;span&amp;gt; Person: {person.fullName()}&amp;lt;/span&amp;gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Ember:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Person = Ember.Object.extend({
   firstName: null,
   lastName:  null,
   fullName: function() { return firstName + &amp;#39; &amp;#39; + lastName; 
       return this.get(&amp;#39;firstName&amp;#39;) + &amp;#39; &amp;#39; + this.get(&amp;#39;lastName&amp;#39;);
     }.property(&amp;#39;firstName&amp;#39;, &amp;#39;lastName&amp;#39;); 
});&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Batman (Coffeescript):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;class Person extends Batman.Object
   firstName: null,
   lastName:  null,
   @accessor &amp;#39;fullName&amp;#39;, -&amp;gt;
     @get(&amp;#39;firstName&amp;#39;) + &amp;#39; &amp;#39; + @get(&amp;#39;lastName&amp;#39;); &lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Knockout:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;  function AppViewModel(first, last) {
    this.firstName = ko.observable(first);
    this.lastName = ko.observable(last);
    this.fullName = ko.computed(function() {
      return this.firstName() + &amp;quot; &amp;quot; + this.lastName();
    }, this);
  }&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;AngularJS:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;function Person(first, last) {
  this.first = first;
  this.last = last;
}
Person.prototype.fullName = function() {
  return this.first + &amp;#39; &amp;#39; + this.last;
};&lt;/code&gt;&lt;/pre&gt;

&lt;h1 id='choosing_a_framework'&gt;Choosing a framework&lt;/h1&gt;

&lt;p&gt;The downsides of Angularjs is that it is a heavyweight in size and its REST and collection support is more immature than what I am used to from Backbone.js.&lt;/p&gt;

&lt;p&gt;If you are loooking for a small-sized framework, and you are not using jQuery already, Serenade.js may fit the bill, weighing in at only 9k with no dependencies. We should note that Serenade.js does not target IE6 support.&lt;/p&gt;

&lt;p&gt;If you want to share code with a server side javascript application, Batman.js is designed for that. Knockback.js and Batman.js seem to have good collection/REST support and may be easier options when switching from Backbone.js.&lt;/p&gt;

&lt;p&gt;Please understand that this is a very limited comparison. There are probably other frameworks out there with 2-way data binding. Getting data binding right or taking a particular approach to templating doesn&amp;#8217;t mean a lot unless there is good documentation on many other well-implemented features and capabilities. I think I have enough experience to know there must be something better than Backbone, but I have little practical experience with the alternatives. One nice way to compare frameworks is the &lt;a href='https://github.com/addyosmani/todomvc'&gt;TodoMVC project&lt;/a&gt;.&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Elegant Xml Parsing</title>
   <link href="http://recursive-design.com/ruby/2012/06/08/elegant-xml-parsing"/>
   <updated>2012-06-08T00:00:00-07:00</updated>
   <id>http://recursive-design.com/ruby/2012/06/08/elegant-xml-parsing</id>
   <content type="html">&lt;h1 id='elegant_xml_parsing_in_ruby'&gt;Elegant XML Parsing in Ruby&lt;/h1&gt;

&lt;p&gt;I &lt;a href='http://blog.gregweber.info/posts/2011-06-03-high-performance-rb-part1'&gt;blogged in more detail&lt;/a&gt; about this before. But I saw a &lt;a href='
http://stackoverflow.com/questions/9199859/parsing-large-file-with-saxmachine-seems-to-be-loading-the-whole-file-into-memor/10818578#10818578
'&gt;Stack Overflow question&lt;/a&gt; about this, so I feel I need to keep up the public service announcements :)&lt;/p&gt;

&lt;p&gt;If you are parsing big XML files you have to stream them using something like SAX. Does your code look like this?&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;    &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;start_element&lt;/span&gt; &lt;span class='n'&gt;tag&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='n'&gt;attributes&lt;/span&gt;
      &lt;span class='k'&gt;case&lt;/span&gt; &lt;span class='n'&gt;tag&lt;/span&gt;
      &lt;span class='k'&gt;when&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;name&amp;#39;&lt;/span&gt;
        &lt;span class='vi'&gt;@attribute&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;name&amp;#39;&lt;/span&gt;
      &lt;span class='k'&gt;when&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;titles&amp;#39;&lt;/span&gt;
        &lt;span class='vi'&gt;@attribute&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;name&amp;#39;&lt;/span&gt;
      &lt;span class='k'&gt;end&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;

    &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;end_element&lt;/span&gt; &lt;span class='n'&gt;tag&lt;/span&gt;
      &lt;span class='vi'&gt;@model&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;save!&lt;/span&gt; &lt;span class='k'&gt;if&lt;/span&gt; &lt;span class='n'&gt;tag&lt;/span&gt; &lt;span class='o'&gt;==&lt;/span&gt; &lt;span class='s1'&gt;&amp;#39;name&amp;#39;&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;

    &lt;span class='k'&gt;def&lt;/span&gt; &lt;span class='nf'&gt;characters&lt;/span&gt; &lt;span class='n'&gt;text&lt;/span&gt;
      &lt;span class='vi'&gt;@model&lt;/span&gt;&lt;span class='o'&gt;[&lt;/span&gt;&lt;span class='vi'&gt;@attribute&lt;/span&gt;&lt;span class='o'&gt;]&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='n'&gt;text&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;Please stop doing this!&lt;/p&gt;

&lt;p&gt;Sax Machine was created to have an elegant API for parsing XML.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;    &lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;AtomEntry&lt;/span&gt;
      &lt;span class='kp'&gt;include&lt;/span&gt; &lt;span class='no'&gt;SAXMachine&lt;/span&gt;
      &lt;span class='n'&gt;element&lt;/span&gt; &lt;span class='ss'&gt;:title&lt;/span&gt;
      &lt;span class='c1'&gt;# the :as argument makes this available through atom_entry.author instead of .name&lt;/span&gt;
      &lt;span class='n'&gt;element&lt;/span&gt; &lt;span class='ss'&gt;:name&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:as&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='ss'&gt;:author&lt;/span&gt;
      &lt;span class='n'&gt;element&lt;/span&gt; &lt;span class='s2'&gt;&amp;quot;feedburner:origLink&amp;quot;&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:as&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='ss'&gt;:url&lt;/span&gt;
      &lt;span class='n'&gt;element&lt;/span&gt; &lt;span class='ss'&gt;:summary&lt;/span&gt;
      &lt;span class='n'&gt;element&lt;/span&gt; &lt;span class='ss'&gt;:content&lt;/span&gt;
      &lt;span class='n'&gt;element&lt;/span&gt; &lt;span class='ss'&gt;:published&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;This is declarative coding, which is what we should be striving for no matter what programming tools we are using. The problem is that the official sax-machine gem loads everything into memory. The reason why is that it does not use a callback (yield) or fibers to process elements when they are immediately loaded.&lt;/p&gt;

&lt;p&gt;At yap.TV, we have been using &lt;a href='https://github.com/gregwebs/sax-machine'&gt;my fork of sax-machine&lt;/a&gt; for over a year now on gigantic XML files. This fork uses Ruby&amp;#8217;s fibers to transfer control from the xml parsing back to your code. This is similar in concept to how yield works, but you don&amp;#8217;t have to pass in a block right away. Instead you get back an Enumerator that will end up parsing on demand.&lt;/p&gt;
&lt;div class='highlight'&gt;&lt;pre&gt;&lt;code class='ruby'&gt;    &lt;span class='k'&gt;class&lt;/span&gt; &lt;span class='nc'&gt;Atom&lt;/span&gt;
      &lt;span class='kp'&gt;include&lt;/span&gt; &lt;span class='no'&gt;SAXMachine&lt;/span&gt;
      &lt;span class='n'&gt;element&lt;/span&gt; &lt;span class='ss'&gt;:title&lt;/span&gt;
      &lt;span class='n'&gt;elements&lt;/span&gt; &lt;span class='ss'&gt;:entry&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:lazy&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='kp'&gt;true&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:as&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='ss'&gt;:entries&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:class&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='no'&gt;AtomEntry&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;

    &lt;span class='n'&gt;feed&lt;/span&gt; &lt;span class='o'&gt;=&lt;/span&gt; &lt;span class='no'&gt;Atom&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;parse&lt;/span&gt;&lt;span class='p'&gt;(&lt;/span&gt;&lt;span class='n'&gt;xml_file_handle&lt;/span&gt;&lt;span class='p'&gt;,&lt;/span&gt; &lt;span class='ss'&gt;:lazy&lt;/span&gt; &lt;span class='o'&gt;=&amp;gt;&lt;/span&gt; &lt;span class='kp'&gt;true&lt;/span&gt;&lt;span class='p'&gt;)&lt;/span&gt;
    &lt;span class='n'&gt;feed&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;entries&lt;/span&gt; &lt;span class='c1'&gt;# =&amp;gt; #&amp;lt;Enumerator: #&amp;lt;Enumerator::Generator:0x00000004c41ea0&amp;gt;:each&amp;gt; &lt;/span&gt;
    &lt;span class='n'&gt;feed&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;entries&lt;/span&gt;&lt;span class='o'&gt;.&lt;/span&gt;&lt;span class='n'&gt;each&lt;/span&gt; &lt;span class='k'&gt;do&lt;/span&gt; &lt;span class='o'&gt;|&lt;/span&gt;&lt;span class='n'&gt;entry&lt;/span&gt;&lt;span class='o'&gt;|&lt;/span&gt;
      &lt;span class='c1'&gt;# every time the block is called the next entry is parsed- no memory blow up! &lt;/span&gt;
      &lt;span class='c1'&gt;# This is probably where you save the entry to a database&lt;/span&gt;
    &lt;span class='k'&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;/div&gt;
&lt;p&gt;The only thing extra you need to do is add a :lazy attribute to your top level elements. Also checkout &lt;a href='https://github.com/gregwebs/sax-machine'&gt;ezkl&amp;#8217;s fork&lt;/a&gt;. He is taking over maintenance of sax-machine in the official repo now though and planning on pulling in my changes.&lt;/p&gt;

&lt;p&gt;This solves the memory part of performance. However, if this is not fast enough for you, I suggest switching the library to use &lt;a href='https://github.com/ohler55/ox'&gt;ox&lt;/a&gt;. From the ox documentation:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Unlike Nokogiri and LibXML, Ox can be tuned to use only the SAX callbacks that are of interest to the caller&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The current Sax parser will pull everything out of the XML and bring it into Ruby land. Avoiding this could make the parsing an order of magnitude faster depending on how sparsely you are using the XML.&lt;/p&gt;

&lt;p&gt;For our usage at yap (importing to a database) we of course found that database access became a big bottleneck. We added some indexes and caching, and made some queries use the raw driver rather than go through an ORM.&lt;/p&gt;

&lt;p&gt;sax-machine is a great example of how Ruby&amp;#8217;s advanced features of fibers and meta-programming can be used. Please use it to write declarative code!&lt;/p&gt;</content>
 </entry>
 
 <entry>
   <title>Scala On Rails</title>
   <link href="http://recursive-design.com/scala/2012/06/07/scala-on-rails"/>
   <updated>2012-06-07T00:00:00-07:00</updated>
   <id>http://recursive-design.com/scala/2012/06/07/scala-on-rails</id>
   <content type="html">&lt;p&gt;Now that we have our blog going we wanted to collect information on what we have been doing. This post originally published on &lt;a href='http://www.blog.project13.pl/index.php/fun/1497/teaching-jruby-talk-with-scala-on-rails/'&gt;Konrad&amp;#8217;s blog&lt;/a&gt;&lt;/p&gt;

&lt;h1 id='scala_on_rails'&gt;Scala on Rails&lt;/h1&gt;

&lt;h2 id='the_jvm_is_awesome'&gt;The JVM is awesome.&lt;/h2&gt;

&lt;p&gt;But back to the topic of this post: We’ll see how you can leverage both Scala and JRuby in one project. Each will doing what it does best:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Ruby will handle the FAST frontend development as one of Ruby’s strong points is obviously Rails which made it so popular. Though there are people implementing APIs in ruby, if you need pure performance, you may need some other lang (vide airbreak, twitter…).&lt;/li&gt;

&lt;li&gt;Scala will be doing all the heavy lifting including some of our existing code which interacts with zookeeper or uses Akka actors to crunch some numbers.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Another great point here is the reuse of our existing scala codebase which has some nice libraries we’ve implemented during our day-to-day. Anyway, let’s see some code!&lt;/p&gt;

&lt;p&gt;Start out with a plain Rails 3.2 project You know the drill. rvm, ruby, rails new. The only difference here is that we’ll use JRuby right from the start here, so:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# get JRuby and start a new rails app
rvm install jruby &amp;amp;&amp;amp; rvm use jruby
 
gem install rails
rails new scala-on-rails&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id='jrubify_it'&gt;JRubify it!&lt;/h2&gt;

&lt;p&gt;Next we’ll add some more dependencies to our Gemfile:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# jruby dependencies in Gemfile
gem &amp;#39;jruby-openssl&amp;#39; # simply required
gem &amp;#39;jruby-scala&amp;#39; # a jruby scala bridge
gem &amp;#39;warbler&amp;#39; # to create a war file that we&amp;#39;ll deploy layer&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Most important here is the jruby-scala gem, which acts as a bridge to allow the use of scala constructs in ruby, more naturally. For a longre read on this check out Daniel Spiewak’s blogposts about it.&lt;/p&gt;

&lt;p&gt;Now do the usual bundle install (be sure that you’re running jruby (!)). If you don’t want to rvm use jruby, you could also run bundler like this: &lt;code&gt;jruby -S bundle install&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;One thing I’m not covering in this blogpost is how to throw out ActiveRecord from rails. But that’s easily googlable: Just don’t require it, as shown here: Rails 3 without ActiveRecord. Of course you CAN use active record with JRuby etc, but in my project we won’t need it, so I’m removing it.&lt;/p&gt;

&lt;h2 id='scalify_it'&gt;Scalify it!&lt;/h2&gt;

&lt;p&gt;Ok, now that we have all the gems we need let’s proceed with putting scala into our lib/ directory. We’ll need it at runtime obviously… :-)&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# copy scala into your rails /lib directory
cd lib/
cp $SCALA_HOME/lib/scala-library.jar .&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;One way to include jar dependencies into your project is by simply pasting them into the lib/ directory, so if you need some cool-java-library.jar, just drop it in there! It’ll also be automatically packaged with the app into the warfile by warbler – yay!&lt;/p&gt;

&lt;h2 id='require_java'&gt;Require ‘java’!&lt;/h2&gt;

&lt;p&gt;Kk, now on to some code, let’s assume I have a nice “number formatter” I’d like to use in my rails app, that I’ve already implemented in some “commons” library in Scala. (Obviously that’s not the only thing from scala we’re using in our app but it’s just an example class ;-)). Here’s how we’d write our controller:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# app/controllers/AnyController.rb
require &amp;#39;java&amp;#39;
require &amp;#39;scala-library.jar&amp;#39;
require &amp;#39;scala-cool-formatting.jar&amp;#39;

# here&amp;#39;s how to obtain a nice name for something in the Java namespace
PrettyOrdinalNumber = Java::pl.project13.common.format.PrettyOrdinalNumber

class AnyController &amp;lt; ApplicationController
 
  def index
    n = 12
    nth = PrettyOrdinalNumber.new(n) # the constructor in Scala actually takes a Long – but no worries about types, JRuby can handle it
 
    @whoa_from_scala = &amp;quot;the number #{n} is the #{nth.ordinal} natural number!&amp;quot;
  end
end&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;By the way, PrettyOrdinalNumber is a trait in scala. There we use it via implicit conversions to nicely print numbers when counting servers etc ;-) A small thing but nice to have.&lt;/p&gt;

&lt;p&gt;The view here is boring – we just print this one variable; So I won’t even put a code block here for it ;-)&lt;/p&gt;

&lt;h2 id='run_it'&gt;Run it!&lt;/h2&gt;

&lt;p&gt;We still have not launched the app… Does it work at all? It does – but let’s check. The nice thing here is… You can still simply run the app via the good ol’…&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# rails s works as you&amp;#39;d expect it to
rails s&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;command. (Just be sure you&amp;#8217;re running JRuby.) Tests and everything just works as you&amp;#8217;d expect it to - no worries here. One thing worth mentioning here is that currently assets pipeline may not be working with JRuby (or maybe it does but I didn&amp;#8217;t care so I just generate assets before I build the war file). So you&amp;#8217;ll want to disable it in production like this (in config/enrivoments/production.rb):&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# Precompile assets to be included in the WAR file
config.assets.compile = true&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Then in order to pre-generate assets (compile scss -&amp;gt; css, et cetera) you can run:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# precompile assets like this
RAILS_ENV=production bundle exec rake assets:precompile&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Which will generate all assets and throw them into public/assets/. Oh and don&amp;#8217;t panic if this takes a long time - yup, sometimes it does.&lt;/p&gt;

&lt;h2 id='ship_it'&gt;Ship it!&lt;/h2&gt;

&lt;p&gt;Now that we&amp;#8217;ve got our app running let&amp;#8217;s see how we can make a war from it&amp;#8230; We&amp;#8217;ll be using the (awesome) warbler gem here. So if you don&amp;#8217;t want to tweak anything, you just run:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# let&amp;#39;s create a WAR
bundle exec warbler&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;and it&amp;#8217;ll create a war containing all your libraries from lib/ and obviously the entire rails app. (Warbler is &amp;#8220;smart&amp;#8221; and can detect if your project is a rails app etc). If you need more control over what warbler is including (and where) in your warfile you can run:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# for PROs who want to configure warbler
warble config&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Which will create a warble.rb file in conf/. I&amp;#8217;ll leave it up to you if you need more tweaking or not (you could exclude temp/ and other directories from the warfile for example).&lt;/p&gt;

&lt;p&gt;So&amp;#8230; We&amp;#8217;ve got our shiny war file. How can we run it? I&amp;#8217;ll show you two ways of dealing with this, first: on Glassfish 3 (a applicationserver) and on Jetty (a small and fast servlet container).&lt;/p&gt;

&lt;p&gt;So, with glassfish installed you could just:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# deploy a jruby war file to glassfish
asadmin start-domain domain1
asadmin deploy scala-on-rails.jar
chromium-browser http://localhost:8080/scala-on-rails&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;You may want to set it&amp;#8217;s context path to / instead of /scala-on-rails but as you can see, it started and you&amp;#8217;re running JRuby&amp;#8230; accessing Scala code, on a normal JEE server!&lt;/p&gt;

&lt;p&gt;If you prefer a smaller server, which ain&amp;#8217;t so easy to administer remotely (asadmin rocks) but is a bit smaller etc, you should check out Jetty. There is a gem that claims to run apps on jetty &amp;#8220;just so&amp;#8221;, but it didn&amp;#8217;t work out for me. And all in all&amp;#8230; Deploying to jetty is also just 1 line of code, so why would a need a gem for that? ;-) Here&amp;#8217;s how to deploy your war to jetty:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;# It&amp;#39;s that easy to deploy an app to jetty (using jetty-runner)
curl http://repo2.maven.org/maven2/org/mortbay/jetty/jetty-runner/7.6.0.RC5/jetty-runner-7.6.0.RC5.jar &amp;amp;gt; jetty-runner.jar
java -jar jetty-runner.jar scala-on-rails.war&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&amp;#8230;and that&amp;#8217;s it! Look for the app on http://localhost:8080/&lt;/p&gt;

&lt;h2 id='ruby__scala__java__jvm__best_friends'&gt;Ruby ♥ Scala ♥ Java ♥ JVM =&amp;gt; Best friends&lt;/h2&gt;

&lt;p&gt;That&amp;#8217;s it - we&amp;#8217;ve deployed our first app using JRuby and Scala libraries. Such setup is doing pretty well for us and we can gain from scala/java power inside our quickly developed rails app.&lt;/p&gt;

&lt;p&gt;The only tradeoff we made here is the fact that some gems require native extensions, which won&amp;#8217;t work with JRuby. But we gained a hell lot of powerful libraries (lessening code duplication among projects in the process too!) and &amp;#8220;1 file deployments&amp;#8221;, which are really a lot nicer than deploying rails apps (that&amp;#8217;s a personal opinion there, don&amp;#8217;t kill me ;-)).&lt;/p&gt;

&lt;p&gt;That&amp;#8217;s it folks. All hail to the JVM and keep on hakking!&lt;/p&gt;</content>
 </entry>
 
 
</feed>
