<?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/"
	>

<channel>
	<title>Innovation Factory Dev Blog</title>
	<atom:link href="http://dev.innovationfactory.eu/feed/" rel="self" type="application/rss+xml" />
	<link>http://dev.innovationfactory.eu</link>
	<description></description>
	<pubDate>Tue, 17 Apr 2012 09:18:30 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.7.1</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Managing multiple large translation files</title>
		<link>http://dev.innovationfactory.eu/2011/08/16/managing-multiple-large-translation-files/</link>
		<comments>http://dev.innovationfactory.eu/2011/08/16/managing-multiple-large-translation-files/#comments</comments>
		<pubDate>Tue, 16 Aug 2011 09:19:15 +0000</pubDate>
		<dc:creator>Martijn Lafeber</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://dev.innovationfactory.eu/?p=679</guid>
		<description><![CDATA[For our main product, Ideanet, we have over 2500 lines in our yml translation files. That is, 2500 lines per language. 
Currently we support Dutch, English, French, Spanish and German. We manage Dutch and English ourselves, but for the other languages we need the help of a translation agency.
The problem is that Ideanet grows dynamically, [...]]]></description>
			<content:encoded><![CDATA[<p>For our main product, <a href="http://www.innovationfactory.eu/services/ideanet/">Ideanet</a>, we have over 2500 lines in our yml translation files. That is, 2500 lines <em>per language</em>. </p>
<p>Currently we support Dutch, English, French, Spanish and German. We manage Dutch and English ourselves, but for the other languages we need the help of a translation agency.</p>
<p>The problem is that Ideanet grows dynamically, and so do the translation files. We can&#8217;t send all the translation files to the translation agency once in a while and tell them &#8216;figure out which of the English translations are added and add those to the other languages&#8217;.</p>
<p>So we need an extract of the translations that are in the English (and Dutch) files, but not in the other ones. We save those extracts (which contain the English values) to de.yml, es.yml and fr.yml in separate directories. This is done using <code>rake locales:extract</code></p>
<p>These are sent to the translation company.</p>
<p>When we receive the translated files back, we need them merged back into the translation files. We execute <code>rake locales:merge</code></p>
<p>The translation files are sorted alphabetically in the process. This is useful when removing translations, which needs to be done in all translation files.</p>
<p>Code:</p>
<p><script src="https://gist.github.com/1148675.js?file=locales.rake"> </script></p>]]></content:encoded>
			<wfw:commentRss>http://dev.innovationfactory.eu/2011/08/16/managing-multiple-large-translation-files/feed/</wfw:commentRss>
		</item>
		<item>
		<title>HTML5 video with Flash fallback</title>
		<link>http://dev.innovationfactory.eu/2011/05/31/html5-video-for-all-browsers-including-ie-9/</link>
		<comments>http://dev.innovationfactory.eu/2011/05/31/html5-video-for-all-browsers-including-ie-9/#comments</comments>
		<pubDate>Tue, 31 May 2011 08:11:24 +0000</pubDate>
		<dc:creator>Martijn Lafeber</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://dev.innovationfactory.eu/?p=660</guid>
		<description><![CDATA[It has always been a little annoying including video files for our clients. Since most of them use a outdated version of Internet Explorer, we have to resort to Flash video.
We like to show demos to new potential clients on our iPads. The videos won&#8217;t display on the iPad since Flash is not supported. There&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<p>It has always been a little annoying including video files for our clients. Since most of them use a outdated version of Internet Explorer, we have to resort to Flash video.</p>
<p>We like to show demos to new potential clients on our iPads. The videos won&#8217;t display on the iPad since Flash is not supported. There&#8217;s a nice solution using html video tag and a flash fallback using <a href="http://www.flowplayer.org/">flowplayer</a>.</p>
<p>Here&#8217;s the code:<br />
<code class="html"><br />
&lt;video id="movie" width="320" height="240" preload controls src="demo.mp4" /&gt;<br />
</code></p>
<p>This format is currently supported by Chrome, Safari and IE>8.<br />
You will need a bit of javascript code that will replace the video tag with flash for all other browsers:</p>
<p><code class="javascript"><br />
replaceVideoWithFlash = function() {<br />
  if(navigator.userAgent.indexOf('Firefox') != -1 || navigator.userAgent.indexOf('Opera') != -1 || ( navigator.userAgent.indexOf('MSIE') != -1 &#038;&#038; parseFloat(navigator.appVersion.split("MSIE")[1]) < 9  )) {<br />
    var videos = document.getElementsByTagName('video');<br />
    for(var i=0;  i < videos.length ; i++) {<br />
      var video = videos[i];<br />
      fvideodiv = document.createElement('div');<br />
      if(video['poster'] != '') {<br />
        var config = '{"playlist":[{"url": "'+ video['poster'] +'","scaling": "orig"},{"url":"' + video['src'] + '", "autoPlay":false, "autoBuffering":true}]}';<br />
      } else {<br />
        var config = '{"clip":{"url":"' + video['src'] + '", "autoPlay":false, "autoBuffering":true}}';<br />
      }<br />
      fvideodiv.innerHTML = '&lt;object style="z-index:3;" id="flowplayer_'+i+'" width="' + video['width'] + '" height="' + video['height'] + '" data="/flowplayer/flowplayer-3.2.7.swf" type="application/x-shockwave-flash">&#8216; +<br />
      &#8216;&lt;param name=&#8221;movie&#8221; value=&#8221;/flowplayer/flowplayer-3.2.7.swf&#8221; />&#8217; +<br />
      &#8216;&lt;param name=&#8221;allowfullscreen&#8221; value=&#8221;true&#8221; />&#8217; +<br />
      &#8216;&lt;param name=&#8221;flashvars&#8221; value=\&#8217;config=&#8217; + config + &#8216;\&#8217; />&#8217; +<br />
      &#8216;&lt;/object>&#8217;;<br />
      video.parentNode.insertBefore(fvideodiv, video);<br />
      video.parentNode.removeChild(video);<br />
    }<br />
  }<br />
}<br />
</code></p>
<p>Note: We prefer .webm over the h.264 format. The latter is not open and thus not supported by Firefox and Opera, for which we have to resort to flash too <img src='http://dev.innovationfactory.eu/wp-includes/images/smilies/icon_sad.gif' alt=':(' class='wp-smiley' /> However, it&#8217;s <strong>currently</strong> the only format that works out of the box on Safari - and works in the flash fallback as well.</p>
<p>Please Apple, Please Microsoft: support the open Theora Webm format. This is the only way that in a few decades, when all the sluggish large companies have upgraded to modern browsers, we can all use just one, open format.</p>]]></content:encoded>
			<wfw:commentRss>http://dev.innovationfactory.eu/2011/05/31/html5-video-for-all-browsers-including-ie-9/feed/</wfw:commentRss>
		</item>
		<item>
		<title>IF hosts Amsterdam.rb meeting with Sven Fuchs and friends</title>
		<link>http://dev.innovationfactory.eu/2011/04/18/if-hosts-amsterdamrb-meeting-with-sven-fuchs-and-friends/</link>
		<comments>http://dev.innovationfactory.eu/2011/04/18/if-hosts-amsterdamrb-meeting-with-sven-fuchs-and-friends/#comments</comments>
		<pubDate>Mon, 18 Apr 2011 13:38:43 +0000</pubDate>
		<dc:creator>Lukas Spee</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://dev.innovationfactory.eu/?p=654</guid>
		<description><![CDATA[We are proud to host the upcoming Amsterdam.rb meeting at Innovation Factory HQ this Thursday. None other than Sven Fuchs, father of the i18n gem, will come over from Berlin to give a talk about Travis-CI, the distributed Ruby CI server.
And there is more. Josh Kalderimis will talk about Faraday and MultiJson and letting gem [...]]]></description>
			<content:encoded><![CDATA[<p>We are proud to host the upcoming Amsterdam.rb meeting at Innovation Factory HQ this Thursday. None other than <a href="http://twitter.com/svenfuchs">Sven Fuchs</a>, father of the i18n gem, will come over from Berlin to give a talk about <a href="http://travis-ci.org">Travis-CI</a>, the distributed Ruby CI server.</p>
<p>And there is more. <a href="http://twitter.com/joshkalderimis">Josh Kalderimis</a> will talk about Faraday and MultiJson and letting gem users make decisions for themselves. Our own <a href="http://twitter.com/lafeber">Martijn Lafeber</a> will show how to make your web application mobile ready through the power of CSS. And if you&#8217;re still in doubt: beer is on us and there might be some books to give away <img src='http://dev.innovationfactory.eu/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><span style="text-decoration: line-through;">Join the party by registering <a href="http://www.eventbrite.com/s/3UQL">here</a> and we&#8217;ll see you on Thursday!</span></p>]]></content:encoded>
			<wfw:commentRss>http://dev.innovationfactory.eu/2011/04/18/if-hosts-amsterdamrb-meeting-with-sven-fuchs-and-friends/feed/</wfw:commentRss>
		</item>
		<item>
		<title>How to create a mobile version of your (ruby on rails) site, part 2</title>
		<link>http://dev.innovationfactory.eu/2011/03/28/how-to-create-a-mobile-version-of-your-ruby-on-rails-site-part-2/</link>
		<comments>http://dev.innovationfactory.eu/2011/03/28/how-to-create-a-mobile-version-of-your-ruby-on-rails-site-part-2/#comments</comments>
		<pubDate>Mon, 28 Mar 2011 13:18:37 +0000</pubDate>
		<dc:creator>Martijn Lafeber</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://dev.innovationfactory.eu/?p=644</guid>
		<description><![CDATA[In the previous post, I talked about adding the mobile mime type and having separate .mobile.erb files.
Back then, we decided to have constrained functionality in the mobile version. This resulted in extra conditional blocks in the controllers. Also, we had many extra .mobile.erb partials.
Then came the new design.
Implementing the new design gave us the opportunity [...]]]></description>
			<content:encoded><![CDATA[<p>In the previous post, I talked about adding the mobile mime type and having separate <strong>.mobile.erb</strong> files.</p>
<p>Back then, we decided to have constrained functionality in the mobile version. This resulted in extra conditional blocks in the controllers. Also, we had many extra .mobile.erb partials.</p>
<p><em>Then came the new design.</em></p>
<p>Implementing the new design gave us the opportunity to seriously rethink the html of the regular site. Lots of unnecessary html and css code was removed. We also used less instead of css everywhere.</p>
<p>The mobile version needed attention too. Since the html was superclean in the new version, I came up with the idea of switching to the mobile version by just switching the css files. We would have the same html in both versions.</p>
<p>The following steps were taken to create the new mobile version:<br />
- Remove the mobile mime type.<br />
- Remove all css, except for smaller css files for eg. voting.<br />
- For some advanced functionality like filtering and sorting, set the display to &#8216;none&#8217;. We could have included these, but it wouldn&#8217;t fit nicely on small screens.<br />
- Gradually copy css from iWebkit to existing css classes and id&#8217;s.<br />
- Add the following in your header:<br />
<code class="ruby"><br />
&lt;% if mobile_session? %&gt;<br />
&lt; meta content="minimum-scale=1.0, width=device-width, maximum-scale=0.6667, user-scalable=no" name="viewport" /&gt;<br />
&lt; meta content="yes" name="apple-mobile-web-app-capable" /&gt;<br />
&lt; link rel="apple-touch-icon" href="/apple-touch-icon.png"/&gt;<br />
&lt;%= stylesheet_link_tag %w(mobile ... ...) %&gt;<br />
&lt;% else %&gt;<br />
...<br />
&lt;% end %&gt;<br />
</code></p>
<p>The new mobile version maintained all core functionality. Extra code in controllers was removed, as well as all the .mobile.erb partials. #winning !</p>
<p><img class="alignnone size-full wp-image-651" title="mobile-screen" src="http://dev.innovationfactory.eu/wp-content/uploads/2011/03/mobile-screen.png" alt="mobile-screen" width="321" height="479" /></p>]]></content:encoded>
			<wfw:commentRss>http://dev.innovationfactory.eu/2011/03/28/how-to-create-a-mobile-version-of-your-ruby-on-rails-site-part-2/feed/</wfw:commentRss>
		</item>
		<item>
		<title>How to create a mobile version of your (ruby on rails) site</title>
		<link>http://dev.innovationfactory.eu/2010/08/05/how-to-create-a-mobile-version-of-your-ruby-site/</link>
		<comments>http://dev.innovationfactory.eu/2010/08/05/how-to-create-a-mobile-version-of-your-ruby-site/#comments</comments>
		<pubDate>Thu, 05 Aug 2010 12:36:02 +0000</pubDate>
		<dc:creator>Martijn Lafeber</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://dev.innovationfactory.nl/?p=619</guid>
		<description><![CDATA[You have several very useful libraries that do most of the styling / behavior for you:
iWebkit
jQTouch (sencha touch)
iui
We chose for iWebkit, but if you desire a more native feel you might choose jQTouch. The standard browsers on iPhone, Android, palmOS and Blackberry OS6 are all Webkit based. This ensures that sites based on iWebkit will [...]]]></description>
			<content:encoded><![CDATA[<p>You have several very useful libraries that do most of the styling / behavior for you:</p>
<p><a href="http://iwebkit.net/">iWebkit</a><br />
<a href="http://www.jqtouch.com/">jQTouch</a> (<a href="http://www.sencha.com/products/touch/">sencha touch</a>)<br />
<a href="http://code.google.com/p/iui/">iui</a></p>
<p>We chose for iWebkit, but if you desire a more native feel you might choose jQTouch. The standard browsers on iPhone, Android, palmOS and Blackberry OS6 are all Webkit based. This ensures that sites based on iWebkit will work on all these devices, which is great! Copy the required javascript, images and stylesheets to your public folder.</p>
<p>Next, you have to detect if your user is on a mobile device.<br />
Add the following code to your application controller:<br />
<code class="ruby"><br />
helper_method :mobile_session?, :on_mobile?<br />
def mobile_session?<br />
  if session[:mobile_param]<br />
    return session[:mobile_param] == &#8220;1&#8243;<br />
  else<br />
    return on_mobile?<br />
  end<br />
end<br />
&nbsp; &nbsp;<br />
def on_mobile?<br />
  request.user_agent =~ /Mobile|webOS|BlackBerry|Android|iPhone|Opera Mini/<br />
end<br />
</code></p>
<p>Next, in config/initializers/mime_types.rb add the following:</p>
<p><code class="ruby"><br />
Mime::Type.register_alias "text/html", :mobile<br />
</code></p>
<p>The only thing left to do now is to create mobile views. The extension for these files is <b>.mobile.erb</b> Look at the examples provided by the framework to see what html to use in your mobile views.</p>
<p>You&#8217;re done!</p>
<p>Some last tips:</p>
<ul>
<li> You probably want to leave out some pages, and only show the mobile user the core functionality.</li>
<li> Always include a link to get to the normal site, which is done by appending <b>?mobile=0</b> to a link.</li>
</ul>
<p>Some screenshots of the mobile version of one of our products:</p>
<p><img src="http://dev.innovationfactory.nl/wp-content/uploads/2010/08/screen-shot-2010-08-05-at-144203.png" alt="mobile-screenshot" title="mobile-screenshot" width="322" height="480" class="alignnone size-full wp-image-633" /> <img src="http://dev.innovationfactory.nl/wp-content/uploads/2010/08/screen-shot-2010-08-05-at-144241.png" alt="mobile-screenshot2" title="mobile-screenshot2" width="320" height="481" class="alignnone size-full wp-image-634" /></p>]]></content:encoded>
			<wfw:commentRss>http://dev.innovationfactory.eu/2010/08/05/how-to-create-a-mobile-version-of-your-ruby-site/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Development and release strategy with Git</title>
		<link>http://dev.innovationfactory.eu/2010/06/09/development-and-release-strategy-with-git/</link>
		<comments>http://dev.innovationfactory.eu/2010/06/09/development-and-release-strategy-with-git/#comments</comments>
		<pubDate>Wed, 09 Jun 2010 15:39:00 +0000</pubDate>
		<dc:creator>Lukas Spee</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[Git]]></category>

		<guid isPermaLink="false">http://dev.innovationfactory.nl/?p=588</guid>
		<description><![CDATA[At Innovation Factory we offer our clients two solutions for hosting our Innovation Suite applications: we can host it for them as a software-as-a-service solution or they can host it on premises, i.e. in their own IT environment. This means that we have several deployments of our suite that we need to maintain. In this [...]]]></description>
			<content:encoded><![CDATA[<p>At Innovation Factory we offer our clients two solutions for hosting our Innovation Suite applications: we can host it for them as a software-as-a-service solution or they can host it on premises, i.e. in their own IT environment. This means that we have several deployments of our suite that we need to maintain. In this article we show how we use Git branches and tags for this purpose. </p>
<p><strong>Development with story branches</strong></p>
<p>Every new feature and bugfix originates from a story in the Pivotal Tracker. The work that is done for these stories is committed to the master branch. This branch should be stable at all times; no tests should fail when you run the test suite in master. For this reason it is usually a good idea to work on a story in a separate branch and merge this branch back into master when the story is ready for acceptance. </p>
<p>Such a story branch has a name that briefly describes the story. This name is namespaced with &#8217;stories&#8217; and the initials of the developer who created it. For example, when Kyle Broflovski adds an exception handling mechanism to our application, he can do this in a branch called &#8217;stories/KB/add-exception-handling&#8217;. </p>
<p><code>git checkout -b stories/KB/add-exception-handling</code></p>
<blockquote><p><img src="http://dev.innovationfactory.nl/wp-content/uploads/2010/06/gitx-screen-1.png" alt="gitx-screen-1" title="gitx-screen-1" width="149" height="80" class="alignnone size-full wp-image-592" /><br />
<em>The master branch of our example application</em></p></blockquote>
<blockquote><p><img src="http://dev.innovationfactory.nl/wp-content/uploads/2010/06/gitx-screen-2.png" alt="gitx-screen-2" title="gitx-screen-2" width="269" height="83" class="alignnone size-full wp-image-593" /><br />
<em>Creating a story branch for adding an exception handling mechanism</em>
</p></blockquote>
<blockquote><p><img src="http://dev.innovationfactory.nl/wp-content/uploads/2010/06/gitx-screen-3.png" alt="gitx-screen-3" title="gitx-screen-3" width="294" height="175" class="alignnone size-full wp-image-594" /><br />
<em>Building the exception handling mechanism in its own story branch</em>
</p></blockquote>
<p>Kyle then becomes the &#8216;owner&#8217; of the branch. This means that other people may also work in this branch, but Kyle is the one who is responsible for deleting it once it is merged into master. In other words: if you create a story branch, you&#8217;ll also have to destroy it when it is no longer in use. </p>
<p><code>git checkout master<br /> git merge stories/KB/add-exception-handling<br /> git branch -d stories/KB/add-exception-handling</code> </p>
<blockquote><p><img src="http://dev.innovationfactory.nl/wp-content/uploads/2010/06/gitx-screen-4.png" alt="gitx-screen-4" title="gitx-screen-4" width="403" height="198" class="alignnone size-full wp-image-595" /><br />
<em>Merging the story branch into master</em>
</p></blockquote>
<blockquote><p><img src="http://dev.innovationfactory.nl/wp-content/uploads/2010/06/gitx-screen-5.png" alt="gitx-screen-5" title="gitx-screen-5" width="398" height="201" class="alignnone size-full wp-image-596" /><br />
<em>Removing the story branch</em>
</p></blockquote>
<p>If somewhere along the line you have pushed the branch to origin, make sure to delete it there too. </p>
<p><code>git push origin&nbsp;:stories/KB/add-exception-handling</code> </p>
<p>The master branch is regularly deployed to our acceptance server, where the product owners can test the stories and either accept or reject them. </p>
<p><strong>Releases and deployments</strong></p>
<p>After a while we have made enough changes to our applications to do a new release. We record the release history in Git by tagging the last commit that is part of the release. </p>
<p><code>git tag kenny</code> </p>
<blockquote><p><img src="http://dev.innovationfactory.nl/wp-content/uploads/2010/06/gitx-screen-6.png" alt="gitx-screen-6" title="gitx-screen-6" width="358" height="247" class="alignnone size-full wp-image-597" /><br />
<em>Creating a new release tag &#8216;Kenny&#8217;</em>
</p></blockquote>
<p>The tag is a release name that all developers agree on. It is not a version number, because a name is easier to remember and talk about during development. However, externally we could use version numbers for our releases. So a release that is known as &#8216;Kenny&#8217; by the dev team might be known as release 1.0 by our clients. </p>
<p>Ideally we would immediately upgrade all the deployments to the newest release. In practice this is not always possible, for example because we don&#8217;t have direct access to an on-premises deployment. This means that we not only have to keep track of which releases exist, but also of which deployment is currently on which release. For this purpose we give every deployment its own branch namespaced with &#8216;deployments&#8217; (why we use branches and not tags here will become apparent in the next section). </p>
<p>Let&#8217;s assume that we have two deployments of our software: one is our SAAS install and one is an install for client Amazing-co. We then create two deployment branches, named &#8216;deployments/saas&#8217; and &#8216;deployments/amazing-co&#8217;, respectively. </p>
<p><code>git checkout -b deployments/saas<br /> git checkout -b deployments/amazing-co</code> </p>
<blockquote><p><img src="http://dev.innovationfactory.nl/wp-content/uploads/2010/06/gitx-screen-7.png" alt="gitx-screen-7" title="gitx-screen-7" width="433" height="247" class="alignnone size-full wp-image-598" /><br />
<em>Creating deployment branches for the SAAS and Amazing-co deployments</em>
</p></blockquote>
<p>When a deployment is on a certain release, both the deployment branch and the release tag will point to the same commit. That is, if no hotfixes have been applied&#8230; </p>
<p><strong>Hotfixes</strong></p>
<p>Sometimes a bugfix is so important that we cannot wait for the next release to roll it out to the various deployments. But we don&#8217;t want to do an intermediate release which contains all kinds of new and perhaps untested features just to apply one hotfix. Instead, we use separate hotfix branches for our releases. Once we do a release we not only create a tag, but also a corresponding hotfix branch. This branch has the same release name, but namespaced with &#8216;releases&#8217;. Thus, for a release named &#8216;kenny&#8217; the hotfix branch is called &#8216;releases/kenny&#8217;. </p>
<p><code>git checkout releases/kenny</code> </p>
<blockquote><p><img src="http://dev.innovationfactory.nl/wp-content/uploads/2010/06/gitx-screen-8.png" alt="gitx-screen-8" title="gitx-screen-8" width="508" height="245" class="alignnone size-full wp-image-599" /><br />
<em>Creating a hotfix branch for the &#8216;Kenny&#8217; release</em>
</p></blockquote>
<p>A hotfix branch should honour its name and contain only bug fixes, not new features. A hotfix can be a cherry-picked commit from the master branch, but also a release specific patch that will be replaced by a different fix in the upcoming release (e.g. if we cannot cherry-pick from the master branch because the affected code has been refactored in the mean time). For clarity we prefix commit messages of hotfixes with &#8216;HOTFIX:&#8217;. </p>
<blockquote><p><img src="http://dev.innovationfactory.nl/wp-content/uploads/2010/06/gitx-screen-9.png" alt="gitx-screen-9" title="gitx-screen-9" width="391" height="236" class="alignnone size-full wp-image-600" /><br />
<em>Cherry-picking a bug fix from master into the hotfix branch for the &#8216;Kenny&#8217; release</em>
</p></blockquote>
<p>Once a hotfix has been rolled out to a deployment, we update its deployment branch to reflect this. We do this by merging the hotfix branch into the deployment branch. The example below shows how we update our SAAS deployment with the latest hotfixes for the &#8216;Kenny&#8217; release. </p>
<p><code>git checkout deployments/saas<br /> git merge releases/kenny</code> </p>
<blockquote><p><img src="http://dev.innovationfactory.nl/wp-content/uploads/2010/06/gitx-screen-10.png" alt="gitx-screen-10" title="gitx-screen-10" width="360" height="269" class="alignnone size-full wp-image-601" /><br />
<em>Applying a hotfix to the SAAS deployment by merging the hotfix branch for the &#8216;Kenny&#8217; release into the SAAS deployment branch</em>
</p></blockquote>
<p>When a deployment is updated to a new release, we discard the hotfixes in favour of the changes in the master branch. So if we upgrade our SAAS deployment from the hotfixed &#8216;Kenny&#8217; release to the new &#8216;Stan&#8217; release, we first rewind the SAAS deployment branch to the original &#8216;Kenny&#8217; release tag and then fast-forward along the master branch to the &#8216;Stan&#8217; release tag. However, before we can do all of this we need to remove the deployments/saas branch from our remote, otherwise it won&#8217;t let you push the changes as it thinks we&#8217;re behind of the remote branch.</p>
<p><code>git push origin :deployments/saas<br />git checkout deployments/saas<br /> git reset &#8211;hard kenny<br /> git merge stan<br />git push origin deployments/saas</code> </p>
<blockquote><p><img src="http://dev.innovationfactory.nl/wp-content/uploads/2010/06/gitx-screen-11.png" alt="gitx-screen-11" title="gitx-screen-11" width="458" height="269" class="alignnone size-full wp-image-602" /><br />
<em>Before upgrading to the &#8216;Stan&#8217; release, the SAAS deployment is at the head of the &#8216;Kenny&#8217; hotfix branch</em>
</p></blockquote>
<blockquote><p><img src="http://dev.innovationfactory.nl/wp-content/uploads/2010/06/gitx-screen-12.png" alt="gitx-screen-12" title="gitx-screen-12" width="374" height="266" class="alignnone size-full wp-image-603" /><br />
<em>The SAAS deployment has been rewinded to the &#8216;Kenny&#8217; release tag</em>
</p></blockquote>
<blockquote><p><img src="http://dev.innovationfactory.nl/wp-content/uploads/2010/06/gitx-screen-13.png" alt="gitx-screen-13" title="gitx-screen-13" width="378" height="275" class="alignnone size-full wp-image-604" /><br />
<em>The SAAS deployment has been fast-forwarded from the &#8216;Kenny&#8217; release tag to the &#8216;Stan&#8217; release tag</em>
</p></blockquote>
<p>Once all the deployments have been updated to a new release, the hotfix branch for the previous release becomes &#8216;abandoned&#8217;. Although it is not in use anymore, we don&#8217;t delete it. It is part of the history of our applications and it may contain work that can be reused in another context in a new release. </p>
<blockquote><p><img src="http://dev.innovationfactory.nl/wp-content/uploads/2010/06/gitx-screen-14.png" alt="gitx-screen-14" title="gitx-screen-14" width="397" height="267" class="alignnone size-full wp-image-605" /><br />
<em>After upgrading the Amazing-co deployment to the &#8216;Stan&#8217; release the &#8216;Kenny&#8217; hotfix branch is now &#8216;abandoned&#8217;</em>
</p></blockquote>
<p><strong>Experimental branches</strong></p>
<p>If you want to try out a nice new plugin or do some prototyping, an experimental branch is the way to go. An experimental branch will usually not be merged into master, but contains work that may be integrated into the master branch in an altered form. The name of an experimental branch is namespaced with &#8216;experiments&#8217; and the initials of the owner. For example, Kyle Broflovski can try out a Facebook integration plugin in a branch called &#8216;experiments/KB/facebook-integration&#8217;. </p>
<p><code>git checkout -b experiments/KB/facebook-integration</code> </p>
<blockquote><p><img src="http://dev.innovationfactory.nl/wp-content/uploads/2010/06/gitx-screen-15.png" alt="gitx-screen-15" title="gitx-screen-15" width="541" height="246" class="alignnone size-full wp-image-606" /><br />
<em>Experimental work on Facebook integration taking place in a separate branch</em>
</p></blockquote>
<p><strong>Wrap-up</strong></p>
<p>We have been using the above strategy for a few months now and it really fits well in our development and release cycle. It would be interesting to know about other strategies, so feel free to share yours in the comments below.</p>]]></content:encoded>
			<wfw:commentRss>http://dev.innovationfactory.eu/2010/06/09/development-and-release-strategy-with-git/feed/</wfw:commentRss>
		</item>
		<item>
		<title>All the world&#8217;s flags in a sprite</title>
		<link>http://dev.innovationfactory.eu/2010/03/15/all-the-worlds-flags-in-a-sprite/</link>
		<comments>http://dev.innovationfactory.eu/2010/03/15/all-the-worlds-flags-in-a-sprite/#comments</comments>
		<pubDate>Mon, 15 Mar 2010 13:23:30 +0000</pubDate>
		<dc:creator>Martijn Lafeber</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://dev.innovationfactory.nl/?p=554</guid>
		<description><![CDATA[For the short version: check out http://github.com/lafeber/world-flags-sprite
Lukas and I are working on a pet project when we&#8217;re traveling between Utrecht and Amsterdam. We&#8217;ve built a website that contains cheeses of many countries. I&#8217;ve been a fan of the famfamfam world flags for years, so it made sense to include them in the site.
You quickly get [...]]]></description>
			<content:encoded><![CDATA[<p>For the short version: check out <a href="http://github.com/lafeber/world-flags-sprite">http://github.com/lafeber/world-flags-sprite</a></p>
<p>Lukas and I are working on a pet project when we&#8217;re traveling between Utrecht and Amsterdam. We&#8217;ve built a website that contains cheeses of many countries. I&#8217;ve been a fan of the <a href="http://www.famfamfam.com/lab/icons/flags/">famfamfam world flags</a> for years, so it made sense to include them in the site.</p>
<p>You quickly get too many server requests when you have many separate images on one page. <a href="http://dev.innovationfactory.nl/2009/04/21/saving-bandwidth-with-rails/">This is bad</a>. So I thought of making a sprite of all the world&#8217;s flags. I&#8217;ve tried <a href="http://spriteme.org/">spriteme</a> first but it didn&#8217;t work - my guess is there were too many images. Then I tried <a href="http://csssprites.org/">smartsprites</a> which did the trick.</p>
<p>You run the command<br />
<code><br />
./smartsprites.sh --root-dir-path ~/path_to_famfamfam/flags_iso/16<br />
</code><br />
which generates a <a href="http://cloud.github.com/downloads/lafeber/world-flags-sprite/flags32.png">super long image</a> and a new css file that looks like this:</p>
<p><code class="css"><br />
.ad {<br />
  background-color:transparent;<br />
  background-repeat:no-repeat;<br />
  background-image: url('flags16.png');<br />
  background-position: left -336px;<br />
}<br />
.ae {<br />
  background-color:transparent;<br />
  background-repeat:no-repeat;<br />
  background-image: url('flags16.png');<br />
  background-position: left -352px;<br />
}<br />
.af {<br />
  background-color:transparent;<br />
  background-repeat:no-repeat;<br />
  background-image: url('flags16.png');<br />
  background-position: left -368px;<br />
}<br />
...<br />
</code></p>
<p>You&#8217;ll immediately notice a lot of duplication, which is unacceptable since there are more than 240 flags. I&#8217;ve created a simple ruby script to generate the css needed for the sprite. When run in the image directory, it generates a css file that looks like this:</p>
<p><code class="css"><br />
.f16 .flag{background:url(flags16.png) no-repeat}<br />
.f16 .ad{background-position:left -336px;}<br />
.f16 .ae{background-position:left -352px;}<br />
.f16 .af{background-position:left -368px;}<br />
...<br />
</code></p>
<p>An example of how you can use it in your site:<br />
<code class="html"><br />
&lt;link rel="stylesheet" type="text/css" href="http://cloud.github.com/downloads/lafeber/world-flags-sprite/flags32.css" /&gt;<br />
</code></p>
<p><code class="html"><br />
&lt;ul class="f16"&gt;<br />
  &lt;li class="flag ar"&gt;Argentina&lt;/li&gt;<br />
  &lt;li class="flag au"&gt;Australia&lt;/li&gt;<br />
  &lt;li class="flag at"&gt;Austria&lt;/li&gt;<br />
...<br />
&lt;/ul&gt;<br />
</code></p>
<p>See <a href="http://www.cheesewiki.com/">http://www.cheesewiki.com/</a> (which lists all the worlds&#8217; cheeses) for an example.</p>
<p>Note that you can&#8217;t use this in a https environment, and that images won&#8217;t show if github is down. However, if people have visited a site that uses the same css file, they won&#8217;t have to download it again which speeds up things drastically!</p>]]></content:encoded>
			<wfw:commentRss>http://dev.innovationfactory.eu/2010/03/15/all-the-worlds-flags-in-a-sprite/feed/</wfw:commentRss>
		</item>
		<item>
		<title>iPhone version of our blog</title>
		<link>http://dev.innovationfactory.eu/2010/01/08/iphone-version-of-our-blog/</link>
		<comments>http://dev.innovationfactory.eu/2010/01/08/iphone-version-of-our-blog/#comments</comments>
		<pubDate>Fri, 08 Jan 2010 09:33:41 +0000</pubDate>
		<dc:creator>Martijn Lafeber</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://dev.innovationfactory.nl/?p=549</guid>
		<description><![CDATA[This is a story about the power of Rails. 
It all started two days ago, when Seth Godin and Guy Kawasaki blogged about Appmakr.com. It allowed you to have an app in the Appstore based on your own RSS feed. The price they ask for this is $199,-
I believe that the appstore shouldn&#8217;t be polluted [...]]]></description>
			<content:encoded><![CDATA[<p>This is a story about the power of Rails. </p>
<p>It all started two days ago, when Seth Godin and Guy Kawasaki blogged about Appmakr.com. It allowed you to have an app in the Appstore based on your own RSS feed. The price they ask for this is $199,-</p>
<p>I believe that the appstore shouldn&#8217;t be polluted with RSS feeds. They should be websites instead of apps. Websites can have their own icon on the iPhone&#8217;s home screen.</p>
<p>With this in mind, I started to scaffold on my way back home. Commute by train is a bless.</p>
<p>The following gems were already installed:</p>
<ul>
<li><a href="http://github.com/cardmagic/simple-rss">simple-rss</a></li>
<li><a href="http://github.com/ambethia/recaptcha/">recaptcha</a></li>
<li><a href="http://github.com/thoughtbot/paperclip/">paperclip</a></li>
</ul>
<p>I had used <a href="http://code.google.com/p/iui/">http://code.google.com/p/iui/</a> before.</p>
<p>Within two hours, <a href="http://iphonify.net/">http://iphonify.net/</a> was born. It allows anyone to claim their own url. For example, the iPhone version of this blog can be found at <a href="http://iphonify.net/ifdev">http://iphonify.net/ifdev</a>.</p>
<p>If it weren&#8217;t for Rails - and the amazing plugins - I would have never been able to build this site that fast.</p>]]></content:encoded>
			<wfw:commentRss>http://dev.innovationfactory.eu/2010/01/08/iphone-version-of-our-blog/feed/</wfw:commentRss>
		</item>
		<item>
		<title>Pair programming experiences</title>
		<link>http://dev.innovationfactory.eu/2009/12/31/pair-programming-experiences/</link>
		<comments>http://dev.innovationfactory.eu/2009/12/31/pair-programming-experiences/#comments</comments>
		<pubDate>Thu, 31 Dec 2009 09:07:49 +0000</pubDate>
		<dc:creator>Martijn Lafeber</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://dev.innovationfactory.nl/?p=527</guid>
		<description><![CDATA[Last year we talked about pair programming with Obie Fernandez at Rails Underground. He was very enthusiastic about this practice, to the extent that the developers at his company Hashrocket, pair up full time. Inspired by this, we decided to try out pair programming ourselves. And we got quite excited about it too. So we [...]]]></description>
			<content:encoded><![CDATA[<p>Last year we talked about pair programming with <a href="http://obiefernandez.com">Obie Fernandez</a> at <a href="http://dev.innovationfactory.nl/2009/07/27/rails-underground-2009/">Rails Underground</a>. He was very enthusiastic about this practice, to the extent that the developers at his company Hashrocket, pair up full time. Inspired by this, we decided to try out pair programming ourselves. And we got quite excited about it too. So we chose to write a series of blog posts, or at least one, to spread the word and share our experiences. In this first post on this subject, we give a global introduction and we talk about our personal experiences with pair programming at Innovation Factory.</p>
<p>Pair programming is a software development technique in which two programmers work together at one work station. One types in code while the other reviews each line of code as it is typed in. The person typing is called the driver. The person reviewing the code is called the observer or navigator. The two programmers switch roles frequently.</p>
<p>While reviewing, the observer also considers the strategic direction of the work, coming up with ideas for improvements and likely future problems to address. This frees the driver to focus all of his or her attention on the &#8220;tactical&#8221; aspects of completing the current task, using the observer as a safety net and guide.</p>
<p>Here are our experiences so far:</p>
<p><em>Martijn Lafeber:</em> I really enjoyed pair programming. Especially because we&#8217;re working on several projects - it allows you to get familiar with new ones pretty fast. You get distracted less than when you would work on your own; it forces you to stay focused.</p>
<p><em>Sam Aaron:</em> I think that the main benefit of pair programming is that it forces you to externally communicate your ideas and code with another. This makes it the best vehicle for sharing programming-level domain knowledge I&#8217;ve yet found. I also love the fact that it provides you with an opportunity to learn and share lots of small little tips and tricks that you don&#8217;t normally find the time to talk about.</p>
<p><em>Lukas Spee:</em> I have experienced lots of benefits from pair programming. Two brains know more than one and two pairs of eyes see more than one pair. So you make better design decisions &#8212; which gives you more confidence &#8212; and you discover errors earlier on &#8212; which saves you time. Another nice thing is that knowledge sharing takes place on the spot, as you code. And perhaps most importantly: it&#8217;s way more fun than solo programming.</p>
<p><em>Sjoerd Andringa:</em> To me the power of pair programming lies in keeping each other focused and continuous communication. If a pair isn&#8217;t talking all the time they&#8217;re probably not getting the maximum out of pair programming. Ongoing code reviews and knowledge sharing are key. However, pair programming also poses challenges. It can for instance be difficult to adapt the right role. When do you intervene? When do you ask questions? The perfect balance is different for every partner. Also staying focused all day (e.g. not letting your partner down by being distracted by things like email) requires a lot of energy. Be sure to take short breaks.</p>]]></content:encoded>
			<wfw:commentRss>http://dev.innovationfactory.eu/2009/12/31/pair-programming-experiences/feed/</wfw:commentRss>
		</item>
		<item>
		<title>never use sudo gem install again</title>
		<link>http://dev.innovationfactory.eu/2009/10/26/never-use-sudo-gem-install-again/</link>
		<comments>http://dev.innovationfactory.eu/2009/10/26/never-use-sudo-gem-install-again/#comments</comments>
		<pubDate>Mon, 26 Oct 2009 15:17:00 +0000</pubDate>
		<dc:creator>Martijn Lafeber</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://dev.innovationfactory.nl/?p=513</guid>
		<description><![CDATA[It always bothered me that when you do a gem install instead of a sudo gem install you usually get the following errors:

WARNING:  Installing to ~/.gem since /usr/local/lib/ruby/gems/1.8 and
/usr/local/bin aren't both writable.
WARNING:  You don't have /Users/martijn/.gem/ruby/1.8/bin in your PATH,
gem executables will not run.

Most of the times, gems are all over the place. I just want [...]]]></description>
			<content:encoded><![CDATA[<p>It always bothered me that when you do a <strong>gem install</strong> instead of a <strong>sudo gem install</strong> you usually get the following errors:</p>
<p><code><br />
WARNING:  Installing to ~/.gem since /usr/local/lib/ruby/gems/1.8 and<br />
/usr/local/bin aren't both writable.<br />
WARNING:  You don't have /Users/martijn/.gem/ruby/1.8/bin in your PATH,<br />
gem executables will not run.<br />
</code></p>
<p>Most of the times, gems are all over the place. I just want them all to be in one place - <strong>~/.gem</strong> - and I don&#8217;t want to type <strong>sudo gem install &#8230;</strong> again. And, most of all, I don&#8217;t want to see those annoying warnings when I type <strong>gem install &#8230;</strong></p>
<p>Getting rid of the second warning is easy, just type</p>
<p><code>export PATH="$HOME/.gem/ruby/1.8/bin:$PATH"</code></p>
<p>To get rid of the first warning, put</p>
<p><code>:gemhome: /Users/{your_username}/.gem/ruby/1.8/</code></p>
<p>in the ~/.gemrc file.</p>
<p>All your gems will now be in ~/.gem/ and you&#8217;ll no longer see those annoying warnings when you do a gem install. YES!</p>
<p>&#8211;== UPDATE ==&#8211;</p>
<p>Apparently, instead of editing ~/.gemrc you can also type:</p>
<p><code>export GEM_PATH="$HOME/.gem/ruby/1.8"<br />
export GEM_HOME="$HOME/.gem/ruby/1.8"</code></p>
<p>Thanks to Pat Allan, who wrote about it <a href="http://gist.github.com/217895">here</a></p>]]></content:encoded>
			<wfw:commentRss>http://dev.innovationfactory.eu/2009/10/26/never-use-sudo-gem-install-again/feed/</wfw:commentRss>
		</item>
	</channel>
</rss>

