<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss 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/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>SproutCore</title>
	
	<link>http://blog.sproutcore.com</link>
	<description />
	<lastBuildDate>Mon, 12 Dec 2011 16:08:36 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/Sproutcore-BlogPosts" /><feedburner:info uri="sproutcore-blogposts" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Welcome to Maurits Lamers and Mitch Oliver</title>
		<link>http://feedproxy.google.com/~r/Sproutcore-BlogPosts/~3/5EwHsfF375Q/</link>
		<comments>http://blog.sproutcore.com/welcome-to-maurits-lamers-and-mitch-oliver/#comments</comments>
		<pubDate>Mon, 12 Dec 2011 16:08:36 +0000</pubDate>
		<dc:creator>Tyler Keating</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.sproutcore.com/?p=1928</guid>
		<description><![CDATA[Hot on the heels of last week&#8217;s introduction of five new team members, I&#8217;m pleased to announce that Maurits Lamers and Mitch Oliver have also signed on as SproutCore Committers. As with the people from my previous post, these names should be of no surprise to anyone who has been with SproutCore for some time. [...]]]></description>
			<content:encoded><![CDATA[<p>Hot on the heels of last week&#8217;s introduction of five new team members, I&#8217;m pleased to announce that <strong>Maurits Lamers</strong> and <strong>Mitch Oliver</strong> have also signed on as SproutCore Committers.  As with the people from my previous post, these names should be of no surprise to anyone who has been with SproutCore for some time.</p>
<p>For those that aren&#8217;t sure of the difference between Committers and Reviewers, Committers are actually required to work in their own branches in the repo and submit every change as a pull request to be accepted by a Reviewer.  The Reviewers are allowed to make direct fixes, but will most likely submit anything at all substantial as a pull request too in order to get another Reviewer&#8217;s feedback and acceptance.  Both roles also include the responsibility to try to move the outstanding issues and pull requests towards a resolution.</p>
<p>As you can tell from the above description, both roles are a lot of work and it takes people with a real dedication to the project to accept what can be a thankless and demanding task, so please take a moment to catch all of these people on #sproutcore and sproutcore@googlegroups.com and show them your support.</p>
<img src="http://feeds.feedburner.com/~r/Sproutcore-BlogPosts/~4/5EwHsfF375Q" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.sproutcore.com/welcome-to-maurits-lamers-and-mitch-oliver/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://blog.sproutcore.com/welcome-to-maurits-lamers-and-mitch-oliver/</feedburner:origLink></item>
		<item>
		<title>Welcome to SproutCore’s newest Committers and Reviewer</title>
		<link>http://feedproxy.google.com/~r/Sproutcore-BlogPosts/~3/bpiu7_srLs8/</link>
		<comments>http://blog.sproutcore.com/welcome-to-sproutcore%e2%80%99s-newest-committers-and-reviewer/#comments</comments>
		<pubDate>Fri, 09 Dec 2011 04:17:40 +0000</pubDate>
		<dc:creator>Tyler Keating</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.sproutcore.com/?p=1922</guid>
		<description><![CDATA[As noted in the previous post, we are in the beginning of a major new thrust in SproutCore development and community involvement. As part of this work, we’ve created a guideline to becoming a contributor and list of contributors. Today, I’m pleased to announce that several people have already graciously accepted the offer to take [...]]]></description>
			<content:encoded><![CDATA[<p>As noted in the previous post, we are in the beginning of a major new thrust in SproutCore development and community involvement.  As part of this work, we’ve created a <a href="https://github.com/sproutcore/sproutcore/wiki/Collaborator-Guidelines" title="guideline to becoming a contributor">guideline to becoming a contributor</a> and <a href="https://github.com/sproutcore/sproutcore/wiki/List-of-Collaborators">list of contributors</a>.  </p>
<p>Today, I’m pleased to announce that several people have already graciously accepted the offer to take on roles and contribute even more towards shaping the future of SproutCore as the best application development framework, period.</p>
<p>Please join me in welcoming:</p>
<p> <strong>Jason Dooley</strong>,<br />
 <strong>Jeff Pittman</strong>,<br />
 <strong>Tim Evans</strong>, and<br />
 <strong>Wesley Workman</strong> </p>
<p>as the first <em>SproutCore Committers</em> and </p>
<p><strong>Geoffrey Donaldson</strong></p>
<p>as a new <em>SproutCore Reviewer</em>.  </p>
<p>Undoubtedly, you will have come across these individuals on IRC and the mailing lists and will recognize them for their commitment to SproutCore and to the community.  We are very excited and lucky to have them onboard.</p>
<p>In the future I expect to write many more posts like this, so to those that wish to be included, keep contributing, keep learning and we hope to hear from you soon.</p>
<img src="http://feeds.feedburner.com/~r/Sproutcore-BlogPosts/~4/bpiu7_srLs8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.sproutcore.com/welcome-to-sproutcore%e2%80%99s-newest-committers-and-reviewer/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.sproutcore.com/welcome-to-sproutcore%e2%80%99s-newest-committers-and-reviewer/</feedburner:origLink></item>
		<item>
		<title>Changes to SproutCore</title>
		<link>http://feedproxy.google.com/~r/Sproutcore-BlogPosts/~3/jlb8OKQHCE8/</link>
		<comments>http://blog.sproutcore.com/changes-to-sproutcore/#comments</comments>
		<pubDate>Wed, 07 Dec 2011 20:00:06 +0000</pubDate>
		<dc:creator>Charles Jolley</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.sproutcore.com/?p=1914</guid>
		<description><![CDATA[Today I am writing to announce three important changes to the SproutCore project to better accomodate the community who are using it. Change 1: SproutCore 2.0 Is Now Amber SproutCore 2.0 started out as a rebuild of SproutCore around a more modular and modern design. Since then, the project has evolved in a different direction [...]]]></description>
			<content:encoded><![CDATA[<p>Today I am writing to announce three important changes to the SproutCore project to better accomodate the community who are using it.</p>
<h2>Change 1: SproutCore 2.0 Is Now Amber</h2>
<p>SproutCore 2.0 started out as a rebuild of SproutCore around a more modular and modern design. Since then, the project has evolved in a different direction that means it will never be a complete replacement for SproutCore 1.x.</p>
<p>Therefore, we have decided to rename SproutCore 2.0 and manage it as a separate project. The new project will take on the original code name &#8211; Amber. It will be run by Yehuda Katz, Tom Dale, and Peter Wagenet.</p>
<p>The Amber guys are working on a new website and complete update for the new project. When they are ready we will post a link to the blog here so you can find out more about it. In the meantime, work on this project is continuing in the <a title="SproutCore 2.0 Repository" href="github.com/sproutcore/sproutcore20" target="_blank">sproutcore20</a> repository on Github.</p>
<h2>Change 2: New Contributor Process</h2>
<p>With the Amber change, SproutCore will now once again be the sole domain of those wanting to create fast, native style applications on the web based on the SproutCore 1.x code base.</p>
<p>There is a very active community of developers who have invested heavily in this area. But, due to the structure of our governance system (via a Core Team), we haven&#8217;t done a very good job at making it easy for members of the community to get actively involved.</p>
<p>As of today we are adopting a new contributor process that will change all of this. The new process is based on the Reviewer/Committer model used by WebKit and several other big projects. It is <a href="https://github.com/sproutcore/sproutcore/wiki/Collaborator-Guidelines" target="_blank">fully documented</a> on the SproutCore wiki, but here are the highlights:</p>
<ul>
<li>All SproutCore projects will have reviewers and committers. Reviewers have the authority to approve changes to the code, committers can commit code when it is approved by a reviewer.</li>
<li>Anyone can become a committer once they have had a few patches accepted and a reviewer is willing to sponsor them. Anyone can become a reviewer once they have experience as a committer and the majority of other reviewers votes to approve them.</li>
<li>There is no longer a &#8220;Core Team&#8221;. Instead, we expect reviewers and committers to agree as a group on directional changes to the project. All discussions will be held on the sproutcore-dev mailing list or in IRC. We will avoid private mailing lists.</li>
</ul>
<p>The goal is to make it possible for anyone who is willing to put in the time and effort to contribute to SproutCore to become a leader in the community. You don&#8217;t need a secret handshake to get in &#8211; just contribute.</p>
<p>To get this process started, we have identified a group of people &#8211; both former Core Team members and others &#8211; who qualify as either Committers or Reviewers and reached out to them. You can <a href="https://github.com/sproutcore/sproutcore/wiki/List-of-Collaborators" target="_blank">see the list</a> of those who have already accepted on the wiki. If you aren&#8217;t on the list and you want to be, please email Tyler Keating and he will help you out.</p>
<h2>Change 3: New Leadership</h2>
<p>Finally, I want to talk a bit about my own role in SproutCore. Over the last year, my job has evolved to include a lot less coding and more other activities. While I am still very passionate about seeing SproutCore grow, I am not able to provide the kind of detailed attention that the project needs on a day-to-day level.</p>
<p>Part of the solution to this is to move towards the community driven contributor process above so that no one person can be a bottleneck anymore. We also need someone who has shown dedication to the community to help lead the process.</p>
<p>Tyler Keating is an independent developer who has been contributing to SproutCore for the last four years. He has shown dedication to the project and a desire to get others involved that is just what SproutCore needs.</p>
<p>Therefore, Tyler has agreed to become the new administrator for SproutCore. He is the main guy you should now contact with questions about managing the project day to day. I am going to remain as an honorary project owner so I can chime in on directional things.  In general though, I hope SproutCore can become more community directed than it has been in the past.  Tyler is here to help facilitate that.</p>
<p>Open source is only as strong as the community around it. I have been proud to get to work with some of the best technical talent on the planet through SproutCore. Thank you everyone for your contributions over the last several years.</p>
<p>SproutCore exists to serve your needs. Get involved and make it your own!</p>
<p>PS. I am posting a similar version of this post to the <a href="https://groups.google.com/group/sproutcore" target="_blank">SproutCore mailing list</a> where we can discuss this in the open.  Please feel free to join in there.</p>
<p>&nbsp;</p>
<img src="http://feeds.feedburner.com/~r/Sproutcore-BlogPosts/~4/jlb8OKQHCE8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.sproutcore.com/changes-to-sproutcore/feed/</wfw:commentRss>
		<slash:comments>19</slash:comments>
		<feedburner:origLink>http://blog.sproutcore.com/changes-to-sproutcore/</feedburner:origLink></item>
		<item>
		<title>Why Handlebars?</title>
		<link>http://feedproxy.google.com/~r/Sproutcore-BlogPosts/~3/-mueOyIDry8/</link>
		<comments>http://blog.sproutcore.com/why-handlebars/#comments</comments>
		<pubDate>Mon, 03 Oct 2011 06:20:35 +0000</pubDate>
		<dc:creator>Tom Dale</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Handlebars]]></category>

		<guid isPermaLink="false">http://blog.sproutcore.com/?p=1872</guid>
		<description><![CDATA[When people check out SproutCore 2.0 for the first time, one question that they frequently ask is: Do I have to use Handlebars? Handlebars, if you&#8217;re not familiar with it, is a semantic templating language written entirely in JavaScript. It&#8217;s an expressive language with a tag syntax reminiscent of HTML, except expressions (oftentimes referred to [...]]]></description>
			<content:encoded><![CDATA[<p>When people check out SproutCore 2.0 for the first time, one question that they frequently ask is: Do I have to use Handlebars?</p>
<p><a href="http://www.handlebarsjs.com/">Handlebars</a>, if you&#8217;re not familiar with it, is a semantic templating language written entirely in JavaScript. It&#8217;s an expressive language with a tag syntax reminiscent of HTML, except expressions (oftentimes referred to as &#8220;mustaches&#8221;) are wrapped in double-curly braces. A simple template might look like this:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">&lt;div class=&quot;entry&quot;&gt;
  &lt;h1&gt;{{title}}&lt;/h1&gt;
  &lt;div class=&quot;body&quot;&gt;
    {{body}}
  &lt;/div&gt;
&lt;/div&gt;</pre></div></div>

<p>Handlebars, unlike other templating solutions like Eco, doesn&#8217;t tempt you to embed domain logic in your HTML. Anything other than simple conditionals and loops must be contained in your application&#8217;s JavaScript, which enforces the separation of concerns and leads to better testability. The language is also extensible with custom helpers, which allows you to effectively write a template DSL for your particular application.</p>
<p>So, while the answer to the question is<em> use whatever templating system you&#8217;d like,</em> we think Handlebars is a great option. Perhaps most importantly, we&#8217;ve spent a lot of time deeply integrating SproutCore and Handlebars, such that you get a lot for free just by using bindings, computed properties, and the SproutCore object system. In fact, while we like the features and simple-yet-expressive syntax of Handlebars, the real reason we chose it when creating SproutCore 2.0 was because of its speed and architecture, allowing us the kind of integration that would be very difficult with other templating libraries.<br />
<span id="more-1872"></span><br />
Handlebars compiles a given template only once. After that, it generates a JavaScript function that can be executed repeatedly without the expense of re-parsing the template. For example, a template like this:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">{{#if arrived}}
	Hello,
{{else}}
	Goodbye,
{{/if}}
{{name}}!</pre></div></div>

<p>might be translated into a function like this:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;"><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #003366; font-weight: bold;">var</span> arrived <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">arrived</span><span style="color: #339933;">,</span>
      <span style="color: #000066;">name</span> <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #000066;">name</span><span style="color: #339933;">,</span>
      result <span style="color: #339933;">=</span> <span style="color: #3366CC;">''</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>arrived<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    result <span style="color: #339933;">+=</span> <span style="color: #3366CC;">&quot;Hello, &quot;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span> <span style="color: #000066; font-weight: bold;">else</span> <span style="color: #009900;">&#123;</span>
    result <span style="color: #339933;">+=</span> <span style="color: #3366CC;">&quot;Goodbye, &quot;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  result <span style="color: #339933;">+=</span> <span style="color: #000066;">name</span><span style="color: #339933;">+</span><span style="color: #3366CC;">&quot;!&quot;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #000066; font-weight: bold;">return</span> result<span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>(Please note that the generated code looks different; this is just illustrative of the effect.)</p>
<p>Because you declare your intent, Handlebars knows how to generate the JavaScript that gets executed at runtime. If your templates don&#8217;t change, you can precompile the templates into JavaScript during the build process for additional speed and file size improvements. It also means that, as Handlebars is optimized, so is your application.</p>
<p>But most importantly, because of its declarative nature, we can make your templates bindings-aware. Here&#8217;s where the real advantage appears: <b>you never have to write code that updates the DOM.</b> Most other frameworks require you to have two separate code paths: one that creates the initial representation (often via a templating solution), and one to update it, usually with something like:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">$<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'#welcome'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">text</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">&quot;Goodbye, &quot;</span><span style="color: #339933;">+</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #000066;">name</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>With SproutCore and Handlebars, both behaviors are contained in the same template.</p>
<p>But beyond simple values, we also support things like conditionals and loops. If you use the <code>{{#each}}</code> helper to print an array, for example, the DOM will update <em>automatically</em> whenever items are added, removed, or modified. This eliminates lots of boilerplate and common bugs from your application, and it means you don&#8217;t need to anticipate all of the places data may change and manually re-render. Just modify the array (or the contents of the array) and let Handlebars take care of the rest.</p>
<p>So, while we encourage you to use whatever templating system makes most sense to you, we think that using the built-in Handlebars integration will let you write less code&mdash;and have fewer bugs&mdash;by eliminating the tedious boilerplate that you&#8217;re used to writing.</p>
<p>You can expect many improvements to these auto-updating templates as time goes on. In particular, we are focused on ensuring they work flawlessly with elements, such as <code>&lt;tr&gt;</code>, that have strict requirements about their enclosing tag. Yehuda and I have been working on <a href="https://github.com/tomhuda/metamorph.js">metamorph.js</a>, which we are in the process of integrating into SproutCore 2.0, that will both improve compatibility with these kinds of elements, as well as offer performance improvements. Look for these commits to SproutCore soon!</p>
<img src="http://feeds.feedburner.com/~r/Sproutcore-BlogPosts/~4/-mueOyIDry8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.sproutcore.com/why-handlebars/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		<feedburner:origLink>http://blog.sproutcore.com/why-handlebars/</feedburner:origLink></item>
		<item>
		<title>SproutCore 2 and AJAX</title>
		<link>http://feedproxy.google.com/~r/Sproutcore-BlogPosts/~3/KRTqPM3bp7I/</link>
		<comments>http://blog.sproutcore.com/sproutcore-2-and-ajax/#comments</comments>
		<pubDate>Thu, 22 Sep 2011 17:53:04 +0000</pubDate>
		<dc:creator>Peter Wagenet</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://blog.sproutcore.com/?p=1856</guid>
		<description><![CDATA[A question we hear often about SproutCore 2 is &#8220;how do I connect to a server?&#8221; The answer to this question is actually easier than you might expect. Since SC2 is dependent on jQuery, we already have access to all the standard jQuery methods, including the AJAX ones. In this post, I&#8217;ll explain to you how [...]]]></description>
			<content:encoded><![CDATA[<p>A question we hear often about SproutCore 2 is &#8220;how do I connect to a server?&#8221; The answer to this question is actually easier than you might expect. Since SC2 is dependent on jQuery, we already have access to all the standard jQuery methods, including the AJAX ones. In this post, I&#8217;ll explain to you how to use AJAX in SC2 to communicate with your server.</p>
<p>In this example, I&#8217;ll assume a standard REST backend. To make things easier on you, I&#8217;ve made up a basic one in Rails. You can grab it with:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">git</span> clone <span style="color: #c20cb9; font-weight: bold;">git</span>:<span style="color: #000000; font-weight: bold;">//</span>github.com<span style="color: #000000; font-weight: bold;">/</span>sproutcore<span style="color: #000000; font-weight: bold;">/</span>todos-server.git <span style="color: #660033;">--recursive</span></pre></div></div>

<p>If you just want to grab the completed SC code you can run:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #c20cb9; font-weight: bold;">git</span> clone <span style="color: #c20cb9; font-weight: bold;">git</span>:<span style="color: #000000; font-weight: bold;">//</span>github.com<span style="color: #000000; font-weight: bold;">/</span>sproutcore<span style="color: #000000; font-weight: bold;">/</span>todos.git <span style="color: #660033;">-b</span> server</pre></div></div>

<p>Anyway, lets dive into the code. All of our work is based upon the original <a title="SC2 To-Dos App" href="http://github.com/sproutcore/todos">SC2 To-Dos app</a>, and I&#8217;ll walk through how we get from there to our completed AJAXified app.</p>
<h2>Fetching from the Server</h2>
<p>The first step is to fetch a list of our to-dos from the server. Here&#8217;s the code to do that:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">Todos <span style="color: #339933;">=</span> SC.<span style="color: #660066;">Application</span>.<span style="color: #660066;">create</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
  ready<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">this</span>._super<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">fetchTodos</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
&nbsp;
  fetchTodos<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    $.<span style="color: #660066;">ajax</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'/todos.json'</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span>
      success<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>data<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
        Todos.<span style="color: #660066;">todosController</span>.<span style="color: #660066;">beginPropertyChanges</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        data.<span style="color: #660066;">forEach</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">item</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
          <span style="color: #000066; font-weight: bold;">item</span> <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">item</span>.<span style="color: #660066;">todo</span><span style="color: #339933;">;</span>
          <span style="color: #003366; font-weight: bold;">var</span> todo <span style="color: #339933;">=</span> Todos.<span style="color: #660066;">Todo</span>.<span style="color: #660066;">create</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
            id<span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">item</span>.<span style="color: #660066;">id</span><span style="color: #339933;">,</span>
            title<span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">item</span>.<span style="color: #660066;">title</span><span style="color: #339933;">,</span>
            isDone<span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">item</span>.<span style="color: #660066;">done</span>
          <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
          Todos.<span style="color: #660066;">todosController</span>.<span style="color: #660066;">pushObject</span><span style="color: #009900;">&#40;</span>todo<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        Todos.<span style="color: #660066;">todosController</span>.<span style="color: #660066;">endPropertyChanges</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p><span id="more-1856"></span><br />
The <code>fetchTodos</code> method is simpler than it looks. We&#8217;re making an AJAX call to &#8220;todos.json&#8221; which returns an array of todos that looks like:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
</pre></td><td class="code"><pre class="json" style="font-family:monospace;">[
  { 
    todo: {
      done: false
      id: 13
      title: &quot;Todo One&quot;
    }
  },
  {
    todo: {
      done: false
      id: 14
      title: &quot;Todo Two&quot;
    }
  }
]</pre></td></tr></table></div>

<p>(Rails actually throws in a few additional fields, but we can ignore those.)</p>
<p>Once we get the data, we loop over each item and create a new <code>Todos.Todo</code>, adding it to <code>Todos.todosController</code>. Since our views are bound to the controller, as soon as these items are pushed, our page displays a list of our To-Dos.</p>
<h2>Creating Records</h2>
<p>Now that we&#8217;ve been able to fetch a list from the server, it would be nice we could actually add new records. We&#8217;ll begin by adding a <code>save</code> method to our <code>Todos.Todo</code> class.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">Todos.<span style="color: #660066;">Todo</span> <span style="color: #339933;">=</span> SC.<span style="color: #660066;">Object</span>.<span style="color: #660066;">extend</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
  <span style="color: #006600; font-style: italic;">// ...</span>
  id<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">null</span><span style="color: #339933;">,</span>
&nbsp;
  attributes<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #009900;">&#123;</span>
      title<span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">get</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'title'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
      done<span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">get</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'isDone'</span><span style="color: #009900;">&#41;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>.<span style="color: #660066;">property</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'title'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'isDone'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">cacheable</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
&nbsp;
  save<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> self <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">;</span>
&nbsp;
    $.<span style="color: #660066;">ajax</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'/todos.json'</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span>
      type<span style="color: #339933;">:</span> <span style="color: #3366CC;">'POST'</span><span style="color: #339933;">,</span>
      data<span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span> todo<span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">get</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'attributes'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
      dataType<span style="color: #339933;">:</span> <span style="color: #3366CC;">'json'</span><span style="color: #339933;">,</span>
      success<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>data<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        self.<span style="color: #660066;">set</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'id'</span><span style="color: #339933;">,</span> data<span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'todo'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'id'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
  <span style="color: #006600; font-style: italic;">// ...</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Next, we modify <code>Todos.todosController.createTodo</code> to save the new to-do:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">createTodo<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>title<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
  <span style="color: #003366; font-weight: bold;">var</span> todo <span style="color: #339933;">=</span> Todos.<span style="color: #660066;">Todo</span>.<span style="color: #660066;">create</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span> title<span style="color: #339933;">:</span> title <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">pushObject</span><span style="color: #009900;">&#40;</span>todo<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  todo.<span style="color: #660066;">save</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #009900;">&#125;</span></pre></td></tr></table></div>

<p>Now, when we create a new to-do, it will be automatically saved. If you refreshed the page now, you&#8217;d see the same list reloaded.</p>
<h2>Updating Your Records</h2>
<p>We&#8217;re doing well so far, but once we&#8217;ve created our record, we&#8217;re not doing any updates. Lets modify our code to automatically save any changes to the to-do:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">Todos.<span style="color: #660066;">Todo</span> <span style="color: #339933;">=</span> SC.<span style="color: #660066;">Object</span>.<span style="color: #660066;">extend</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
  <span style="color: #006600; font-style: italic;">//...</span>
  isNew<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #339933;">!</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">get</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'id'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>.<span style="color: #660066;">property</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'id'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">cacheable</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span>
&nbsp;
  save<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> self <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">,</span>
        url <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">get</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'isNew'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">?</span> <span style="color: #3366CC;">'/todos.json'</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">'/todos/'</span><span style="color: #339933;">+</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">get</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'id'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">+</span><span style="color: #3366CC;">'.json'</span><span style="color: #339933;">,</span>
        method <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">get</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'isNew'</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">?</span> <span style="color: #3366CC;">'POST'</span> <span style="color: #339933;">:</span> <span style="color: #3366CC;">'PUT'</span><span style="color: #339933;">;</span>
&nbsp;
    $.<span style="color: #660066;">ajax</span><span style="color: #009900;">&#40;</span>url<span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span>
      type<span style="color: #339933;">:</span> <span style="color: #3366CC;">'POST'</span><span style="color: #339933;">,</span>
      <span style="color: #006600; font-style: italic;">// _method is used by Rails to spoof HTTP methods not supported by all browsers</span>
      data<span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span> todo<span style="color: #339933;">:</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">get</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'attributes'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> _method<span style="color: #339933;">:</span> method <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
      <span style="color: #006600; font-style: italic;">// Sometimes Rails returns an empty string that blows up as JSON</span>
      dataType<span style="color: #339933;">:</span> <span style="color: #3366CC;">'text'</span><span style="color: #339933;">,</span>
      success<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>data<span style="color: #339933;">,</span> response<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        data <span style="color: #339933;">=</span> $.<span style="color: #660066;">trim</span><span style="color: #009900;">&#40;</span>data<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
        <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>data<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> data <span style="color: #339933;">=</span> JSON.<span style="color: #660066;">parse</span><span style="color: #009900;">&#40;</span>data<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span>
        <span style="color: #000066; font-weight: bold;">if</span> <span style="color: #009900;">&#40;</span>self.<span style="color: #660066;">get</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'isNew'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> self.<span style="color: #660066;">set</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'id'</span><span style="color: #339933;">,</span> data<span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'todo'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'id'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #009900;">&#125;</span>
      <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
&nbsp;
  autosave<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">save</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>.<span style="color: #660066;">observes</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'attributes'</span><span style="color: #009900;">&#41;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>That was pretty easy. The main work was modifying our <code>save</code> method so that it&#8217;s able to handle both updates and creates. We also added a nifty little <code>autosave</code> method that checks for any changes to our <code>attributes</code> and calls <code>save</code> automatically. The power of bindings really shines here.</p>
<p>The only thing left to do now is to delete to-dos.</p>
<h2>Deleting Records</h2>
<p>For this we need to add a <code>destroy</code> method to our to-do and update <code>Todos.todosController.clearCompletedTodos</code> to call it:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">Todos.<span style="color: #660066;">Todo</span> <span style="color: #339933;">=</span> SC.<span style="color: #660066;">Object</span>.<span style="color: #660066;">extend</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
  <span style="color: #006600; font-style: italic;">//...</span>
  isDestroyed<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">,</span>
&nbsp;
  destroy<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> self <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">;</span>
&nbsp;
    $.<span style="color: #660066;">ajax</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'/todos/'</span><span style="color: #339933;">+</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">get</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'id'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">+</span><span style="color: #3366CC;">'.json'</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span>
      type<span style="color: #339933;">:</span> <span style="color: #3366CC;">'POST'</span><span style="color: #339933;">,</span>
      data<span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span> _method<span style="color: #339933;">:</span> <span style="color: #3366CC;">'delete'</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #006600; font-style: italic;">// For Rails</span>
      dataType<span style="color: #339933;">:</span> <span style="color: #3366CC;">'text'</span><span style="color: #339933;">,</span> <span style="color: #006600; font-style: italic;">// Handle blank strings</span>
      success<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
        self.<span style="color: #660066;">set</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'isDestroyed'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
  <span style="color: #006600; font-style: italic;">//...</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
Todos.<span style="color: #660066;">todosController</span> <span style="color: #339933;">=</span> SC.<span style="color: #660066;">ArrayProxy</span>.<span style="color: #660066;">create</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
  <span style="color: #006600; font-style: italic;">//...</span>
  clearCompletedTodos<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003366; font-weight: bold;">var</span> self <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">;</span>
    <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">filterProperty</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'isDone'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">forEach</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>todo<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#123;</span>
      self.<span style="color: #660066;">removeObject</span><span style="color: #009900;">&#40;</span>todo<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      todo.<span style="color: #660066;">destroy</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
  <span style="color: #006600; font-style: italic;">//...</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p>Now, when you click &#8220;Clear Completed Todos&#8221;, they&#8217;ll also be removed on the server.</p>
<h2>Wrapping Up</h2>
<p>As you can see, most of our code wasn&#8217;t even server interaction, it was just making sure we notified the server at the right time. The server interaction was just some simple AJAX calls, made even simpler with jQuery. If you look at the code I provided on GitHub, you&#8217;ll notice that I have a series of conditionals to check for whether the record is in the process of saving or being destroyed. This helps to make sure that we don&#8217;t send duplicate create or delete requests or send conflicting saves. I hid all of that along with the error handling code to help focus on the key aspects of server interaction.</p>
<img src="http://feeds.feedburner.com/~r/Sproutcore-BlogPosts/~4/KRTqPM3bp7I" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.sproutcore.com/sproutcore-2-and-ajax/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		<feedburner:origLink>http://blog.sproutcore.com/sproutcore-2-and-ajax/</feedburner:origLink></item>
		<item>
		<title>Hubbub ❤ SproutCore – Socket.IO &amp; Modular Loading</title>
		<link>http://feedproxy.google.com/~r/Sproutcore-BlogPosts/~3/7TxoQNeiJVo/</link>
		<comments>http://blog.sproutcore.com/hubbub-%e2%9d%a4-sproutcore-socket-io-modular-loading/#comments</comments>
		<pubDate>Thu, 15 Sep 2011 18:41:10 +0000</pubDate>
		<dc:creator>Tyler Keating</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Tutorial]]></category>

		<guid isPermaLink="false">http://blog.sproutcore.com/?p=1837</guid>
		<description><![CDATA[As promised in my last post, I&#8217;ll go into more detail on some of the technical aspects of Hubbub. And since there was only a single request to talk about Socket.IO integration with SproutCore, that&#8217;s the topic for today. In order to keep these posts down to a nice bite-sized length, today will strictly be [...]]]></description>
			<content:encoded><![CDATA[<p>As promised in my last post, I&#8217;ll go into more detail on some of the technical aspects of <a title="Hubbub" href="https://hubbubapp.com" target="_blank">Hubbub</a>. And since there was only a single request to talk about Socket.IO integration with SproutCore, that&#8217;s the topic for today. In order to keep these posts down to a nice bite-sized length, today will strictly be about how Hubbub uses SproutCore&#8217;s modular loading to include Socket.IO.</p>
<h2>Socket.IO! I Choose You.</h2>
<p>There is actually some nice stuff that happens in Hubbub in real time if you have the app open. For example, if someone sends you a message, signs out an item to you, makes a new item available, or any number of other events occur, then the application updates instantly without requiring a page reload. Sure it&#8217;s not new, but with Socket.IO and SproutCore it&#8217;s also not a difficult-to-implement kludge.</p>
<p>So for those that haven&#8217;t yet tried it, Socket.IO is available <a title="Socket.IO" href="http://socket.io/" target="_blank">here</a>. There are really good instructions on using Socket.IO on their site, but it&#8217;s so simple I will include my entire setup here.</p>
<h3>My Setup &#8211; Server Side</h3>
<p>Hubbub&#8217;s app server is written with <a title="node.js" href="http://nodejs.org/" target="_blank">Node</a> and <a title="node web framework" href="http://expressjs.com/" target="_blank">Express</a>. So after installing Socket.IO, there&#8217;s nothing more to getting it working server-side than:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">app <span style="color: #339933;">=</span> require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'express'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">createServer</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>key<span style="color: #339933;">:</span> …<span style="color: #339933;">,</span> cert<span style="color: #339933;">:</span> …<span style="color: #339933;">,</span> ca<span style="color: #339933;">:</span> …<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
io <span style="color: #339933;">=</span> require<span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'socket.io'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">listen</span><span style="color: #009900;">&#40;</span>app<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
app.<span style="color: #660066;">listen</span><span style="color: #009900;">&#40;</span><span style="color: #CC0000;">3443</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Note: I use port 3443 locally with TLS/SSL encryption, which is not strictly necessary.<span id="more-1837"></span></p>
<h3>My Setup &#8211; Client Side</h3>
<p>On the client side, you need to first retrieve the Socket.IO JS from the server. Initially, I added the Socket.IO script to my copy of <code>index.rhtml</code> directly above the <code>javascripts_for_client</code> statement. This simply pulls the JavaScript from the server on page load like the Socket.IO default examples show and if you want to do the same and aren&#8217;t using a custom <code>index.rhtml</code>, then the instructions for copying <code>index.rhtml</code> are listed at the top of the original <a title="SproutCore's index.rhtml File" href="https://github.com/sproutcore/sproutcore/blob/master/lib/index.rhtml" target="_blank">file</a>.</p>
<p>However, I&#8217;m just not satisfied with Hubbub being anything less than the best application it can be, and the first improvement I made to reduce loading times was to load Socket.IO dynamically. Without getting into the details of how I use Statecharts, the application begins basically like this:</p>
<div id="attachment_1839" class="wp-caption aligncenter" style="width: 255px"><a href="http://blog.sproutcore.com/wp-content/uploads/2011/09/hubbub-initial-states-diagram-2.png"><img class="size-medium wp-image-1839" src="http://blog.sproutcore.com/wp-content/uploads/2011/09/hubbub-initial-states-diagram-2-245x300.png" alt="" width="245" height="300" /></a><p class="wp-caption-text">Initial States Diagram</p></div>
<p>Notice that I don&#8217;t load Socket.IO until the application reaches the Ready state. The following details describe exactly how I&#8217;ve done this.</p>
<h2>1. Directory Structure</h2>
<p>To make Socket.IO available to all the apps in my Hubbub project, I wanted it to be its own framework. The relevant directory structure I used is this:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">hubbub<span style="color: #339933;">/</span>
   frameworks<span style="color: #339933;">/</span>
      socket.<span style="color: #660066;">io</span><span style="color: #339933;">/</span>
         modules<span style="color: #339933;">/</span>
            io<span style="color: #339933;">/</span>
         resources<span style="color: #339933;">/</span></pre></div></div>

<p>I then copied <code>socket.io.min.js</code> and <code>WebSocketMain.swf</code> from <code>./node_modules/socket.io/node_modules/socket.io-client/</code> into my project like so:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">hubbub<span style="color: #339933;">/</span>
   frameworks<span style="color: #339933;">/</span>
      socket.<span style="color: #660066;">io</span><span style="color: #339933;">/</span>
         modules<span style="color: #339933;">/</span>
            io<span style="color: #339933;">/</span>
               socket.<span style="color: #660066;">io</span>.<span style="color: #660066;">min</span>.<span style="color: #660066;">js</span>
         resources<span style="color: #339933;">/</span>
            WebSocketMain.<span style="color: #660066;">swf</span></pre></div></div>

<h2>2. Buildfile</h2>
<p>The files are now where I want them, but SproutCore&#8217;s build tools won&#8217;t load anything in the <code>frameworks</code> or <code>modules</code> directories unless told to do so, plus I still need to proxy the Socket.IO traffic to my local development server. Here is the relevant part of my Buildfile:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">config <span style="color: #339933;">:</span>hubbub<span style="color: #339933;">,</span>
   <span style="color: #339933;">:</span>required <span style="color: #339933;">=&amp;</span>gt<span style="color: #339933;">;</span> <span style="color: #009900;">&#91;</span>
      <span style="color: #339933;">:</span><span style="color: #3366CC;">'socket.io'</span>
   <span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span>
   <span style="color: #339933;">:</span>deferred_modules <span style="color: #339933;">=&amp;</span>gt<span style="color: #339933;">;</span> <span style="color: #009900;">&#91;</span>
      <span style="color: #339933;">:</span><span style="color: #3366CC;">'socket.io/io'</span>
   <span style="color: #009900;">&#93;</span>
&nbsp;
proxy <span style="color: #3366CC;">'/socket.io'</span><span style="color: #339933;">,</span>
   <span style="color: #339933;">:</span>to <span style="color: #339933;">=&amp;</span>gt<span style="color: #339933;">;</span> <span style="color: #3366CC;">'localhost:3443'</span><span style="color: #339933;">,</span>
   <span style="color: #339933;">:</span>secure <span style="color: #339933;">=&amp;</span>gt<span style="color: #339933;">;</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">,</span> # Hubbub <span style="color: #000066; font-weight: bold;">is</span> entirely over HTTPS
   <span style="color: #339933;">:</span>timeout <span style="color: #339933;">=&amp;</span>gt<span style="color: #339933;">;</span> <span style="color: #CC0000;">25</span> # A longer timeout <span style="color: #000066; font-weight: bold;">for</span> polling transports</pre></div></div>

<p>I&#8217;ve required <code>:'socket.io'</code> here as an example, which isn&#8217;t strictly necessary. The reason you may want to do this is so that <code>frameworks/socket.io/resources/</code> will be included in the builds, and therefore if you were to use <code>flashsocket</code> as a transport mechanism, you would be able to set <code>WEB_SOCKET_SWF_LOCATION = sc_static('WebSocketMain.swf');</code> (see the Socket.IO FAQ).</p>
<p>Also notice that the <code>socket.io/io</code> module is deferred. Therefore it won&#8217;t be fetched until we tell SC.Module to do so. That way, we can pass through our initial application states without any background loading interfering with the more important task of getting people into the app as quickly as possible.</p>
<h2>3. Load the Code</h2>
<p>Finally, to load Socket.IO I added the following to Hubbub&#8217;s READY state:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">enterState<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
      <span style="color: #006600; font-style: italic;">// Load Socket.IO and initialize it when it is ready</span>
      SC.<span style="color: #660066;">Module</span>.<span style="color: #660066;">loadModule</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'socket.io/io'</span><span style="color: #339933;">,</span> <span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">,</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">initializeSocketIO</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
    <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span>
&nbsp;
    initializeSocketIO<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
&nbsp;
      socket <span style="color: #339933;">=</span> io.<span style="color: #660066;">connect</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'https://localhost:3443'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
      socket.<span style="color: #660066;">on</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'connect'</span><span style="color: #339933;">,</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
        <span style="color: #006600; font-style: italic;">// ... for a later post</span></pre></div></div>

<h3>Cool Beans</h3>
<p>At this point, I see the following in my development console after reaching the READY state:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">SC.<span style="color: #660066;">Module</span><span style="color: #339933;">:</span> Attempting to load <span style="color: #3366CC;">'socket.io/io'</span>
SC.<span style="color: #660066;">Module</span><span style="color: #339933;">:</span> Module <span style="color: #3366CC;">'socket.io/io'</span> <span style="color: #000066; font-weight: bold;">is</span> not loaded<span style="color: #339933;">,</span> loading now.
<span style="color: #660066;">SC</span>.<span style="color: #660066;">Module</span><span style="color: #339933;">:</span> Loading JavaScript file <span style="color: #000066; font-weight: bold;">in</span> <span style="color: #3366CC;">'socket.io/io’ -&amp;gt; '</span><span style="color: #339933;">/</span>static<span style="color: #339933;">/</span>socket.<span style="color: #660066;">io</span><span style="color: #339933;">/</span>io<span style="color: #339933;">/</span>en<span style="color: #339933;">-</span>ca<span style="color: #339933;">/</span>current<span style="color: #339933;">/</span>javascript.<span style="color: #660066;">js</span><span style="color: #339933;">?</span><span style="color: #CC0000;">1315847166</span><span style="color: #3366CC;">'
SC.Module: Module '</span>socket.<span style="color: #660066;">io</span><span style="color: #339933;">/</span>io<span style="color: #3366CC;">' finished loading.
SC.Module: Evaluating and invoking callbacks for '</span>socket.<span style="color: #660066;">io</span><span style="color: #339933;">/</span>io<span style="color: #3366CC;">'.
SC.Module: Module '</span>socket.<span style="color: #660066;">io</span><span style="color: #339933;">/</span>io<span style="color: #3366CC;">' has completed loading, invoking callbacks.
RTM: Welcome to Hubbub Real Time Messaging</span></pre></div></div>

<p>And that my friends, is that! An extra 42KB of data and processing that does not detract from the application start up. See it in action at <a title="Hubbub" href="https://hubbubapp.com" target="_blank">https://hubbubapp.com</a> . You&#8217;ll need to get one of your <strong>Borrowers</strong> online at the same time as you.</p>
<img src="http://feeds.feedburner.com/~r/Sproutcore-BlogPosts/~4/7TxoQNeiJVo" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.sproutcore.com/hubbub-%e2%9d%a4-sproutcore-socket-io-modular-loading/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		<feedburner:origLink>http://blog.sproutcore.com/hubbub-%e2%9d%a4-sproutcore-socket-io-modular-loading/</feedburner:origLink></item>
		<item>
		<title>Dispatch From The Edge: Blacklists and Whitelists</title>
		<link>http://feedproxy.google.com/~r/Sproutcore-BlogPosts/~3/iYBLxSJL8cw/</link>
		<comments>http://blog.sproutcore.com/dispatch-from-the-edge-blacklists-and-whitelists/#comments</comments>
		<pubDate>Tue, 13 Sep 2011 18:40:30 +0000</pubDate>
		<dc:creator>Greg Moeck</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Dispatch]]></category>

		<guid isPermaLink="false">http://blog.sproutcore.com/?p=1808</guid>
		<description><![CDATA[The &#8220;true edge&#8221; of SproutCore nowadays is primarily the 2.0 branch, where the new and fresh is continually appearing. However that doesn&#8217;t mean that the 1.x branch has been forsaken, or forgotten. The 1.7 beta release has some pretty cool features that allow you to improve the performance of your application. What I want to [...]]]></description>
			<content:encoded><![CDATA[<p>The &#8220;true edge&#8221; of SproutCore nowadays is primarily the 2.0 branch, where the new and fresh is continually appearing. However that doesn&#8217;t mean that the 1.x branch has been forsaken, or forgotten. The 1.7 beta release has some pretty cool features that allow you to improve the performance of your application. What I want to focus on today is how to use a blacklist or whitelist with the 1.x build tools.</p>
<p>One of the biggest knocks against SproutCore 1.x is that it is a &#8220;big, monolithic framework&#8221;. You end up pulling in more than you&#8217;re ever going to use or need. This is a problem, particularly in a JavaScript context, because it increases the size of the file that needs to be sent down from your server, and then parsed by the browser. Particularly in a mobile context, this can be a serious performance drain.</p>
<p>Enter the SproutCore whitelist/blacklist. If there is a section of SproutCore 1.x that you&#8217;re not using inside of your application, you can use either a whitelist or a blacklist to tell the build tools not to include that code in the final packaged version of your application&#8217;s JavaScript. So for example, if my application is not using collection view, I could create a file called Blacklist inside of the root of my file directory, and put the following into it to exclude collection view:</p>
<p><code><br />
{<br />
"/sproutcore/desktop": "views/collection.js"<br />
}<br />
</code></p>
<p>&#8220;/sproutcore/desktop&#8221; is the &#8220;target&#8221; for the build tools, which you can think of as basically the framework to target. Then, &#8220;views/collection.js&#8221; which is the &#8220;rule&#8221; for the build tools. If the list is a whitelist, then the rule would mean to include the file in the final build, whereas if the list is a blacklist, then the rule would exclude that file. So in this case, &#8220;/sproutcore/desktop&#8221;: &#8220;views/collection.js&#8221; tells the build tools to exclude the file &#8220;views/collection.js&#8221; from the desktop framework.</p>
<p>So if you have a 1.x app and you&#8217;re looking to improve the initial load time of your app, I would create a blacklist for your application, and go file by file seeing what you can exclude from the framework. Happy optimizing.</p>
<img src="http://feeds.feedburner.com/~r/Sproutcore-BlogPosts/~4/iYBLxSJL8cw" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.sproutcore.com/dispatch-from-the-edge-blacklists-and-whitelists/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://blog.sproutcore.com/dispatch-from-the-edge-blacklists-and-whitelists/</feedburner:origLink></item>
		<item>
		<title>Localization in SproutCore 1.6</title>
		<link>http://feedproxy.google.com/~r/Sproutcore-BlogPosts/~3/hWVITtCLyRc/</link>
		<comments>http://blog.sproutcore.com/localization-in-sproutcore-1-6/#comments</comments>
		<pubDate>Thu, 01 Sep 2011 20:44:18 +0000</pubDate>
		<dc:creator>Peter Bergstrom</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Localization]]></category>

		<guid isPermaLink="false">http://blog.sproutcore.com/?p=1750</guid>
		<description><![CDATA[Why Should I Care About Localization and Internationalization? When developing applications, localization and internationalization are things that are easily overlooked and forgotten until the very end. In the case of smaller applications, they are targeted to only one language, and not having to account for localization or internationalization might work out in the end. However, [...]]]></description>
			<content:encoded><![CDATA[<h2>Why Should I Care About Localization and Internationalization?</h2>
<p>When developing applications, localization and internationalization are things that are easily overlooked and forgotten until the very end. In the case of smaller applications, they are targeted to only one language, and not having to account for localization or internationalization might work out in the end. </p>
<p>However, especially for larger applications or applications that are targeted to several international markets, planning and implementing an application with localization and internationalization is extremely important. Without proper planning, you can get into a lot of trouble that could have been alleviated with very little upfront effort. The type of planning you&#8217;ll need to do is what we&#8217;ll go over in this in this post.</p>
<h2>Factor in localization early in your development cycle!</h2>
<p>As a developer, you should plan for localization and internationalization early in your development cycle, when it is easy to deal with. Once an application grows too large, it is very difficult to add localizable strings. </p>
<p>If you develop without taking into account localization, often text winds up hard coded and, as with any application, these strings are found in a million different places. Having to track down all the non-localized strings after the fact is time consuming and unnecessary if accounted for earlier in the project.</p>
<h2>Localizing Your Apps with SproutCore</h2>
<p>SproutCore makes it easy to localize your application. Using a strings table for each language, developers can enter key-value pairs. These keys are generic and are referenced throughout the application. </p>
<p>When the application runs, instead of using the actual string in the view, SproutCore looks up the correct localized value from the strings table. This makes it easy not only to localize the application, but also to manage all of the strings in your application because they are all located in one place. If you need to finalize the strings, you can send that off to be finalized without having the stakeholders know any JavaScript.<br />
<span id="more-1750"></span><br />
However, there are more things to localize than just strings. For each language or locale, you can have a sub-directory that contains not only your strings file, but also other resources such as images, CSS, and HTML templates. We&#8217;ll go into more detail how to properly set up your application for localization in the next section.</p>
<h2>Set Up Your Application for Localization</h2>
<p>Now that you&#8217;re thinking about localization, how do you go about setting up an application to be localized? There are some things that will need to be expanded upon from the normal directory structure that you are familiar with.</p>
<h3>The directory structure</h3>
<p>The first thing to go over is the general structure of a SproutCore application as it is normally presented when you create a basic app. Below is the directory structure for an application, MyApp, that contains an image, <code>myapp_logo.png</code> inside of the <code>resources</code> directory that contains some English text, and the normal <code>en</code> directory with CSS and a strings file. Most of time the, the strings file will be empty because the developer hasn&#8217;t considered localization.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">apps<span style="color: #339933;">/</span>
   myapp<span style="color: #339933;">/</span>
      core.<span style="color: #660066;">js</span>
      en<span style="color: #339933;">/</span>
         strings.<span style="color: #660066;">js</span>
         myapp.<span style="color: #660066;">css</span>
      main.<span style="color: #660066;">js</span>
      resources<span style="color: #339933;">/</span>
         images<span style="color: #339933;">/</span>
            myapp_logo.<span style="color: #660066;">png</span></pre></div></div>

<p>However, this is not very localizable. Let&#8217;s say that we also want the application to be available in German. In this case, we&#8217;ll have to readjust the directory structure a bit. </p>
<p>First, the image in the case has some text that needs to be in German. Second, there is some CSS layout that needs to be readjusted for the really long German words. Third, and most important, there are a lot of strings that need to be translated, so we need to create a strings file.</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">apps<span style="color: #339933;">/</span>
   myapp<span style="color: #339933;">/</span>
      core.<span style="color: #660066;">js</span>
      en<span style="color: #339933;">/</span>
         strings.<span style="color: #660066;">js</span>
         myapp.<span style="color: #660066;">css</span>
         images<span style="color: #339933;">/</span>
            myapp_logo.<span style="color: #660066;">png</span>
      de<span style="color: #339933;">/</span>
         strings.<span style="color: #660066;">js</span>
         myapp.<span style="color: #660066;">css</span>
         images<span style="color: #339933;">/</span>
            myapp_logo.<span style="color: #660066;">png</span>
      main.<span style="color: #660066;">js</span></pre></div></div>

<p>In this structure, when you run the application in English, only the contents of the &#8220;en&#8221; directory will be loaded and vice versa for German. Therefore, you can optimize the code loaded for the specific language.</p>
<h3>About Those Language Codes</h3>
<p>The language codes that are used in a SproutCore application are standard internationally recognized language codes in the format: &#8216;language_REGION or just &#8216;language&#8217;. For instance, if you want to localize your application into British English and American English, you would have two localizable directories: <code>en_US</code> and <code>en_UK</code>.</p>
<h3>The <code>strings.js</code> File</h3>
<p>At the heart of the localization system that SproutCore provides is the strings file. Each language has its own file in its respective language directory. It is important to note that only the strings file in the language that you&#8217;re running will be loaded for any given language when the application runs. </p>
<p>Basically, the string file is a lookup table for a string key, which you reference in your application code, and a string value, which is the corresponding localized string for the key.</p>
<p>The strings file has a specific format that you will need to follow:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">SC.<span style="color: #660066;">StringsFor</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'en_US'</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span>
	<span style="color: #3366CC;">'key'</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">'value'</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<h2>Localizing Your Application</h2>
<p>Now that you have everything set up, you can write your localizable application. Whenever you create a view element using either a <code>SC.View</code> or a <code>SC.TemplateView</code>, it is likely that you will need some text to go with it. </p>
<p>Instead of putting in some hardcoded text, even if it is temporary, you should create a key and add that to your view element and a corresponding value in your strings file, regardless if it is final or not.</p>
<h3>What is the Best Practice to Create a String Key-Value Pair?</h3>
<p>There isn&#8217;t a hard and fast rule on how to create a string key, but as long as you come up with a consistent formula, it will work out in the end. One way to do it is to refer to the path of the view inside your application. </p>
<p>For example, if you have a list view in the application that has items with a title, you could name the string key something like <code>MyApp.List.Item.Title</code>. While this seems verbose, any developer who looks at your view will know what the key stands in for.</p>
<p>Another tip is that if a string is not finalized, you should make it stand out clearly in the UI until it is finalized. One way to do so is to precede it with an underscore: <code>_MyApp is a great way search for beanie babies</code>. Once that string is approved by the stakeholders, you can easily remove the underscore.</p>
<h3>Localization in <code>SC.Views</code></h3>
<p>Several of the built-in SproutCore <code>SC.Views</code> have support for localization. for example, you can pass in localization string key into a <code>SC.LabelView</code>:</p>

<div class="wp_syntax"><div class="code"><pre class="javascript" style="font-family:monospace;">MyApp.<span style="color: #660066;">TitleLabel</span> <span style="color: #339933;">=</span> SC.<span style="color: #660066;">LabelView</span>.<span style="color: #660066;">extend</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
	localize<span style="color: #339933;">:</span> YES<span style="color: #339933;">,</span>
	value<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;MyApp.TitleLabel&quot;</span>
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<h2>Using the .loc() Function for Computed Strings</h2>
<p>To understand how to do more complex localizations with passed-in properties, it is important to know how the .loc() function operates. In many cases it is run for you by SproutCore, but there are cases where you want to do something more dynamic. </p>
<p>The .loc() function takes optional parameters like the .fmt() function. For example, let&#8217;s say that you have a computed property on a customized SC.TemplateView that represents a list item. You want this list item to be more dynamic, showing a localized string with some parameters; note that the order of the parameters may be different in different languages. </p>
<p>The  key-value pair is the following: &#8220;MyApp.List.Item.Title&#8221;: &#8220;%@1 employees working for %@2&#8243;</p>
<p><strong>list_item.js</strong> view:</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
</pre></td><td class="code"><pre class="javascript" style="font-family:monospace;">	MyApp.<span style="color: #660066;">ListItem</span> <span style="color: #339933;">=</span> SC.<span style="color: #660066;">TemplateView</span>.<span style="color: #660066;">extend</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span>
		templateName<span style="color: #339933;">:</span> <span style="color: #3366CC;">'list_item'</span><span style="color: #339933;">,</span>
		localizedTitle<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
			<span style="color: #003366; font-weight: bold;">var</span> content <span style="color: #339933;">=</span> <span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">get</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'content'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> ret <span style="color: #339933;">=</span> <span style="color: #3366CC;">''</span><span style="color: #339933;">;</span>
			<span style="color: #000066; font-weight: bold;">if</span><span style="color: #009900;">&#40;</span>content<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
				ret <span style="color: #339933;">=</span> <span style="color: #3366CC;">&quot;MyApp.List.Item.Title&quot;</span>.<span style="color: #660066;">loc</span><span style="color: #009900;">&#40;</span>content.<span style="color: #660066;">get</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'employeeCount'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> content.<span style="color: #660066;">get</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'managerName'</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
			<span style="color: #009900;">&#125;</span>
			<span style="color: #000066; font-weight: bold;">return</span> ret<span style="color: #339933;">;</span>
		<span style="color: #009900;">&#125;</span>.<span style="color: #660066;">property</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'*content.employeeCount'</span><span style="color: #339933;">,</span> <span style="color: #3366CC;">'*content.managerName'</span><span style="color: #009900;">&#41;</span>.<span style="color: #660066;">cacheable</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>
	<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></td></tr></table></div>

<p><strong>list_item.handlebars</strong> template:</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">{{localizedTitle}}</pre></div></div>

<p>Now, the computed &#8216;localizedTitle&#8217; property will be used inside of the template and properly format for any language.</p>
<h2>Localizing Simple Values in Templates</h2>
<p>In SC.TemplateView templates, there is a handlebars helper that allows you to easily localize strings without having to use a computed property. Computed properties only need to be be used if there are complex properties. In the case of a simple static string, you can use the &#8216;loc&#8217; helper in the handlebars template directly.</p>

<div class="wp_syntax"><div class="code"><pre class="html" style="font-family:monospace;">{{loc &quot;MyApp.Path.To.Loc.String&quot;}}</pre></div></div>

<h2>Conclusion</h2>
<p>SproutCore provides a powerful way to localize your application into as many languages as you need. The main takeaway from this post should be that if your application might support multiple languages, plan ahead and do the right thing early on. If you don&#8217;t, it will be difficult to retrofit your existing application to support localization.</p>
<img src="http://feeds.feedburner.com/~r/Sproutcore-BlogPosts/~4/hWVITtCLyRc" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.sproutcore.com/localization-in-sproutcore-1-6/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://blog.sproutcore.com/localization-in-sproutcore-1-6/</feedburner:origLink></item>
		<item>
		<title>SproutCore 1.7 Beta Released</title>
		<link>http://feedproxy.google.com/~r/Sproutcore-BlogPosts/~3/PeOPh7qGy6M/</link>
		<comments>http://blog.sproutcore.com/sproutcore-1-7-beta-released/#comments</comments>
		<pubDate>Tue, 30 Aug 2011 19:33:52 +0000</pubDate>
		<dc:creator>Peter Wagenet</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Release]]></category>

		<guid isPermaLink="false">http://blog.sproutcore.com/?p=1792</guid>
		<description><![CDATA[I&#8217;m pleased to announce that SproutCore 1.7 beta is now available. This release is largely a bug fix release and the addition of some minor features so if you&#8217;re using 1.6 and like the cutting edge you should check it out. Installers are available for Mac and Windows. If you&#8217;re using RubyGems, just run gem [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m pleased to announce that SproutCore 1.7 beta is now available. This release is largely a bug fix release and the addition of some minor features so if you&#8217;re using 1.6 and like the cutting edge you should check it out. Installers are available for <a title="SproutCore Beta Mac" href="http://installers.sproutcore.com/SproutCore-Beta.pkg">Mac</a> and <a title="SproutCore Beta Windows" href="http://installers.sproutcore.com/SproutCore-Beta.exe">Windows</a>. If you&#8217;re using RubyGems, just run <code>gem install sproutcore --pre</code>. A word of warning, however: if you&#8217;re using the installers the beta will overwrite any previously installed versions of SproutCore. As always, share any issues you encounter on <a title="SproutCore Issue Tracker" href="https://github.com/sproutcore/sproutcore/issues">Github Issues</a>.</p>
<p>Read on for more information on the changes.<span id="more-1792"></span></p>
<p>In the framework itself changes include:</p>
<ul>
<li>Safari Lion browser detection.</li>
<li>Speed improvements</li>
<li>Flag to stop PickerPane repositioning when resizing the window</li>
<li>Option to enable or disable overflow in SegmentedView</li>
<li>Support for autoCorrect and autoCapitalize in TextFields</li>
<li>Minor improvements in SC.Statechart</li>
<li>New SC globals to provide information like build mode, build number and locale.</li>
<li>Lots of bug fixes</li>
</ul>
<p>New features in the build tools include:</p>
<ul>
<li>When a stylesheet hits the 4096 CSS selectors limit in IE , the files will now be automatically split.</li>
<li>Sprites are optimized to use less space</li>
<li>Layout.js, which includes location metrics, will be always first when building the js files</li>
<li>Added security feature for dev environment. By default sc-server can only be used from your local machine unless you set a flag.</li>
</ul>
<p>Along with the following bug fixes:</p>
<ul>
<li>Sprites are again the default for abbot due to performance issues with data-uris in some browsers</li>
<li>index.html will be minified again</li>
<li>Whitelist and black list fixes</li>
<li>Fixed iOS retina display styling</li>
</ul>
<div>For a full list of all changes see the Changelogs: <a title="Framework Changelogs" href="https://github.com/sproutcore/sproutcore/blob/master/CHANGELOG.md">Framework</a> and <a title="Build Tools Changelog" href="https://github.com/sproutcore/abbot/blob/master/CHANGELOG">Build Tools</a>.</div>
<img src="http://feeds.feedburner.com/~r/Sproutcore-BlogPosts/~4/PeOPh7qGy6M" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.sproutcore.com/sproutcore-1-7-beta-released/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://blog.sproutcore.com/sproutcore-1-7-beta-released/</feedburner:origLink></item>
		<item>
		<title>Video from the August South Bay Meetup</title>
		<link>http://feedproxy.google.com/~r/Sproutcore-BlogPosts/~3/xkllJ_WrLg8/</link>
		<comments>http://blog.sproutcore.com/video-from-the-august-south-bay-meetup/#comments</comments>
		<pubDate>Fri, 26 Aug 2011 00:51:32 +0000</pubDate>
		<dc:creator>Madeleine Douglas</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[Community]]></category>
		<category><![CDATA[Demo]]></category>
		<category><![CDATA[Events]]></category>
		<category><![CDATA[Video]]></category>

		<guid isPermaLink="false">http://blog.sproutcore.com/?p=1781</guid>
		<description><![CDATA[Thanks to all of you who came out to our first meetup in the South Bay, at at Nokia HQ in Sunnyvale! For those of you who couldn’t make it, don’t worry; as always, we made sure to record everything for you. It was quite the night— we heard presentations from Majd Taby and Greg [...]]]></description>
			<content:encoded><![CDATA[<p>Thanks to all of you who came out to our first meetup in the South Bay, at at Nokia HQ in Sunnyvale! For those of you who couldn’t make it, don’t worry; as always, we made sure to record everything for you. </p>
<p>It was quite the night— we heard presentations from Majd Taby and Greg Moeck, followed by community Q&#038;A. Majd started us off with a talk on how bindings help SproutCore make your application smaller, concluding with an impressive demo of his work on SproutCore Touch and TransformJS. Greg spoke about connecting SproutCore apps to your backend, and best-practice approaches based on your app&#8217;s structure. </p>
<p>Check out the videos below! Many thanks again to our friends at Nokia, who recorded the talks— note the improved video quality <img src='http://blog.sproutcore.com/wp-includes/images/smilies/icon_razz.gif' alt=':P' class='wp-smiley' />  — and kept everyone happily fed with pizza, cookies, and refreshments for the night.</p>
<p>Hope to see everyone at the September meetup, back in San Francisco at Twitter! </p>
<p><iframe src="http://player.vimeo.com/video/28174480" width="400" height="190" frameborder="0"></iframe></p>
<p><iframe src="http://player.vimeo.com/video/28175133" width="400" height="180" frameborder="0"></iframe></p>
<img src="http://feeds.feedburner.com/~r/Sproutcore-BlogPosts/~4/xkllJ_WrLg8" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.sproutcore.com/video-from-the-august-south-bay-meetup/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.sproutcore.com/video-from-the-august-south-bay-meetup/</feedburner:origLink></item>
	</channel>
</rss>

