<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>The Loop</title>
	<atom:link href="http://blog.getintheloop.eu/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.getintheloop.eu</link>
	<description>Technologist Timothy Perrett rambling about technology</description>
	<lastBuildDate>Mon, 26 Dec 2011 19:54:59 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Using dust.js with Scala SBT</title>
		<link>http://blog.getintheloop.eu/2011/12/26/using-dust-js-with-scala-sbt/</link>
		<comments>http://blog.getintheloop.eu/2011/12/26/using-dust-js-with-scala-sbt/#comments</comments>
		<pubDate>Mon, 26 Dec 2011 19:54:59 +0000</pubDate>
		<dc:creator>timperrett</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[SBT]]></category>
		<category><![CDATA[Scala]]></category>

		<guid isPermaLink="false">http://blog.getintheloop.eu/?p=1217</guid>
		<description><![CDATA[If you&#8217;ve been living under a rock for the past few weeks you might have missed LinkedIn bloging about their usage of dust.js. This idea of client-side templating is certainly a very interesting one, and something that is in all likelihood very useful for many large-scale applications currently in production. dust.js is quite nice in [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;ve been living under a rock for the past few weeks you might have missed LinkedIn <a href="http://engineering.linkedin.com/frontend/leaving-jsps-dust-moving-linkedin-dustjs-client-side-templates">bloging</a> about their usage of <a href="http://akdubya.github.com/dustjs">dust.js</a>. This idea of client-side templating is certainly a very interesting one, and something that is in all likelihood very useful for many large-scale applications currently in production. dust.js is quite nice in that it has no dependencies on any javascript library such as JQuery or YUI. This is really rather handy is it means no prescription on your style of implementation.</p>

<p>However, whilst the dust.js documentation has a wide range of examples demonstrating how to use the templating engine, what it does not have is any examples of how one might actually wrap it up and use it. So, with that I wanted to just write up a quick post to explain some of the things that might not be immediately obvious. Before getting to the meat of the article, it&#8217;s worth bearing in mind some terminology:</p>

<ul>
<li><strong>Template</strong>: The source dust.js template</li>
<li><strong>Compiled template</strong>: A pre-compiled version of the template; essentially some generated JavaScript that is created at build-time (it&#8217;s also possible to create the JavaScript at runtime, but this is heavily discouraged)</li>
<li><strong>Context</strong>: Each template can only be rendered with a context. More regularly we can think of this as the data that populates the template variables</li>
</ul>

<p>In short, the developers writes a source template which is then compiled to JavaScript at build time and then rendered at runtime with a given context; which is likely a dynamic JSON payload.</p>

<p>When I first go going with dust.js I was unsure how to handle this build-time compilation. Frankly, the support for everything that isn&#8217;t JavaScript or <a href="http://nodejs.org/">Node</a> was (and is still mostly) non-existent. This was problematic as I certainly didn&#8217;t want to be compiling templates on each and every request for a given HTML page. With that, I set about writing an <a href="https://github.com/timperrett/sbt-dustjs">SBT plugin for dust.js template compilation</a>. This then allows you to have SBT build the dust.js templates into JavaScript that you can simply reference directly from your HTML (more on this later). The plugin itself takes templates it finds in <code>src/main/dust</code> and compiles them to the resource managed target whenever you invoke the <code>dust</code> task from the SBT shell. It&#8217;s also super easy to redirect the compilation output to the webapp directory during development so that you can simply use the local Jetty server to tryout your app:</p>

<pre><code>(resourceManaged in (Compile, DustKeys.dust)) <<= (
  sourceDirectory in Compile){
    _ / "webapp" / "js" / "view"
}  
</code></pre>

<p>But I digress. For more information about the plugin, see it&#8217;s <a href="https://github.com/timperrett/sbt-dustjs">README file in the github repo</a>. </p>

<p>After making my own tooling for SBT to work with dust.js, I then got to thinking about how one would actually wrap the dust.js rendering system. Curiously, the examples I found online suggest making an AJAX call to fetch the context, or template data. This strikes me as quite sub-optimal as it would mean creating the following requests:</p>

<ul>
<li>fetching the general html for the page in the first instance</li>
<li>another request for the dust.js runtime</li>
<li>another request for the dust template </li>
<li>and then another for the context data</li>
</ul>

<p>All that, just to render one template and add unnecessary lag to the page load whilst the ancillary request for context data takes place (after the initial page load has already completed!). For general page rendering, this seems somewhat bizarre. That is to say, requesting context data via AJAX for say, a single page application could well be a reasonable use-case, but for general pages that render &#8220;in full&#8221;, it seems silly. </p>

<p>Assuming you&#8217;re just rendering regular page content, we can make the separation between things one would want to load and cache locally in the browser, and things that need to be dynamic. For the most part, the context is the only thing you&#8217;d want to be dynamic and the more general plumbing code for rendering would probably be reusable throughout your rendering call sites. Consider a simple sample:</p>

<p>The dust template (lets call it home.dust in src/main/dust):</p>

<pre><code>&lt;div&gt;
  &lt;h2&gt;Hey {name}&lt;/h2&gt;
&lt;/div&gt;  
</code></pre>

<p>This template will then be compiled to home.js and placed in the resource managed output location (as per your build config). The other thing to probably think about is if had several pre-compiled template files needed on a given page it would make sense to merge and minify them into a single JS file. Alternatively, if you were building a single-page application it might be nice to use a client-side loading framework like <a href="http://labjs.com/">LABjs</a> to pull in the template files lazily (i.e. as you needed them). Getting back tot eh example, and considering the aforementioned, lets assume a HTML page that loads the DOM skeleton and the static libraries needed for rendering:</p>

<pre><code>&lt;!DOCTYPE html PUBLIC &quot;-//W3C//DTD XHTML 1.0 Strict//EN&quot;
  &quot;http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd&quot;&gt;
&lt;html xmlns=&quot;http://www.w3.org/1999/xhtml&quot; xml:lang=&quot;en&quot; lang=&quot;en&quot;&gt;
&lt;head&gt;
  &lt;meta http-equiv=&quot;Content-Type&quot; content=&quot;text/html; charset=utf-8&quot;/&gt;
  &lt;script type=&quot;text/javascript&quot; src=&quot;js/dust.min.js&quot;&gt;&lt;/script&gt;
  &lt;script type=&quot;text/javascript&quot; src=&quot;js/view/home.js&quot;&gt;&lt;/script&gt;
&lt;/head&gt;
&lt;body&gt;
  &lt;h1&gt;Home&lt;/h1&gt;
&lt;/body&gt;
&lt;/html&gt;
</code></pre>

<p>Now, as it stands this page would display the heading &#8220;Home&#8221; and load the dust library along with the compiled template; otherwise it is essentially static. In order to render the dust template one would have to add something like the following to the page <code>&lt;head&gt;</code>:</p>

<pre><code>&lt;script type=&quot;text/javascript&quot;&gt;
//&lt;![CDATA[
dust.render(&quot;home&quot;, { name: &quot;Fred&quot; }, function(err, out) {
  document.getElementById('whatever').innerHTML = out;
});
//]]&gt;
&lt;/script&gt;
</code></pre>

<p>This simple bit of JS would render the content into the element with the &#8220;whatever&#8221; ID attribute. Now then, this will work, and prove the concept for sure. What it does not do however is provide a dynamic context, which almost certainly most users would want to do. In this way, I can see why people might see that it made sense to make an AJAX request to a pure JSON backend service to get the context dynamically, but as above, this would be a bit slow and cumbersome. Instead, I think it would probably make more sense to dynamically deliver a call to a rendering function with the desired context. Let&#8217;s qualify that: when the page loads, the template has been loaded and so has the dust library, so all that is actually required is have a call site that starts the rendering. I think this need can quite nicely be served by a server-side helper function. In essence, when the page is loaded, the server generates a <code>&lt;script&gt;</code> tag. Here&#8217;s an example:</p>

<pre><code>&lt;body&gt;
  ...
  &lt;script type=&quot;text/javascript&quot; src=&quot;/view/home&quot;&gt;&lt;/script&gt;
&lt;/body&gt;</code></pre>

<p>Which in turn would deliver something like:</p>

<pre><code>draw("home", { name: "Whatever" });</code></pre>

<p>That is, where the <code>draw</code> function wraps the dust rendering system. This is just an example though as the point is that this could be any kind of JavaScript. For instance, it could be a backbone.js view or something along those lines: you deliver the rendering code along with the context. This at least seems more optimal than making a fuckton of JavaScript requests for context objects as other blogs suggest. </p>

<p>In the next post i&#8217;ll be showing you how to combine all the latest hipster web programming tools like <a href="http://akdubya.github.com/dustjs/">dust.js</a>, <a href="http://coffeescript.org/">CoffeeScript</a> and <a href="http://lesscss.org/">Less</a> with a Scala backend using <a href="http://unfiltered.databinder.net/">Unfiltered</a> to deliver the dynamic template contexts. </p>
]]></content:encoded>
			<wfw:commentRss>http://blog.getintheloop.eu/2011/12/26/using-dust-js-with-scala-sbt/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>The Year in Photos, 2011</title>
		<link>http://blog.getintheloop.eu/2011/12/17/the-year-in-photos-2011/</link>
		<comments>http://blog.getintheloop.eu/2011/12/17/the-year-in-photos-2011/#comments</comments>
		<pubDate>Sat, 17 Dec 2011 20:55:19 +0000</pubDate>
		<dc:creator>timperrett</dc:creator>
				<category><![CDATA[Personal]]></category>

		<guid isPermaLink="false">http://blog.getintheloop.eu/?p=1194</guid>
		<description><![CDATA[This is a fairly personal post, so i&#8217;m sorry if you are a regular reader of the Scala articles here &#8211; those will resume from the next post! The Years Events As is becoming customary, I like to try and review the year nearly past as we look forward to the delights of the next. [...]]]></description>
			<content:encoded><![CDATA[<p><em>This is a fairly personal post, so i&#8217;m sorry if you are a regular reader of the Scala articles here &#8211; those will resume from the next post!</em></p>


	<h2>The Years Events</h2>


	<p>As is becoming customary, I like to try and review the year nearly past as we look forward to the delights of the next. This blog is the second in a yearly series to make a conscious effort to note what the year was made up of and recall those awesome memories made.</p>


	<h5>Alpe d&#8217;huez, France</h5>


	<p>Most years I try to get some skiing in with friends, and this year we&#8217;d decided to go to France rather than my beloved Italy. Whilst the snow could have been better, we had a great time. I took this picture at the top of the highest gondola lift&#8230;</p>


	<p><img src="http://blog.getintheloop.eu/wp-content/uploads/2011/12/1c.jpg" alt="" /></p>


	<h5>Bathoniean Sunsets</h5>


	<p>I&#8217;m fortunate to live in a beautiful area of the UK, and spring time is quite idyllic here. As the winter thaw gives way to things growing and spouting, the sun once again starts to bathe the evenings with glorious sunsets. This is one such evening looking out over the garden.</p>


	<p><img src="http://blog.getintheloop.eu/wp-content/uploads/2011/12/2.jpg" alt="" /></p>


	<h5>QConn London, Scala Community Dinner</h5>


	<p>March saw QConn return to London for a whole week and bring with it a heard of geeks from all over the globe. Many of my friends were visiting for the conference and with that decided that it would be a good idea to get the Scala folks together for some food, wine and all-round good times. Having people like <a href="twitter.com/jstrachan">James</a> and <a href="twitter.com/debasishg">Debasish</a> was awesome fun. Can&#8217;t wait to do something similar next year during Scala days. James, we&#8217;re still waiting for &#8220;scala minus minus&#8221; <img src='http://blog.getintheloop.eu/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>


	<p><img src="http://blog.getintheloop.eu/wp-content/uploads/2011/12/3.jpg" alt="" /></p>


	<h5>California Route 1: Pacific Highway</h5>


	<p>For anyone who&#8217;s been reading this blog over the past years, you may recall that last year I was stranded in mainland Europe during the volcano eruption whilst attending ScalaDays 2010. After rounding up a bunch of stranded folks for dinner, I ended up meeting <a href="http://twitter.com/jteigen">Jon-Anders</a> &#8211; making a long story short, we became good friends and one day decided that what we should do is drive the length of the pacific highway in a convertible Mustang. After a hastily organised flight to america we were all set. What ensued was an utterly hilarious time away where we had arranged nothing in advance and just took things as they came. From huge trees in Redwood country&#8230;</p>


	<p><img src="http://blog.getintheloop.eu/wp-content/uploads/2011/12/4a.jpg" alt="" /></p>


	<p>&#8230;to the winding roads and stunning coastline of BigSur and southern california:</p>


	<p><img src="http://blog.getintheloop.eu/wp-content/uploads/2011/12/4f.jpg" alt="" /></p>


	<p>The trip was a complete riot and finishing it off with spending time at Xerox <span class="caps">PARC</span> was a real high for me. It was literally like walking the halls of technology fame.</p>


	<h5>Early Summer Thistles</h5>


	<p>Getting back from Cali was somewhat of a come down, but I often go for hikes in and around where I live and was out one day and noticed a small set of thistles just growing on this open exposed hill face. Pretty nice, especially with the city backdrop.</p>


	<p><img src="http://blog.getintheloop.eu/wp-content/uploads/2011/12/5.jpg" alt="" /></p>


	<h5>Canada, Up-state New York and Niagara Falls.</h5>


	<p>In summer I was sent to Canada for a meeting (technically just across the boarder in Upstate New York) but this was a pretty awesome experience. Having booked a &#8220;Small European Saloon Car&#8221; before traveling, me and my colleague were surprised to be presented with a 4.0 litre land cruiser. Clearly &#8220;small&#8221; has some definition in Canada that i&#8217;m not familiar with. Anyway&#8230; it was fun to drive around in a <del>tank</del> truck for a few days and enjoy the delights of Toronto and New York scenery:</p>


	<p><img src="http://blog.getintheloop.eu/wp-content/uploads/2011/12/6b.jpg" alt="" /></p>


	<p><img src="http://blog.getintheloop.eu/wp-content/uploads/2011/12/6.jpg" alt="" /></p>


	<p>Of course, being in the area it only made sense to swing by Niagara falls on the way back to the airport. It was my first time here and damn, it&#8217;s far, far bigger than you might imagine. It really is a stunning natural spectacle.</p>


	<p><img src="http://blog.getintheloop.eu/wp-content/uploads/2011/12/niagra.jpg" alt="" /></p>


	<h5>End of Summer: Harvest Time</h5>


	<p>Back in England for the end of the summer is yet another lovely time. The UK was drenched in sunshine for the last few days (weeks?) of August which meant all the farms nearby were busy making the most harvesting their crops and preparing the land for winter. Being out on a walk I picked up this picture just after the field had been harvested:</p>


	<p><img src="http://blog.getintheloop.eu/wp-content/uploads/2011/12/harvest-time.jpg" alt="" /></p>


	<h5>JavaZone and M.I.T Arctic</h5>


	<p>Come September it was time once again for the most awesome conference of the yearly calendar: <a href="javazone.no">JavaZone</a>! I love this conference; its always well organised, has great talks and really wicked parties. This year was no exception to that rule and proved to again be most excellent. This year we were also joined by some of our <a href="http://twitter.com/rit">american</a> <a href="twitter.com/djspiewak">friends</a>, which just added to the delight. Following the conference, some of us head north from Oslo to the M.I.T Arctic lab for a few days of geekery and walking in the tundra. This was a really special highlight of the year and felt like a somewhat magical trip for everyone. Here&#8217;s a small sample of what we got up too (not all pictures taken by me, credits where credit appropriate):</p>


	<p><img src="http://blog.getintheloop.eu/wp-content/uploads/2011/12/8d.jpg" alt="" />
<em>(photo credit: Andreas Røe)</em></p>


	<p><img src="http://blog.getintheloop.eu/wp-content/uploads/2011/12/mit-cabins.jpg" alt="" />
<em>(photo credit: Andreas Røe)</em></p>


	<p>And don&#8217;t forget the somewhat successful fishing in the fjords!!</p>


	<p><img src="http://blog.getintheloop.eu/wp-content/uploads/2011/12/IMG_1074.jpg" alt="" /></p>


	<p>It really was an amazing trip. If you&#8217;ve never visited Norway, you should, its a stunning country.</p>


	<h5>Lift in Action goes to production</h5>


	<p>So we&#8217;re nearly at the end of the year, so I should really mention Lift in Action going to print. This was a huge, huge milestone for me personally and concluded a two year unit of work. I should also mention that during the writing of this blog post I had originally neglected to even mention the book and that a friend had to remind me to mention it&#8230; I&#8217;m sure the psychologists would have something to say about that, but anyway!&#8230;</p>


	<p><img src="http://blog.getintheloop.eu/wp-content/uploads/2011/12/lift-in-action-complete.jpg" alt="" /></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.getintheloop.eu/2011/12/17/the-year-in-photos-2011/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Documenting the Difficulties of Documentation</title>
		<link>http://blog.getintheloop.eu/2011/12/11/documenting-the-difficulties-of-documentation/</link>
		<comments>http://blog.getintheloop.eu/2011/12/11/documenting-the-difficulties-of-documentation/#comments</comments>
		<pubDate>Sun, 11 Dec 2011 20:11:50 +0000</pubDate>
		<dc:creator>timperrett</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[documentation]]></category>
		<category><![CDATA[OpenSource]]></category>
		<category><![CDATA[Scala]]></category>

		<guid isPermaLink="false">http://blog.getintheloop.eu/?p=1170</guid>
		<description><![CDATA[Over the years i&#8217;ve been involved in a wide-range of diverse open source projects. Some large. Some small. Some very obscure. But every single one has at one point or another, had a &#8220;problem&#8221; with documentation. Many of you reading this will no doubt have had a similar experience at some point in your programming [...]]]></description>
			<content:encoded><![CDATA[	<p>Over the years i&#8217;ve been involved in a wide-range of diverse open source projects. Some large. Some small. Some very obscure. But every single one has at one point or another, had a &#8220;problem&#8221; with documentation. Many of you reading this will no doubt have had a similar experience at some point in your programming career. Perhaps you were a project creator wondering how best to communicate the inherent awesome of something you&#8217;ve just created, or perhaps you were that eager n00b trying to get to grips with some new technology you came across on <a href="https://github.com/">github</a> &#8211; in either case, you have to create or consume &#8220;documentation&#8221;.</p>


	<p>Now then, before we go any further I do have somewhat of a problem with the overloaded meaning of the term &#8220;documentation&#8221;. The widely accepted definition of documentation is the following:</p>


	<blockquote>
		<p><strong>Doc&middot;u&middot;men&middot;ta&middot;tion</strong> <em>noun</em> &#8211; Material that provides official information or evidence or that serves as a record.</p>
	</blockquote>


	<p>Evidence that serves as a record? That sounds awfully vague doesn&#8217;t it. I&#8217;d like to suggest that this is, to all intent purposes, <em>too</em> vague. More specifically it is often an ambiguous umbrella term for what people are actually referring too. It&#8217;s this ambiguity that causes all manner of problems for software projects and their (would-be)users.</p>


	<h2>Disambiguating Documentation Components</h2>


	<p>There are many excellent projects in the Scala ecosystem, and many suffer this apparent &#8220;lack of documentation&#8221;. Curiously though, each project seems to suffer this affliction in its own specific way&#8230; at least, this is often what you might witness on the mailing-list of any project you might care to pick at random. Most projects have some thread or other in the archives of their mailing lists where someone has complained about their documentation, or distinct lack of whatever it is they were looking for.</p>


	<p>With this in mind, i&#8217;d like to now illustrate what I think are the key aspects of the wider &#8220;documentation problem&#8221;, and disambiguate their respective intentions.</p>


	<h5>Tutorials and Introductions</h5>


	<p>The first thrust of documentation i&#8217;d like to define is that all-important introductory material people will need when coming to your project in the first instance. This is quite probably the most difficult type of text to write, particularly if the subject matter is highly technical in nature. It&#8217;s typically difficult for the following three reasons:</p>


	<ul>
	<li><strong>Assumptions</strong> &#8211; Assuming the reader fully understands a topic, line of code, operator or anything else must be one of the most common issues. In introductory texts and tutorials its highly likely that the reader will not be in possession of the implicit knowledge that&#8217;s relevant to properly grok the topic at hand.</li>
		<li><strong>Accessibility</strong> &#8211; &#8220;Joe Developer&#8221; can initially be easily scared by large words, complex-sounding terms that originate from academic theories, and terse writing styles. It is so vitally important that your tutorials and introduction texts are <em>accessible</em>. For the most part this may well mean that you have to sweep over some of the finer details, or forego some more abstract possibilities in order to effectively get the point across to newcomers. Ironically, it is often this simplification or frivolity with the facts that programmers struggle with when taking up the pen (ok &#8211; keyboard, but you know what I mean).</li>
		<li><strong>Authorship</strong> &#8211; Writing is hard. Be honest with yourself and recognise that you may not be any good at it. During the writing of Lift in Action I had to throw away a whole bunch of manuscript which was either too technical or just plain rubbish. Having a professional team of editors who could help me (re)learn about writing was really key&#8230; but i&#8217;m aware that this is hardly practical for the common case. The fact is that most of us have not written long documents since high-school or college, and it is <em>incredibly difficult</em>. Don&#8217;t forget this when writing your project introduction and tutorials &#8211; if you can&#8217;t do it the proper justice it deserves, then embrace the fact that us humans all have different skills and find someone who can plug the required gaps. Having your texts reviewed honestly by your peers is also another useful strategy to ensure what you&#8217;re writing is actually any good.</li>
	</ul>


	<h5>Examples and Explanations</h5>


	<p>The second branch of the documentation umbrella is somewhat of an extension to the first, but I decided to make it separate because its use-case feels distinctly different. With this in mind i&#8217;ll add the caveat that yes, examples often form parts of tutorials (and later, references), but in and of themselves you wouldn&#8217;t use verbose introductory-style writing <em>within</em> an example. In my mind at least, the primary difference is that example/explanatory documentation is tightly coupled with the code to which it relates. That is to say that the text is more often than not sitting next to the code itself in the comments, which usually means there are certain conventions to follow with regard to syntax and so forth (e.g. ScalaDoc, Wiki markup etc). Critically though, the tone of voice in the explanatory text when compared to that of the introductory &#38; tutorial manuscripts is much shorter, more concise and really focusing on the line-by-line, blow-by-blow goings on of the code. More generally, its reasonable to suggest that examples are about illustrating concepts, and this is where the writing style really differentiates itself from the other branches listed in this article.</p>


	<p>Finally, if you&#8217;re going to go to the trouble of writing examples and explanations, <em>make sure the code actually works</em>! Nothing is more frustrating to find an example that simply does not do what it should because the code either doesn&#8217;t compile or doesn&#8217;t run correctly.</p>


	<h5>Reference materials</h5>


	<p>Reference material is your last line of defence before forcing users to delve into the source code. Consider the type of person might be using a reference, or what their goal might be? I&#8217;d propose that when someone is looking at a reference, they know what they are looking for: they need something specific. It&#8217;s probably also fair to assume that before arriving at the reference they will have read tutorials and examples, so there is a degree of implied understanding. Reference materials are usually heavy on details and light on fluffy writing style, which allows the author to be far more technical, and satisfy the aforementioned need for presenting the exact facts.</p>

<p>Unlike the other aspects of documentation writing, references can have the tendency to become quite large; even for mid-sized projects. With this in mind you should take care to refactor the organisation and layout of the reference with each major change and strives for a reference that is logically ordered and consistent throughout. If your reference is massive, then you should seriously consider having a decent search function in addition to a logical layout. </p>

	<h5>Source Code</h5>


	<p>Your last line of documentation defence is the source code. That might seem odd, as i&#8217;m not talking about comments or ScalaDoc (or similar in your language of choice). I&#8217;m talking about types (sorry dynamically typed people!). Type annotations can be extremely useful when reading code and concisely communicating the result or intention of a particular item. With Scala for example, consider these two lines:</p>


<pre><code>
  // actual code irrelevant
  val foo = whatever.map(...).flatMap(...).foldLeft(...).map(...)
  val foo: Option[Int] = whatever.map(...).flatMap(...).foldLeft(...).map(...)
</code></pre>

	<p>Having the simple type annotation frees me from having to mull over the code in order to understand its result; its right there in the type annotation. When moving code between teams, or people, having the ability to simple scan complex blocks of code and understand it is a huge win (IMHO). Sure, make use of type inference where the value is obvious (e.g. simple assignment etc), but where you think something might not be directly understood explicitly annotating can serve as effective documentation.</p>


	<p>&#8230;In any case, writing readable and well documented code could easily be the subject of a whole other blog post (or indeed, <a href="http://infoscience.epfl.ch/record/138586/files/dubochet2009coco.pdf?version=2">academic paper</a>), so we&#8217;ll put a pin in that subject and move swiftly along&#8230;</p>


	<p>In my mind at least, when your general users complain about documentation, they are typically complaining about one of first three branches of this documentation umbrella.</p>


	<h2>Isn&#8217;t all this a lot of work?</h2>


	<p>I won&#8217;t lie to you, good reader: this will take a lot of time and dedication to do. To do it <em>well</em>, will take more time and a fuckton more effort. However, if you want your software or project to be used by people other than yourself, then it is imperative the documentation is well structured, and exhibiting some &#8211; if not most &#8211; of the traits in this article. It&#8217;s also important that you realise that it will, in all likelihood, be &#8220;expensive&#8221; in terms of time; this is nearly unavoidable, but it will make your project more approachable and more usable.</p>


	<p>Interestingly one thing that you often see are projects that try to distill the documentation effort by promoting community authorship, which when considering what a social activity programming has become in recent times, does not seem like such a crazy idea. The reality however is somewhat different to the ideal: people are often keen to submit bugs and patches, but those same keen people are still typically reluctant to contribute documentation. One could speculate that writing documentation was too tedious, or that perhaps it was not as fun as doing the coding and people didn&#8217;t want to spend time in that area&#8230; the reason is actually irrelevant, as the result is always the same: without a small core of dedicated people who write, maintain and constantly improve that wiki <em>the whole documentation effort will fail</em>. To qualify that, i&#8217;m not saying that community-powered documentation <em>never</em> works, as that clearly isn&#8217;t the case. I am however suggesting that by-and-large for most communities it simply does not operate effectively, and this has an overall negative impact on the project as a whole.</p>


	<h2>Who&#8217;s doing it right?</h2>


	<p>I&#8217;m not going to gratify this article with pointing out projects that are &#8220;doing it wrong&#8221;, as frankly most projects are making a hash of their documentation; irrespective of language or community. I do however want to highlight a couple of projects that are setting an excellent example:</p>


	<ul>
	<li><strong>Akka</strong> &#8211; The Akka team are making a superb job of documenting their project, even with extensive changes to the codebase they are very effective when it comes to ensuring the docs are up-to-date and covering all new or refactored features. The documentation is nearly exclusively maintained by the core team of programmers.</li>
	</ul>


	<ul>
	<li><strong>JQuery</strong> &#8211; Very different to Akka, and in a different community, JQuery has been very effective in delivering core reference materials that allow (and encourage) the wider community to write tutorials, introductions and other helpful articles. JQuery also makes extensive use of illustrative examples, and its good documentation is probably one of the reasons for its apparent ubiquity on the web today.</li>
	</ul>


	<p>Both of these projects exhibit dedication on the part of the coders, who are typically the ones authoring the core reference materials and bulk of the ancillary texts. Learn from these projects and others like them. We can all do a better job of documenting our projects, myself included. Say no to undocumented projects, and the next time you&#8217;re throwing something on github, take the time to write some documentation&#8230; even if its a long <span class="caps">README</span> people will thank you for it.</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.getintheloop.eu/2011/12/11/documenting-the-difficulties-of-documentation/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Lift in Action Finally Completed</title>
		<link>http://blog.getintheloop.eu/2011/11/06/lift-in-action-finally-completed/</link>
		<comments>http://blog.getintheloop.eu/2011/11/06/lift-in-action-finally-completed/#comments</comments>
		<pubDate>Sun, 06 Nov 2011 17:10:14 +0000</pubDate>
		<dc:creator>timperrett</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.getintheloop.eu/?p=1163</guid>
		<description><![CDATA[So here we are. The end finally happened. Lift in Action was sent to print last week, representing the conclusion of 20 months of work. Without doubt this has been one of the largest and most difficult projects i&#8217;ve ever undertaken. With this in mind I wanted to thank everyone who read the MEAP edition, [...]]]></description>
			<content:encoded><![CDATA[<p>So here we are. The end finally happened. Lift in Action was sent to print last week, representing the conclusion of 20 months of work. Without doubt this has been one of the largest and most difficult projects i&#8217;ve ever undertaken. With this in mind I wanted to thank everyone who read the <span class="caps">MEAP </span>edition, contributed fixes, asked questions, issued pull requests and everyone who generally helped me with the project! Without your input the book wouldn&#8217;t be what it is, and I hope that it serves to be a useful reference for learning and making the most of Lift.</p>

<p>The print copies should be coming out in a week or so and depending where you purchased, your copy should be arriving in the coming weeks.</p>

<p>Thanks again for all the support and kind words during the writing; i&#8217;m now looking forward to getting my life back! <img src='http://blog.getintheloop.eu/wp-includes/images/smilies/icon_biggrin.gif' alt=':-D' class='wp-smiley' /> </p>]]></content:encoded>
			<wfw:commentRss>http://blog.getintheloop.eu/2011/11/06/lift-in-action-finally-completed/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Using Apache Shiro with Lift</title>
		<link>http://blog.getintheloop.eu/2011/08/23/using-apache-shiro-with-lift/</link>
		<comments>http://blog.getintheloop.eu/2011/08/23/using-apache-shiro-with-lift/#comments</comments>
		<pubDate>Tue, 23 Aug 2011 14:42:24 +0000</pubDate>
		<dc:creator>timperrett</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Technology]]></category>

		<guid isPermaLink="false">http://blog.getintheloop.eu/?p=1154</guid>
		<description><![CDATA[As it stands, Lift only has its proto* traits for user management, and that system has its limitations and you will ultimately end up replacing it in any non-trivial application as your needs change and you need to grow. Whilst this is what those traits are designed for (quick start, short haul), you typically end [...]]]></description>
			<content:encoded><![CDATA[<p>As it stands, Lift only has its proto* traits for user management, and that system has its limitations and you will ultimately end up replacing it in any non-trivial application as your needs change and you need to grow. Whilst this is what those traits are designed for (quick start, short haul), you typically end up rolling your own system for users etc when using Lift, and this can often be somewhat cumbersome or not particularly easy to do well. As this whole user management piece is so often requested, I figured that i&#8217;d write a plugin library for Lift.</p>

<p><a href="http://shiro.apache.org/">Apache Shiro</a> is a Java security framework (formally known as JSecurity) and it comes with a fairly abstract set of classes for building systems that have the familiar users, roles and permissions setup. Pretty much most applications these days have some notion of users, customers or some other subject that you care about and might want to conduct access control around. This is exactly what Shiro is designed for, and it ships with out of the box inter-operation with ActiveDirectory and other such repositories commonly found in the enterprise space for managing user data. </p>

<p>Part of the reason that other security frameworks never really took to Lift (or vice-versa) is that Lift has its own mech for managing resource <span class="caps">ACL</span>s and it never made sense to separate that into a different servlet filter and somehow munge that together: its not 1990. Fortunately Shiro was fairly easy to integrate with Lift in such a way that it allows you to simply augment your existing SiteMap setup, template markup and even dispatch resources. Currently this integration project is in early stages, and you can find the source code here: <a href="https://github.com/timperrett/lift-shiro">github.com/timperrett/lift-shiro</a></p>

<h2>Example</h2>

<p>Here&#8217;s a quick walkthrough of the various ways you can use the integration within your project. Firstly, lets assume you only want to display a section of content to authenticated users: </p>



<pre><code>
  &lt;lift:has_role name=&quot;admin&quot;&gt;
    &lt;p&gt;This content is only available for admins&lt;/p&gt;
  &lt;/lift:has_role&gt;
</code></pre>



<p>There are a range of authentication snippets that allow you to define who sees what within your templates, checkout the documentation for more on that. Nextup, what if you want to block access to an page entirely if the user is not authenticated? Just add the following to your SiteMap:</p>



<pre><code>...
Menu(&quot;Home&quot;) / &quot;index&quot; &gt;&gt; RequireAuthentication
...
</code></pre>



<p>By default <code>RequireAuthentication</code> will redirect unauthenticated users back to the <span class="caps">URL </span>defined in <code>Shiro.loginURL</code>. Likewise, you can specify whole resources to require a particular role or permission:</p>



<pre><code>...
Menu(&quot;Role Test&quot;) / &quot;restricted&quot; &gt;&gt; RequireAuthentication &gt;&gt; HasRole(&quot;admin&quot;)
...
</code></pre>



<p>Clearly the SiteMap functionality is implemented as <code>LocParam</code>, so you can implement them within your own Loc types, or simply use them declaratively within the regular SiteMap usage.</p>

<p>This whole integration project wraps the Shiro types, so you only need to configure shiro.ini in the root of your classpath and enter the appropriate realm information as per the regular Shiro documentation, then away you go: password files&#8230; active directory&#8230; whatever you want. </p>

<p>As above, this project is still early stage, but it does indeed work. I&#8217;m currently looking for feedback, so if you have some thoughts or things that would be cool to see, then please checkout the project on Github and fork away. </p>

<p> </p>]]></content:encoded>
			<wfw:commentRss>http://blog.getintheloop.eu/2011/08/23/using-apache-shiro-with-lift/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>System Scripting with Scala</title>
		<link>http://blog.getintheloop.eu/2011/08/01/system-scripting-with-scala/</link>
		<comments>http://blog.getintheloop.eu/2011/08/01/system-scripting-with-scala/#comments</comments>
		<pubDate>Mon, 01 Aug 2011 13:46:07 +0000</pubDate>
		<dc:creator>timperrett</dc:creator>
				<category><![CDATA[Hacks]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[Scala]]></category>
		<category><![CDATA[scripting]]></category>

		<guid isPermaLink="false">http://blog.getintheloop.eu/?p=1143</guid>
		<description><![CDATA[For the longest time I have used Ruby as my pocket knife for system scripting&#8230; you know, just knocking up small little executable files that run helpful tasks or automate yawnful processes. I like Ruby for this kind of thing and it works. Recently a coworker in marketing wanted some automation for something relatively simple [...]]]></description>
			<content:encoded><![CDATA[<p>For the longest time I have used Ruby as my pocket knife for system scripting&#8230; you know, just knocking up small little executable files that run helpful tasks or automate yawnful processes. I like Ruby for this kind of thing and it works. Recently a coworker in marketing wanted some automation for something relatively simple and instead of using Ruby I thought i&#8217;d just knock it together with Scala and in doing so I came across a neat little thing with the Scala scripting support. </p>

<p>Assuming you have Scala installed, you can execute bash statements and pass them directly to your Scala code. This can be pretty handy as there are certain things that are particularly annoying to do from Scala (and more broadly with Java) like finding out where exactly you are executing too on the file system. Often if you use the good ol&#8217; protection domain trick it will give you a location in /var/tmp, as opposed to the <b>real</b> location of the script. Consider the following:</p>



<pre><code>
#!/bin/sh
SCRIPT=&quot;$(cd &quot;${0%/*}&quot; 2&gt;/dev/null; echo &quot;$PWD&quot;/&quot;${0##*/}&quot;)&quot;
DIR=`dirname &quot;${SCRIPT}&quot;}`
exec scala $0 $DIR $SCRIPT
::!#

import java.io.File

object App {
  def main(args: Array[String]): Unit = {
    val Array(directory,script) = args.map(new File(_).getAbsolutePath)
    println(&quot;Executing '%s' in directory '%s'&quot;.format(script, directory))
  }
}

</code></pre>



<p>Notice the base code between <code>#!/bin/sh</code> and <code>::!#</code>. This allows you to execute bash script (or whatever script you want) before evaluating this file as a Scala script. This can be pretty handy for certain tasks when doing system scripting <img src='http://blog.getintheloop.eu/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  </p>

<p>Assume you saved this file as &#8220;thing&#8221;, you can then execute it like any other script: <code>./thing</code></p>

<p>Enjoy. </p>]]></content:encoded>
			<wfw:commentRss>http://blog.getintheloop.eu/2011/08/01/system-scripting-with-scala/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>Using SOAP with Scala</title>
		<link>http://blog.getintheloop.eu/2011/07/26/using-soap-with-scala/</link>
		<comments>http://blog.getintheloop.eu/2011/07/26/using-soap-with-scala/#comments</comments>
		<pubDate>Tue, 26 Jul 2011 12:44:14 +0000</pubDate>
		<dc:creator>timperrett</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Scala]]></category>
		<category><![CDATA[SOAP]]></category>
		<category><![CDATA[Web Services]]></category>

		<guid isPermaLink="false">http://blog.getintheloop.eu/?p=1125</guid>
		<description><![CDATA[It seems I have inadvertently become &#8220;that guy who does SOAP with Scala&#8221;. Given this illustrious position it seemed prudent to get around to putting up an article that explains how to use the SOAP support now present in Scalaxb. Scalaxb is a nice tool for working with XSD Schema from Scala, and recently WSDL [...]]]></description>
			<content:encoded><![CDATA[<p>It seems I have inadvertently become &#8220;that guy who does <span class="caps">SOAP </span>with Scala&#8221;. Given this illustrious position it seemed prudent to get around to putting up an article that explains how to use the <span class="caps">SOAP </span>support now present in <a href="http://scalaxb.org/">Scalaxb</a>.</p>

<p>Scalaxb is a nice tool for working with <span class="caps">XSD</span> Schema from Scala, and recently <span class="caps">WSDL </span>support was added. In short this means that you can use native Scala types (such as Option[T]) for interacting with <span class="caps">SOAP </span>methods. </p>

<h2>Prerequisites</h2>

<p>Before you get going, its necessary to install Scalaxb, which itself requires <a href="https://github.com/n8han/conscript/">Conscript</a>, so install that first. With ConScript in place, install Scalaxb by running:</p>



<pre>
cs eed3si9n/scalaxb
</pre>



<p>This will install Scalaxb and make it available on your $PATH. You can verify this by running the <code>scalaxb</code> command. </p>

<h2>Generating Contracts</h2>

<p>With Scalaxb installed and your <span class="caps">WSDL </span>to hand, you can run something like: </p>



<pre>
scalaxb -p eu.getintheloop.sample \ 
        -d src/main/scala \
        src/main/wsdl/weather.wsdl
</pre>



<p>This will generate a range of .scala files pertaining to the <span class="caps">WSDL </span>contract you passed as the last argument to the scalaxb tool. In addition this sample includes the <code>-p</code> to specify your own package and also the <code>-d</code> argument to place the output files into my Scala source directory. In this particular case, I&#8217;m using <a href="http://www.deeptraining.com/webservices/weather.asmx?wsdl">this <span class="caps">SOAP </span>endpoint</a>, and you can freely do so too for the sake of this example.</p>

<h2>Understanding Generated Classes</h2>

<p>Scalaxb generates three separate components: </p>


<ul>
<li><strong><span class="caps">SOAP </span>protocol classes</strong>: These are the ancillary classes that are used to operate the <span class="caps">SOAP </span>protocol for things like the message envelope. </li>
<li><strong>Default transport implementation</strong>: The <span class="caps">HTTP </span>driver to actually <span class="caps">POST </span>the <span class="caps">SOAP </span>message to the endpoint <span class="caps">URI.</span> This default implementation is based on the blocking <span class="caps">HTTP </span><a href="http://dispatch.databinder.net/Dispatch.html">Scala Dispatch</a> </li>
<li><strong>Your service contracts</strong>: This is the only service specific part of the generated files. These relate to your specific service whilst the other two parts are completely decoupled and reusable over implementations / services you might have. </li>
</ul>



<p>Enough talking, lets look at some code. </p>

<h2>Usage</h2>

<p>The Scalaxb <span class="caps">SOAP </span>mechanism makes heavy use of the cake pattern, and thus allows you to mix and match different components as your situation dictates. Here&#8217;s the default usage pattern:</p>



<pre>
package eu.getintheloop.sample

import scalaxb._

object Main {
  def main(args: Array[String]){
    
    val remote = new WeatherSoap12s 
       with SoapClients 
       with DispatchHttpClients {}
    
    println {
      remote.service.getWeather(Some(&quot;New York&quot;))
    }
  }
}
</pre>



<p>Note specifically that by combining the weather service contracts with the <span class="caps">SOAP </span>protocol classes and the transport implementation, the result is a working driver from which you can directly call the <span class="caps">SOAP </span>methods.</p>

<p>The result of the service call itself is a <code>Either[Fault[_], Option[T]]</code>, so if you want to get at the actual value you can just simply <code>fold</code> on the Either.</p>

<h2>Suggestions for Customisation</h2>

<p>If you have multiple services to interact with then it can be nice to cake together all your service implementations so that you just have a single client that lazily loads the appropriate service classes as needed. Additionally, you could also replace the transport implementation with something asynchronous and based on futures&#8230; that also is fun. </p>

<p>The sample code for this example can be found at: <a href="https://github.com/timperrett/scalaxb-soap-example">https://github.com/timperrett/scalaxb-soap-example</a></p>

<p>Enjoy.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.getintheloop.eu/2011/07/26/using-soap-with-scala/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Running SproutCore from within Lift</title>
		<link>http://blog.getintheloop.eu/2011/05/25/running-sproutcore-from-within-lift/</link>
		<comments>http://blog.getintheloop.eu/2011/05/25/running-sproutcore-from-within-lift/#comments</comments>
		<pubDate>Wed, 25 May 2011 08:13:21 +0000</pubDate>
		<dc:creator>timperrett</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.getintheloop.eu/?p=1087</guid>
		<description><![CDATA[If you want to run SproutCore from within your Lift application there are a couple of configurations you need to ensure you apply within your Boot.scala in order to actually make it work as you might anticipate. Firstly you need to ensure you set the HTML parser to use HTML5 and not XHTML, otherwise your [...]]]></description>
			<content:encoded><![CDATA[<p>If you want to run <a href="http://sproutcore.com">SproutCore</a> from within your Lift application there are a couple of configurations you need to ensure you apply within your Boot.scala in order to actually make it work as you might anticipate.</p>

<p>Firstly you need to ensure you set the <span class="caps">HTML </span>parser to use <span class="caps">HTML5 </span>and not <span class="caps">XHTML, </span>otherwise your templates will explode in extraordinary fashion when using the built template file as created by SproutCore build tools:</p>



<pre><code>LiftRules.htmlProperties.default.set((r: Req) =&gt; 
  new Html5Properties(r.userAgent))
</code></pre>



<p>With that in place you need to do the equivalent of implementing a symlink for those setups that use the filesystem (a la <span class="caps">PHP,</span> Rails etc). Within Lift this is accomplished by using a stateless rewrite:</p>



<pre><code>LiftRules.statelessRewrite.append {
  case RewriteRequest(ParsePath(&quot;index&quot; :: Nil, &quot;&quot;, true, false),_,_) =&gt; {
       RewriteResponse(&quot;static&quot; :: &quot;todos&quot; :: &quot;en&quot; :: &quot;1.0&quot; :: &quot;index&quot; :: Nil)
  }
}
</code></pre>



<p>This code tells Lift to rewrite the root path (/) to /static/todos/en/<buildnumber>/index template. Also be sure to implement your SiteMap so that only / is accessible and not the full (direct) SproutCore template path. If I do much more stuff with SproutCore I may well end up making an <span class="caps">SBT </span>plugin that automatically builds the updated JS files and copies them to your src/main/webapp path&#8230; not sure yet, we&#8217;ll see. Eitherway, the rewriting is certainly a good candidate for stuffing into a LocParam and making it reusable based upon some project configuration. For example:</p>



<pre><code>Menu(&quot;Home&quot;) / &quot;index&quot; &lt;&lt; UsesSproutCore </code></pre>



<p>For more information like this checkout my book on Lift launching this quarter on Manning Publications.</p>]]></content:encoded>
			<wfw:commentRss>http://blog.getintheloop.eu/2011/05/25/running-sproutcore-from-within-lift/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>SBT gets CloudBees support (and fast deploys!)</title>
		<link>http://blog.getintheloop.eu/2011/04/19/sbt-gets-cloudbees-support-and-fast-deploys/</link>
		<comments>http://blog.getintheloop.eu/2011/04/19/sbt-gets-cloudbees-support-and-fast-deploys/#comments</comments>
		<pubDate>Tue, 19 Apr 2011 09:33:13 +0000</pubDate>
		<dc:creator>timperrett</dc:creator>
				<category><![CDATA[Programming]]></category>
		<category><![CDATA[Technology]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Lift]]></category>
		<category><![CDATA[SBT]]></category>
		<category><![CDATA[Scala]]></category>
		<category><![CDATA[Web Services]]></category>

		<guid isPermaLink="false">http://blog.getintheloop.eu/?p=1078</guid>
		<description><![CDATA[About 18 months ago a company came out of nowhere called Stax Networks who were offering the ability to host JVM-based applications in the cloud, for FREE. This was too awesome not to look into and I subsequently made a plugin for SBT that automatically deployed your WAR files with a simple command. Stax themselves [...]]]></description>
			<content:encoded><![CDATA[<p>About 18 months ago a company came out of nowhere called Stax Networks who were offering the ability to host <span class="caps">JVM</span>-based applications in the cloud, for <span class="caps">FREE.</span> This was too awesome not to look into and I subsequently made a plugin for <span class="caps">SBT </span>that automatically deployed your <span class="caps">WAR </span>files with a simple command. </p>

<p>Stax themselves were recently taken over by <a href="http://www.cloudbees.com">CloudBees</a> and from what I can see the service has done nothing but become more awesome since that has happened. Now that take over is bedding in, the <span class="caps">API </span>has changed somewhat so I thought i&#8217;d rewrite my Stax plugin to work with CloudBees instead and take advantage of the ability to delta <span class="caps">WAR </span>files and only publish the updates. </p>

<h3>Speedy Deploys</h3>

<p>The way this works is the build tool creates a <span class="caps">WAR </span>file like it would do normally, but as this is usually fairly large it can be exceedingly annoying to have to keep waiting for the deployment to take place. Rather than wait, the build tool calculates the difference between the deployed artefact and the one you just created, and subsequently only deploys the difference (or delta): essentially reducing your deploy time from 15 mins or more to a few seconds.</p>

<h3>Gimmeh It</h3>

<p>In order to get started with using the <span class="caps">SBT </span>plugin, you will of course need a CloudBees account and upon registering you need to grab the key and secret from grandcentral.cloudbees.com, which should look something like:<br />
<img src="https://github.com/timperrett/sbt-cloudbees-plugin/raw/master/notes/img/beehive-keys.jpg" alt="" /></p>

<p>These values represent the <span class="caps">API</span> Key and <span class="caps">API</span> Secret that CloudBees will use to verify your deployment rights. Once you have these two values, you can do one of two things in order to have them recognised by the <span class="caps">SBT</span>:</p>


<ul>
<li>Enter them when the plugin prompts you; this will be on everytime you run a deployment to the cloud so is potentially a little sub-optiomal.</li>
<li>Create the properties file $HOME/.bees/bees.config so that you only need to define them once per computer. This properties file needs to be a key-value pair which should look something like this:</li>
</ul>





<pre><code>bees.api.key=XXXXXXXXXX
bees.api.secret=XXXXXXXXXXXXXXXXXXXXXXXXXXXXX=
</code></pre>



<p>Whichever route you choose to specify that information, you then only need to define the plugin information in any given project. Specifically, in the Plugins.scala file define the following:</p>



<pre><code>  import sbt._
  class Plugins(info: ProjectInfo) extends PluginDefinition(info) {
    lazy val cloudbees = &quot;eu.getintheloop&quot; % &quot;sbt-cloudbees-plugin&quot; % &quot;0.2.7&quot;
    lazy val sonatypeRepo = &quot;sonatype.repo&quot; 
      at &quot;https://oss.sonatype.org/content/groups/public&quot;
  }
</code></pre>


<p> <br />
Add the plugin to your <span class="caps">SBT </span>project like so:</p>



<pre><code>  import sbt._
  class YourProject(info: ProjectInfo) extends DefaultWebProject(info) 
    with bees.RunCloudPlugin {
    ....
    override def beesUsername = Some(&quot;youruser&quot;)
    override def beesApplicationId = Some(&quot;whatever&quot;)
  }
</code></pre>



<p>Again, if you would prefer to enter these values when you deploy your application then you can of course just enter the appropriate values when prompted. Now your all configured and good to go, there are two commands you can run with this plugin:</p>


<ul>
<li>Get a list of your configured applications: <code>bees-applist</code></li>
<li>Deploy your application <code>bees-deploy</code></li>
</ul>



<p>Upon running  <code>bees-deploy</code> for the first time there will of course be a wait whilst the first version is deployed, but all your subsequent deployments should be much, much quicker. CloudBees is a rather awesome service and i&#8217;d highly recommend checking it out for fast, easy deployment of your <span class="caps">JVM </span>web applications. </p>

<p>Find the source code for the CloudBees <span class="caps">SBT </span>plugin <a href="https://github.com/timperrett/sbt-cloudbees-plugin">here</a></p>


<p> </p>]]></content:encoded>
			<wfw:commentRss>http://blog.getintheloop.eu/2011/04/19/sbt-gets-cloudbees-support-and-fast-deploys/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
		<item>
		<title>Color: You Are Your Device</title>
		<link>http://blog.getintheloop.eu/2011/04/18/color-you-are-your-device/</link>
		<comments>http://blog.getintheloop.eu/2011/04/18/color-you-are-your-device/#comments</comments>
		<pubDate>Mon, 18 Apr 2011 13:23:53 +0000</pubDate>
		<dc:creator>timperrett</dc:creator>
				<category><![CDATA[Personal]]></category>

		<guid isPermaLink="false">http://blog.getintheloop.eu/?p=1070</guid>
		<description><![CDATA[Disclaimer: This is mostly a rant. If you&#8217;ve been living in a cave for the past months, you may not have seen Colour. These guys raised $41m in investment which in and of itself is seriously impressive. After that hit the headlines, I decided that just like everyone else i&#8217;d grab me a chilled bottle [...]]]></description>
			<content:encoded><![CDATA[<p>Disclaimer: This is mostly a rant. </p>

<p>If you&#8217;ve been living in a cave for the past months, you may not have seen <a href="http://www.color.com/">Colour</a>. These guys <a href="http://www.businessinsider.com/color-deal-2011-3">raised $41m in investment</a> which in and of itself is seriously impressive. After that hit the headlines, I decided that just like everyone else i&#8217;d grab me a chilled bottle of tech koolade and try it out. </p>

<p>Now, I want to say here that my first impression of Colour was, well, underwhelming. When you&#8217;re alone, its useless. However, when you&#8217;re at an event, or gig, or somewhere else with a number of other people it was actually pretty awesome. Being able to collect a whole set of photos and events from a range of vantage points was quite awesome&#8230; It&#8217;s like event snaps, but on steroids because you automatically have everyone else&#8217;s. </p>

<p>There is however a rather huge &#8220;but&#8221; that has just reared its ugly head today. Colour identifies <strong>devices</strong> not <strong>people</strong>. This small but subtle difference is somewhat of a killer for Colour. Case in point: At the weekend I dropped my iPhone 4 by accident and totally destroyed the screen&#8230; this meant I had to get a replacement, which I did this morning. Upon reloading Colour from my backup, I no longer have all the pictures and groups from my old device because it thinks i&#8217;m someone &#8220;new&#8221;. </p>

<p>Guys, really, $41m and you cant make a login? I actually really liked the app, but having it not come with you when you change device is just such a killer. People these days have a really high turn over of mobile devices, so it simply doesn&#8217;t make sense to bind to the device&#8230; the service is meant to be about people and the photos they take, so perhaps it would be a super great idea to stop using the device ID as a route to identify people. </p>

<p>It generally feels like this could have been a really cool app, but its just lacking in some key areas. </p>

<p>End rant. </p>]]></content:encoded>
			<wfw:commentRss>http://blog.getintheloop.eu/2011/04/18/color-you-are-your-device/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

