Development blog posts

Below you find an overview of our most recent blog posts.
Check regularly for updates!

 

Managing multiple large translation files

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, and so do the translation files. We can’t send all the translation files to the translation agency once in a while and tell them ‘figure out which of the English translations are added and add those to the other languages’.

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 rake locales:extract

These are sent to the translation company.

When we receive the translated files back, we need them merged back into the translation files. We execute rake locales:merge

The translation files are sorted alphabetically in the process. This is useful when removing translations, which needs to be done in all translation files.

Code:

Posted August 16th, 2011 by Martijn Lafeber
Logo
 

HTML5 video with Flash fallback

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’t display on the iPad since Flash is not supported. There’s a nice solution using html video tag and a flash fallback using flowplayer.

Here’s the code:

<video id="movie" width="320" height="240" preload controls src="demo.mp4" />

This format is currently supported by Chrome, Safari and IE>8.
You will need a bit of javascript code that will replace the video tag with flash for all other browsers:


replaceVideoWithFlash = function() {
if(navigator.userAgent.indexOf('Firefox') != -1 || navigator.userAgent.indexOf('Opera') != -1 || ( navigator.userAgent.indexOf('MSIE') != -1 && parseFloat(navigator.appVersion.split("MSIE")[1]) < 9 )) {
var videos = document.getElementsByTagName('video');
for(var i=0; i < videos.length ; i++) {
var video = videos[i];
fvideodiv = document.createElement('div');
if(video['poster'] != '') {
var config = '{"playlist":[{"url": "'+ video['poster'] +'","scaling": "orig"},{"url":"' + video['src'] + '", "autoPlay":false, "autoBuffering":true}]}';
} else {
var config = '{"clip":{"url":"' + video['src'] + '", "autoPlay":false, "autoBuffering":true}}';
}
fvideodiv.innerHTML = '<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">‘ +
‘<param name=”movie” value=”/flowplayer/flowplayer-3.2.7.swf” />’ +
‘<param name=”allowfullscreen” value=”true” />’ +
‘<param name=”flashvars” value=\’config=’ + config + ‘\’ />’ +
‘</object>’;
video.parentNode.insertBefore(fvideodiv, video);
video.parentNode.removeChild(video);
}
}
}

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 :( However, it’s currently the only format that works out of the box on Safari - and works in the flash fallback as well.

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.

Posted May 31st, 2011 by Martijn Lafeber
Logo
 

IF hosts Amsterdam.rb meeting with Sven Fuchs and friends

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 users make decisions for themselves. Our own Martijn Lafeber will show how to make your web application mobile ready through the power of CSS. And if you’re still in doubt: beer is on us and there might be some books to give away :)

Join the party by registering here and we’ll see you on Thursday!

Posted April 18th, 2011 by Lukas Spee
Logo
 

How to create a mobile version of your (ruby on rails) site, part 2

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 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.

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.

The following steps were taken to create the new mobile version:
- Remove the mobile mime type.
- Remove all css, except for smaller css files for eg. voting.
- For some advanced functionality like filtering and sorting, set the display to ‘none’. We could have included these, but it wouldn’t fit nicely on small screens.
- Gradually copy css from iWebkit to existing css classes and id’s.
- Add the following in your header:

<% if mobile_session? %>
< meta content="minimum-scale=1.0, width=device-width, maximum-scale=0.6667, user-scalable=no" name="viewport" />
< meta content="yes" name="apple-mobile-web-app-capable" />
< link rel="apple-touch-icon" href="/apple-touch-icon.png"/>
<%= stylesheet_link_tag %w(mobile ... ...) %>
<% else %>
...
<% end %>

The new mobile version maintained all core functionality. Extra code in controllers was removed, as well as all the .mobile.erb partials. #winning !

mobile-screen

Posted March 28th, 2011 by Martijn Lafeber
Logo
 

How to create a mobile version of your (ruby on rails) site

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 work on all these devices, which is great! Copy the required javascript, images and stylesheets to your public folder.

Next, you have to detect if your user is on a mobile device.
Add the following code to your application controller:

helper_method :mobile_session?, :on_mobile?
def mobile_session?
if session[:mobile_param]
return session[:mobile_param] == “1″
else
return on_mobile?
end
end
   
def on_mobile?
request.user_agent =~ /Mobile|webOS|BlackBerry|Android|iPhone|Opera Mini/
end

Next, in config/initializers/mime_types.rb add the following:


Mime::Type.register_alias "text/html", :mobile

The only thing left to do now is to create mobile views. The extension for these files is .mobile.erb Look at the examples provided by the framework to see what html to use in your mobile views.

You’re done!

Some last tips:

  • You probably want to leave out some pages, and only show the mobile user the core functionality.
  • Always include a link to get to the normal site, which is done by appending ?mobile=0 to a link.

Some screenshots of the mobile version of one of our products:

mobile-screenshot mobile-screenshot2

Posted August 5th, 2010 by Martijn Lafeber
Logo
 

Development and release strategy with Git

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.

Development with story branches

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.

Such a story branch has a name that briefly describes the story. This name is namespaced with ’stories’ 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 ’stories/KB/add-exception-handling’.

git checkout -b stories/KB/add-exception-handling

gitx-screen-1
The master branch of our example application

gitx-screen-2
Creating a story branch for adding an exception handling mechanism

gitx-screen-3
Building the exception handling mechanism in its own story branch

Kyle then becomes the ‘owner’ 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’ll also have to destroy it when it is no longer in use.

git checkout master
git merge stories/KB/add-exception-handling
git branch -d stories/KB/add-exception-handling

gitx-screen-4
Merging the story branch into master

gitx-screen-5
Removing the story branch

If somewhere along the line you have pushed the branch to origin, make sure to delete it there too.

git push origin :stories/KB/add-exception-handling

The master branch is regularly deployed to our acceptance server, where the product owners can test the stories and either accept or reject them.

Releases and deployments

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.

git tag kenny

gitx-screen-6
Creating a new release tag ‘Kenny’

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 ‘Kenny’ by the dev team might be known as release 1.0 by our clients.

Ideally we would immediately upgrade all the deployments to the newest release. In practice this is not always possible, for example because we don’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 ‘deployments’ (why we use branches and not tags here will become apparent in the next section).

Let’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 ‘deployments/saas’ and ‘deployments/amazing-co’, respectively.

git checkout -b deployments/saas
git checkout -b deployments/amazing-co

gitx-screen-7
Creating deployment branches for the SAAS and Amazing-co deployments

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…

Hotfixes

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’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 ‘releases’. Thus, for a release named ‘kenny’ the hotfix branch is called ‘releases/kenny’.

git checkout releases/kenny

gitx-screen-8
Creating a hotfix branch for the ‘Kenny’ release

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 ‘HOTFIX:’.

gitx-screen-9
Cherry-picking a bug fix from master into the hotfix branch for the ‘Kenny’ release

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 ‘Kenny’ release.

git checkout deployments/saas
git merge releases/kenny

gitx-screen-10
Applying a hotfix to the SAAS deployment by merging the hotfix branch for the ‘Kenny’ release into the SAAS deployment branch

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 ‘Kenny’ release to the new ‘Stan’ release, we first rewind the SAAS deployment branch to the original ‘Kenny’ release tag and then fast-forward along the master branch to the ‘Stan’ release tag. However, before we can do all of this we need to remove the deployments/saas branch from our remote, otherwise it won’t let you push the changes as it thinks we’re behind of the remote branch.

git push origin :deployments/saas
git checkout deployments/saas
git reset –hard kenny
git merge stan
git push origin deployments/saas

gitx-screen-11
Before upgrading to the ‘Stan’ release, the SAAS deployment is at the head of the ‘Kenny’ hotfix branch

gitx-screen-12
The SAAS deployment has been rewinded to the ‘Kenny’ release tag

gitx-screen-13
The SAAS deployment has been fast-forwarded from the ‘Kenny’ release tag to the ‘Stan’ release tag

Once all the deployments have been updated to a new release, the hotfix branch for the previous release becomes ‘abandoned’. Although it is not in use anymore, we don’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.

gitx-screen-14
After upgrading the Amazing-co deployment to the ‘Stan’ release the ‘Kenny’ hotfix branch is now ‘abandoned’

Experimental branches

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 ‘experiments’ and the initials of the owner. For example, Kyle Broflovski can try out a Facebook integration plugin in a branch called ‘experiments/KB/facebook-integration’.

git checkout -b experiments/KB/facebook-integration

gitx-screen-15
Experimental work on Facebook integration taking place in a separate branch

Wrap-up

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.

Posted June 9th, 2010 by Lukas Spee
Logo
 

All the world’s flags in a sprite

For the short version: check out http://github.com/lafeber/world-flags-sprite

Lukas and I are working on a pet project when we’re traveling between Utrecht and Amsterdam. We’ve built a website that contains cheeses of many countries. I’ve been a fan of the famfamfam world flags for years, so it made sense to include them in the site.

You quickly get too many server requests when you have many separate images on one page. This is bad. So I thought of making a sprite of all the world’s flags. I’ve tried spriteme first but it didn’t work - my guess is there were too many images. Then I tried smartsprites which did the trick.

You run the command

./smartsprites.sh --root-dir-path ~/path_to_famfamfam/flags_iso/16

which generates a super long image and a new css file that looks like this:


.ad {
background-color:transparent;
background-repeat:no-repeat;
background-image: url('flags16.png');
background-position: left -336px;
}
.ae {
background-color:transparent;
background-repeat:no-repeat;
background-image: url('flags16.png');
background-position: left -352px;
}
.af {
background-color:transparent;
background-repeat:no-repeat;
background-image: url('flags16.png');
background-position: left -368px;
}
...

You’ll immediately notice a lot of duplication, which is unacceptable since there are more than 240 flags. I’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:


.f16 .flag{background:url(flags16.png) no-repeat}
.f16 .ad{background-position:left -336px;}
.f16 .ae{background-position:left -352px;}
.f16 .af{background-position:left -368px;}
...

An example of how you can use it in your site:

<link rel="stylesheet" type="text/css" href="http://cloud.github.com/downloads/lafeber/world-flags-sprite/flags32.css" />


<ul class="f16">
<li class="flag ar">Argentina</li>
<li class="flag au">Australia</li>
<li class="flag at">Austria</li>
...
</ul>

See http://www.cheesewiki.com/ (which lists all the worlds’ cheeses) for an example.

Note that you can’t use this in a https environment, and that images won’t show if github is down. However, if people have visited a site that uses the same css file, they won’t have to download it again which speeds up things drastically!

Posted March 15th, 2010 by Martijn Lafeber
Logo
 

iPhone version of our blog

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’t be polluted with RSS feeds. They should be websites instead of apps. Websites can have their own icon on the iPhone’s home screen.

With this in mind, I started to scaffold on my way back home. Commute by train is a bless.

The following gems were already installed:

I had used http://code.google.com/p/iui/ before.

Within two hours, http://iphonify.net/ was born. It allows anyone to claim their own url. For example, the iPhone version of this blog can be found at http://iphonify.net/ifdev.

If it weren’t for Rails - and the amazing plugins - I would have never been able to build this site that fast.

Posted January 8th, 2010 by Martijn Lafeber
Logo
 

Pair programming experiences

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 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.

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.

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 “tactical” aspects of completing the current task, using the observer as a safety net and guide.

Here are our experiences so far:

Martijn Lafeber: I really enjoyed pair programming. Especially because we’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.

Sam Aaron: 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’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’t normally find the time to talk about.

Lukas Spee: 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 — which gives you more confidence — and you discover errors earlier on — which saves you time. Another nice thing is that knowledge sharing takes place on the spot, as you code. And perhaps most importantly: it’s way more fun than solo programming.

Sjoerd Andringa: To me the power of pair programming lies in keeping each other focused and continuous communication. If a pair isn’t talking all the time they’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.

Posted December 31st, 2009 by Martijn Lafeber
Logo
 

never use sudo gem install again

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 them all to be in one place - ~/.gem - and I don’t want to type sudo gem install … again. And, most of all, I don’t want to see those annoying warnings when I type gem install …

Getting rid of the second warning is easy, just type

export PATH="$HOME/.gem/ruby/1.8/bin:$PATH"

To get rid of the first warning, put

:gemhome: /Users/{your_username}/.gem/ruby/1.8/

in the ~/.gemrc file.

All your gems will now be in ~/.gem/ and you’ll no longer see those annoying warnings when you do a gem install. YES!

–== UPDATE ==–

Apparently, instead of editing ~/.gemrc you can also type:

export GEM_PATH="$HOME/.gem/ruby/1.8"
export GEM_HOME="$HOME/.gem/ruby/1.8"

Thanks to Pat Allan, who wrote about it here

Posted October 26th, 2009 by Martijn Lafeber
Logo