Internationalizing a Knockout.js app

Here is a good way to do i18n with a Knockout.js app.

First off, use the i18n-js library.

Second, create a view model for translations:

I18nViewModel = (function() {
  function I18nViewModel() {
    this.locale = ko.observable("en");
  }

  I18nViewModel.prototype.t = function(key, options) {
    if (options == null) {
      options = {};
    }
    return ko.computed((function(_this) {
      return function() {
        options['locale'] = _this.locale();
        return I18n.t(key, options);
      };
    })(this));
  };

  return I18nViewModel;

})();

Then, whenever you need a string, just use an instance of your view model:

i18nViewModel = new I18nViewModel;
var translation = i18nViewModel.t('welcome.message.key', {name: "Dolly"})();

Because your view model returns a ko.computed, your view can update itself automatically whenever you change the locale:

i18nViewModel.locale('fr');

Et voilà! A simple solution for data-binding translations.

A low-energy mode for your Ubuntu laptop

Using Ubuntu on your laptop? Here is a quick how-to to increase your battery life.

First off, install powertop:

sudo apt-get install powertop

The Initial Benchmark

Start by benchmarking your battery to know what is the initial situation:

sudo powerstat

This should take a few minutes and tell you how much energy your battery is using. Here is an example output:

Running for 300 seconds (30 samples at 10 second intervals).
ACPI battery power measurements will start in 180 seconds time

Time       User  Nice  Sys  Idle   IO    Run Ctxt/s  IRQ/s  Watts               
16:44:46   1.0   0.0   0.3  98.7   0.1    1    725    228   5.85
16:44:56   0.9   0.0   0.2  98.8   0.0    1    715    245   5.81
16:45:06   2.1   0.0   0.5  97.4   0.1    2    943    336   5.90
16:45:56   1.3   0.0   0.3  98.3   0.2    1    781    306   6.11
16:46:06   2.8   0.0   0.7  95.7   0.9    2   1199    421  11.53
16:46:16   4.0   0.0   1.4  94.3   0.3    1   2205    686   6.46
16:46:26   2.9   0.0   0.7  96.2   0.2    6   1780    431   7.63
16:49:37   2.9   0.0   0.8  96.1   0.2    1   1854    333   6.63
-------- ----- ----- ----- ----- ----- ---- ------ ------ ------
 Average   2.2   0.0   0.6  97.0   0.1  1.3 1525.2  347.9   6.57
  StdDev   0.8   0.0   0.3   1.1   0.1  0.9  666.8   94.9   1.18
-------- ----- ----- ----- ----- ----- ---- ------ ------ ------
 Minimum   0.7   0.0   0.2  94.3   0.0  1.0  714.9  227.7   5.52
 Maximum   4.2   0.0   1.4  98.9   0.9  6.0 4528.3  686.1  11.53
-------- ----- ----- ----- ----- ----- ---- ------ ------ ------
Summary:
  6.57 Watts on Average with Standard Deviation 1.18

The last column (Watts) is what we want to see decrease.

The Tunables

Then use powertop to “toggle the tunables”. Run powertop and tab to the Tunables. Toggle on all that isn’t already on.

PowerTOP 2.5      Overview   Idle stats   Frequency stats   Device stats   Tunables                                     

-- Bad           Using 'ondemand' cpufreq governor                                                                      
-- Bad           Wireless Power Saving for interface wlan0
   Good          NMI watchdog should be turned off
   Good          Bluetooth device interface status
   Good          Enable SATA link power Managmenet for host4
   Good          Enable SATA link power Managmenet for host5
   Good          Enable SATA link power Managmenet for host2
   Good          Enable Audio codec power management
   Good          Enable SATA link power Managmenet for host1
   Good          VM writeback timeout
   Good          Enable SATA link power Managmenet for host0
   Good          Enable SATA link power Managmenet for host3
   Good          Autosuspend for USB device xHCI Host Controller [usb4]
   Good          Autosuspend for unknown USB device 2-1.5 (8086:0189)

Then run the benchmark again:

sudo powerstat

Hopefully the number of watts consumed dropped.

The Scripting

If the tunables did help, you might want to automate their toggling on. For that, you can run a powertop report:

sudo powertop --html

Then open the html report powersave.html and have a look at the Tuning tab. Under the header Software Settings in need of Tuning you can see all the commands required. It’s better to run the report after toggling off all the tunables so you can see all the commands—not just the ones for the tunables that are off.

powertop-report

Copy these commands in a script and you’re good to go. Here’s what my own script looks like:

#!/bin/bash
sudo iw dev wlan0 set power_save on
sudo modprobe cpufreq_ondemand > /dev/null 2>&1
echo '0' | sudo tee '/proc/sys/kernel/nmi_watchdog' > /dev/null
echo 'auto' | sudo tee '/sys/bus/pci/devices/0000:00:1f.3/power/control' > /dev/null
echo 'auto' | sudo tee '/sys/bus/pci/devices/0000:00:1f.0/power/control' > /dev/null
echo '1500' | sudo tee '/proc/sys/vm/dirty_writeback_centisecs' > /dev/null
echo 'auto' | sudo tee '/sys/bus/usb/devices/1-1/power/control' > /dev/null
echo 'auto' | sudo tee '/sys/bus/usb/devices/2-1/power/control' > /dev/null
echo 'auto' | sudo tee '/sys/bus/usb/devices/2-1.5/power/control' > /dev/null
echo 'auto' | sudo tee '/sys/bus/usb/devices/usb1/power/control' > /dev/null
echo 'auto' | sudo tee '/sys/bus/usb/devices/usb2/power/control' > /dev/null
echo 'auto' | sudo tee '/sys/bus/usb/devices/usb3/power/control' > /dev/null
echo 'auto' | sudo tee '/sys/bus/usb/devices/usb4/power/control' > /dev/null
echo 'auto' | sudo tee '/sys/bus/usb/devices/1-1.5/power/control' > /dev/null
echo 'auto' | sudo tee '/sys/bus/pci/devices/0000:00:1d.0/power/control' > /dev/null
echo 'auto' | sudo tee '/sys/bus/pci/devices/0000:00:02.0/power/control' > /dev/null
echo 'auto' | sudo tee '/sys/bus/pci/devices/0000:00:16.0/power/control' > /dev/null
echo 'auto' | sudo tee '/sys/bus/pci/devices/0000:00:1b.0/power/control' > /dev/null
echo 'auto' | sudo tee '/sys/bus/pci/devices/0000:00:1c.0/power/control' > /dev/null
echo 'auto' | sudo tee '/sys/bus/pci/devices/0000:02:00.0/power/control' > /dev/null
echo 'auto' | sudo tee '/sys/bus/pci/devices/0000:00:1f.2/power/control' > /dev/null
echo 'auto' | sudo tee '/sys/bus/pci/devices/0000:00:1c.3/power/control' > /dev/null
echo 'auto' | sudo tee '/sys/bus/pci/devices/0000:00:1a.0/power/control' > /dev/null
echo 'auto' | sudo tee '/sys/bus/pci/devices/0000:03:00.0/power/control' > /dev/null
echo 'auto' | sudo tee '/sys/bus/pci/devices/0000:00:1c.1/power/control' > /dev/null

You can also append the following for extra points:

sudo pm-powersave true
xbacklight -set 0

echo 'Stopping services'
sudo service bluetooth stop
sudo service postgresql stop
sudo service mysql stop
sudo service mongodb stop
sudo service redis-server stop

echo "You are now running in low-energy mode."
echo "You should disable networking in the nm-applet if you don't need an internet connection."
echo "And do not forget to disable the keyboard's backlight."
vim-write-mode

Write Mode For Vim

Vim is nice for coding but sometimes when it comes to writing essays or blogposts, it’s nice to be able to read and write text like a column from a newspaper. The idea is similar to what pyroom or writeroom do.

Here is a nifty write mode for vim. It will remove all clutter and create two ghost windows on each side of your main text. Add this to your .vimrc:

function! WriteMode()
wincmd n
wincmd L
7 wincmd <
hi NonText ctermbg=0 ctermfg=0
wincmd n
wincmd H
7 wincmd <
hi NonText ctermbg=0 ctermfg=0
windo set nonu
wincmd h
map j gj
map k gk
set laststatus=0
hi VertSplit ctermbg=0 ctermfg=0
echo "Write on."
endfunction

Map it like this:

map \w :call WriteMode()

And all you have to do is press \w and vim will go into writing mode.

Two katas for your dojo

If you are organizing a coding dojo and are looking for katas, here are two javascript (or coffeescript) katas you could use:

  • A functional kata where the goal is to implement from scratch various list functions like any or none or zip. This kata is not too hard and a good introduction to TDD or basic list operations.
  • The poker kata where the goal is to rank poker hands. This kata is quite a bit harder but good fun.

Have fun dojo-ing these katas.

And if you’re wondering what’s with the funky vocabulary, have a look at What Is A Coding Dojo.

Searching for a virtual volunteering platform

I have been trying to volunteer remotely as a web developer for a few years now—with mixed results. I believe it is much harder to volunteer remotely than it should be. There are platforms to volunteer online but my experience with them is frustrating. Whether it’s about building websites, designing logos, or translating documents—I wish virtual volunteering were easier.

Searching

First off, searching for volunteering opportunities is difficult. Searches usually turn up either no results at all or way too many results to be manageable. And then these opportunities might or might not be a good match for the skills of the volunteer.

A good volunteering platform should quickly get rid of opportunities that are out of date and allow the volunteers to filter the search according to skills. Even better, the platforms could allow the volunteers to specify skills and to only search opportunities based on those specified skills. Email alerts could also be sent automatically to notify volunteers of new opportunities.

The Problem Descriptions

And then the problem descriptions are often incomplete or ambiguous. A clear problem description makes it easy to commit to a problem with confidence. Ideally, an editor would work on the problem descriptions with the organizations asking for volunteers. The editor could also make sure that all the required information to solve the problem is available.

And how about offering a time estimate along with the problem description? What if all the problems would have to be solvable in one or two blocks of 4 hours? I think that would help define the problems finely and make it easy for volunteers to deliver something quickly. Short tasks also make it more likely that volunteers will finish the work without going off and forgetting about the problem. Longer pieces of work could still be posted on the platform, but they would have to be broken down into smaller tasks. This is similar to micro-volunteering.

Collaboration Among Volunteers

One benefit of smaller tasks adding up to one big piece of work is that it is easier for volunteers to collaborate. Lots of developers can pick up small tasks and contribute on top of each other’s work.

Also, most online platforms make you contact the poster of an opportunity if you want to help. This introduces delays. Perhaps a better system would be more akin to a bug tracker. Volunteers could pick up a problem, assign it to themselves, and start working on it right away. When they are done, they mark the problem as done and submit their solution. If the solution is acceptable to the organization, the volunteer is thanked and the problem is removed from the list of opportunities.

That kind of framework would make it easy for volunteers to jump in and collaborate immediately. Virtual volunteering can be lonely but it doesn’t have to be.

Other Stuff

It would also be nice for the platform to be restricted to virtual volunteering. Virtual volunteering is too different from face-to-face volunteering.

Perhaps charging a small fee to the organizations asking for volunteers could increase the quality of the problem descriptions.

Perhaps offering a permlink to a résumé-like page for each volunteer (listing past contributions) could flatter the ego of volunteers and give them a reason to achieve more.

In The End

In short, here is what I think a volunteering platform should have:

  • A moderation team to work on problem descriptions with the organizations
  • A short list of problems that are varied and up to date
  • A list that contains small problems that can be picked up anytime
  • A way for volunteers to specify their skills and receive alerts based on those
  • A résumé-like page for each volunteer to list all past contributions

What do you think? Would you sign up to such a platform? Or do you find existing platforms good enough?

What is missing for you to volunteer virtually?

A bar chart with d3.js

I just spent some time trying out d3.js—a visualization library. The library is quite powerful and can be used to visualize complex bits of data. (Just have a look at the examples gallery.)

My impression of the library is excellent—in the case where you have complicated visualization needs. For simple charts, you are probably better off with something like Google Charts.

You can see the bar chart I came up with over here, as well as the github repository for it. It’s a twitter search for popular retweeted tweets. Here is a screenshot:

A bar chart in d3.js

A bar chart in d3.js

The Code

The drawing code reads like this:


var graph = {
 data: null,
 oldWidth: null,
 resizeTimer: null,

guardedUpdate: function(){
   var width = $("body").width();

if (graph.oldWidth !== undefined && Math.abs(width - graph.oldWidth) < 20){ return; }
 this.oldWidth = width;
 this.update(this.data);
 },

update: function(data){
 this.data = data;

data.sort(function(a, b){
 return b.retweets - a.retweets;
 });

var width = $("body").width();
 var barHeight = 30;
 var barPadding = 30;
 var axisMargin = 25;
 var leftMargin = 12;

var x = d3.scale.linear().domain([0, d3.max(data.map(function(i){return i.retweets;}))]).range([0, width - 150]);

var xAxis = d3.svg.axis().scale(x).orient("top");

var chart = d3.select(".chart")
 .attr("width", width)
 .attr("height", (barHeight + barPadding) * data.length + axisMargin + barPadding);

chart.selectAll("g").remove();

var bar = chart.selectAll("g").data(data).enter().append("g");

bar.attr("class", "bar")
 .attr("transform", function(d, i) { return "translate(" + leftMargin + "," + (i * (barHeight + barPadding) + axisMargin + barPadding) + ")"; });

bar.append("rect")
 .attr("height", barHeight - 1)
 .on("click", function(d){open(d.link);})
 .attr("width", 0);

var transition = chart.transition().duration(1000);
 transition.selectAll("rect").attr("width", function(d){return x(d.retweets);});

bar.append("text")
 .attr("class", "tweet-text")
 .attr("x", 0)
 .attr("y", -10)
 .attr("dy", ".35em")
 .on("click", function(d){open(d.link);})
 .text(function(d){return d.tweet});

bar.append("text")
 .attr("class", "author")
 .attr("x", function(d) { return x(d.retweets) + 4; })
 .attr("y", barHeight / 2)
 .attr("dy", ".35em")
 .text(function(d) { return d.username; })
 .on("click", function(d){ open(d.user_link); });

bar.append("text")
 .attr("class", "count")
 .attr("x", function(d){var maximum = x(d.retweets) - ((d.retweets + '').length * 15) - 10; return maximum < 0 ? 1 : maximum;})
 .attr("y", barHeight / 2)
 .attr("dy", ".35em")
 .on("click", function(d){open(d.link);})
 .text(function(d) { return d.retweets; });

chart.append("g")
 .attr("class", "x axis")
 .attr("transform", "translate(" + leftMargin + "," + axisMargin + ")")
 .call(xAxis);
 }
};

$(window).on('resize', function(e){
 clearTimeout(graph.resizeTimer);
 graph.resizeTimer = setTimeout(function() { graph.guardedUpdate(); }, 100);
});

That last part using window.onresize does not have anything to do with graphing but it is used to redraw the graph every time the browser window is resized.

The JSON

And then the graph expects a bit of json that looks like this:

{ "results" : [ { "link" : "https://twitter.com/Greenpeace/status/404998719411453952",
        "retweets" : 191,
        "tweet" : "REVEALED: @Shell is number 6 in the list of companies most responsible for #climate change: http://t.co/l1LEqk2Qxi http://t.co/pMP0wH3PAT",
        "user_link" : "https://twitter.com/Greenpeace",
        "username" : "@Greenpeace"
      },
      { "link" : "https://twitter.com/Greenpeace/status/404960418310787072",
        "retweets" : 91,
        "tweet" : "READ: #Gazprom is number 5 in the list of companies most responsible for #climate change: http://t.co/l1LEqk2Qxi http://t.co/JutGGyu32l",
        "user_link" : "https://twitter.com/Greenpeace",
        "username" : "@Greenpeace"
      }
  ]
}

A comparison of CSS frameworks

Here is a quick comparative analysis of a lot of CSS frameworks. Some of them are quite minimal and only offer a way to layout your components in a grid (unsemantic, fluidable). Others give it to you whole and offer a grid layout, a CSS reset, icons and styles for all the components you’ll want to display (Bootstrap, Foundation, UIkit).

I have used or would be happy to use any of the five frameworks I linked to above. My notes on these and other frameworks are below.

If you would like to quickly try it out for yourself, feel free to clone this git repository and fiddle with the file index.html for each framework.

Also, see this cool chart for a quick overview of all the frameworks.

Twitter Bootstrap

Pros:

  • Simple to use
  • Images and icons and widgets
  • Large user base
  • Good documentation
  • Usable

Cons:

  • A lot of extra html needed

Foundation

Pros:

  • Good doc
  • Lots of widgets
  • Icons, though separate from the main release
  • Advanced layout options
  • SCSS

Cons:

  • Default styling not so usable
  • Layouts can get complex

UIKit

Pros:

  • Advanced layouts
  • Icons
  • Javascript stuff
  • Minimal looks
  • Good doc

Cons:

  • Lots of classes to add

Knacss

Pros:

  • Simple and small
  • Some icons
  • Responsive layout
  • Fairly good documentation

Cons:

  • No stylings for things like headers and action buttons
  • Strange class names

RöCSSti

Similar to Knacss. Documentation lacking.

Jaidee

Pros:

  • Simple to use
  • Some widgets like insets and blockquotes and buttons and lightboxes

Cons:

  • Documentation looks weak
  • No images
  • Not lots of widgets

YAML

Pros:

  • Advanced layouts with simpler alternatives if the 12-column layout is not needed
  • Lots of widgets
  • Sass
  • Some icons

Cons:

  • A lot of classes required + unclear conventions for class names
  • Not lots of icons
  • Lots of files to include to get started

Blueprint

Pros:

  • Minimal
  • Styles a lot of things by default
  • Very simple to use

Cons:

  • No widgets
  • No icons

Unsemantic

Pros:

  • Minimal
  • Easy to use

Cons:

  • Nothing but a grid layout (could be a pro too)

Gumby

Pros:

  • Has widgets and icons and stuff
  • Good documentation
  • Easy to use and customize

Cons:

  • Weird classes for buttons
  • Strange UX choices (default style hard to read or icons in the wrong place)

Fluidable

A minimal grid-only framework.