spacer

Olivier Lalonde's blog

Hey. I'm a friendly hacker, HN addict and startup guy. I tweet as @o_lalonde.

Tweet

Pagination With Handlebars

Pagination can be quite tricky with Handlebars since Handlebars does not have any built in way to do for/while loops. One solution mix some presentation code within your logic layer and passing an array containing all your pages in an array.

For example:

1
2
3
4
5
6
7
8
9
10
{
  pagination: [
    { previous: disabled },
    { page: 1, active: true },
    { page: 2 },
    { page: 3 },
    { page: 4 },
    { page: 5 }
  ]
}

This solution has several drawbacks: mixing of logic/view code, code duplication, difficult to reuse, etc.

The other, cleaner solution, is to write a Handlebars helper, which I have already done so you don’t have to!

spacer

The helper is available for download or forking on Github:

https://github.com/olalonde/handlebars-paginate

or through NPM:

1
npm install handlebars-paginate

To use it, all you have to do is register it as an helper:

1
Handlebars.registerHelper('paginate', require('handlebars-paginate'));

And all you need to pass to your template is an object containing a page parameter which is the number of the current page and a pageCount parameter which is the total number of pages.

For example:

1
2
3
4
5
6
{
  pagination: {
    page: 3,
    pageCount: 10
  }
}

Handlebars-paginate let’s you define three types of blocks in your template:

middle:

This will iterate over all the possible pages. An optional limit parameter is available if you’d like to limit how many page links to display. limit=7 will only display 3 links to the left of the active page and 3 pages to its right.

For example:

1
2
3
{{#paginate pagination type="middle" limit="7"}}
  <li {{#if active}}class="active"{{/if}}><a class="?p={{n}}">{{n}}</a></li>
{{/paginate}}

previous and next:

Finally, previous and next are used to define how you want to display the “previous” and “next” buttons.

For example:

1
2
3
{{#paginate pagination type="previous"}}
  <li {{#if disabled}}class="disabled"{{/if}}><a class="?p={{n}}" >Prev</a></li>
{{/paginate}}
1
2
3
{{#paginate pagination type="next"}}
  <li {{#if disabled}}class="disabled"{{/if}}><a class="?p={{n}}">Next</a></li>
{{/paginate}}

Enjoy and feel free to fork or report issues!

Tweet

How to Follow HTTP Redirects in Node.js

One of the biggest annoyance with Node.js’ native HTTP and HTTPS clients is that there is no way to automatically follow HTTP redirects. Let’s say you want to fetch the content of a page that has moved (301 redirect), you will have to write a lot of boilerplate code to handle the redirect(s) by yourself.

Since following redirects is fairly common, I decided to write a a drop-in replacement for the native HTTP and HTTPS module that would handle redirection seamlessly.

This module has exactly the same interface has the native HTTP and HTTPS module but it will handle redirects automatically. In other words, if you want to automatically start following redirects, all you have to do is replace

1
var http = require('http');

by

1
var http = require('follow-redirects').http

Before that, you will of course need to install the module through NPM:

1
npm install follow-redirects

Here are some usage examples:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
var http = require('follow-redirects').http;
var https = require('follow-redirects').https;

/* 
 * http and https are just like Node.js' http and https modules except 
 * that they follow redirects seamlessly. 
 */

http.get('bit.ly/900913', function (res) {
  res.on('data', function (chunk) {
    console.log(chunk);
  });
}).on('error', function (err) {
  console.error(err);
});

/*
 * You can optionnally pass the maxRedirect option which defaults to 5
 */

https.request({
  host: 'bitly.com',
  path: '/UHfDGO',
  maxRedirects: 3
}, function (res) {
  res.on('data', function (chunk) {
    console.log(chunk);
  });
}).on('error', function (err) {
  console.error(err);
});

More info is available at the Github repository: https://github.com/olalonde/follow-redirects/

Tweet

Tips and Tricks When Learning a New Technology

In this post, I’ll share some tricks I use before diving into a new technology. Technology could mean anything from programming language to an operating system (note that some steps are specifically for programming languages/frameworks).

For the sake of demonstration, I’ll pretend that I want to learn the Haskell programming language.

Wikipedia

spacer

Get a high level perspective of the technology by reading its Wikipedia page.

en.wikipedia.org/wiki/Haskell_(programming_language))

Hacker News

spacer

Get hands on feedback from people who have previous or current experience with the technology through comments. Find interesting articles about the technology (by popularity or date) through stories.

Stories: www.hnsearch.com/search#request/submissions&q=haskell&sortby=points+desc&start=0

Comments: www.hnsearch.com/search#request/comments&q=haskell&sortby=points+desc&start=0

StackOverflow / StackExchange

spacer

Find out the highest voted questions relating to the technology. It is very likely that you’ll have those questions as well when learning the technology so why not find out the answers right now. There will also usually be a question about the best resources to learn from. This can be a good starting point for your own learning process.

stackoverflow.com/search?tab=votes&q=title%3ahaskell

stackoverflow.com/questions/tagged/haskell?sort=votes&pagesize=15

GitHub

spacer

Find out the most popular open source projects that relate to the technology. This is especially helpful when you start a project with this new technology and aren’t sure which are the latest and greatest libraries to use. It’s also a good idea to study the codebase of open source projects to get familiar with common idioms and coding styles.

https://github.com/search?langOverride=&language=Haskell&q=language%3Ahaskell&repo=&start_value=1&type=Repositories

IRC

spacer

Find out if the technology has an IRC channel. You can usually find that out by simply connecting to Freenode and joining #technology-name or Googling irc technology-name.

https://www.google.com/?q=haskell%20irc

Conclusion

Don’t forget many people have gone through what you are about to go through. Don’t repeat the same mistakes they did and leverage every piece of information you can from them!

I’d love to hear more tips and tricks in the comments below.

Tweet

Using the Debugger Statement With Node-inspector

The first thing client-side Javascript developers miss when starting out with Node.js is the ability to debug their code through a GUI debugger as they are acustomed to when developing for the browser.

Fortunately, it wasn’t long before the Node.js community came up with GUI debuggers and as of today, the most widespread one is node-inspector.

In this post, I won’t go into the details of using node-inspector but I will instead introduce a neat feature that many Node.js developers aren’t aware of or don’t know how to use.

This feature is called the debugger statement. If you have ever caught yourself firing up node-inspector and browsing through the huge file pane on the left in order to find a file and insert a breakpoint, then this post should save you a lot of trouble in the future.

Here’s what the ECMA-262 specification has to say about the debugger statement:

Syntax

DebuggerStatement :

debugger ;

Evaluating the DebuggerStatement production may allow an implementation to cause a breakpoint when run under a debugger. If a debugger is not present or active this statement has no observable effect.

In other words, you can insert breakpoints directly in your code using debugger;, fire up your app in debug mode, open your debugging client and the breakpoint will be set. Don’t forget to remove debugger; from your code once you are done debugging!

Here’s a quick demonstration.

  1. Insert debugger; statement in your code

    spacer

  2. Fire up node-inspector

    bash node-inspector;

  3. Launch your app in debugging mode (don’t forget to use the --debug-brk flag if your debugger statement is “early” in your code)

    bash node --debug server.js

  4. Open the debugging client

    spacer

No more hunting for files!

Tweet

Don’t Run Node.js as Root!

The root user on Linux and Unix operating systems is a special user that has absolutely total power over a machine. It is therefore very important to use the root account only when absolutely necessary and preferrably through the use of a program such as sudo. From Wikipedia:

In operating systems which have the concept of a superuser, it is generally recommended that most application work be done using an ordinary account which does not have the ability to make system-wide changes.

Indeed, if you are running your server as root and it gets hacked through a vulnerability in your code, the attacker will have total control over your machine. This means the attacker could potentially wipe out your whole disk or worse. On the other hand, if your server runs with the permissions of a regular user, the attacker will be limited by those permissions.

The problem most Node.js developers will face is that in order to open ports below 1024 (i.e. port 80), one has to possess superuser permissions. There are a few solutions around that problem, one being the use of iptables to redirect port 80 to a higher port such as port 3000 and another one being the use of a proxy such as nginx that will redirect requests to your server. However, today I will focus on a solution that can be done entirely within your code.

We still start our server with root permissions using sudo but once we have opened our port(s), we will revert back our server’s permission to that of a regular user using a special trick. That trick is to read the SUDO_UID environment variable which sudo passes to any process it launches and using Node’s global process.setuid() function.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var http = require('http');

var app = function(req, res) {};

http.createServer(app)
  .listen(80, function(err) {
    if (err) return cb(err);

    // Find out which user used sudo through the environment variable
    var uid = parseInt(process.env.SUDO_UID);
    // Set our server's uid to that user
    if (uid) process.setuid(uid);
    console.log('Server\'s UID is now ' + process.getuid());
  });

No excuses for running your server as root anymore!

Tweet

A Better Require() for Node.js

UPDATE: better-require now supports json, yaml, csv, xml, ini as well as coffeescript, clojurescript, typescript, dart and six.

While reading the Node.js API documentation today, I stumbled upon an interesting feature. This feature let’s you add handlers for arbitrary file extensions that require() will call when requiring a file of that extension. Internally, it looks for the extension in require.extensions and if the extension is found, the handler is called instead of the default require routine.

I thought that was pretty cool so I couldn’t resist the urge of wrapping a bunch of file parsers into a standalone NPM module that would make it easy to support for multiple file formats through require().

This gave birth to better-require.

npm install better-require

If allows developers to seamlessly require json, yaml, csv, xml and ini files without having to deal with require.extensions or finding the appropriate parsing libraries. It is also easily extensible so feel free to fork and add additional file formats!

Here’s a usage example:

1
2
3
4
5
6
7
8
9
10
11
require('better-require')('json yaml xml');

// we can now require .xml, .yaml and .xml files!

var yaml = require('./config.yaml')
  , json = require('./config.json')
  , xml = require('./config.xml');

console.log(yaml);
console.log(json);
console.log(xml);

Enjoy!

Tweet

Migrated Blog to Jekyll

I just finished migrating my blog from Posterous to Jekyll. Posterous was acquired by Twitter a few months ago and is now in maintenance mode. I’m now hosting this blog for free on Github and use Octopress/Jekyll to generate the files. So far, it is really a joy to write all my posts in Markdown. I’m basically blogging from Vim right now (and using the Hammer plugin to preview my posts). I wish I had done this move earlier.

<3 Jekyll + Octopress + Github + Markdown + Vim + Hammer.vim

Please let me know if you find any broken links or images not loading: olalonde@gmail.com.

Thanks!

Tweet

17 Crazy and Not So Crazy Startup and Project Ideas

So today I am cleaning up my phone’s Memo app so this post will be dedicated to dumping all those late night ideas I had when I was very tired or had a few too many beers. Note that I had most of those ideas independently but some of them were (partially) implemented later on or I simply hadn’t heard of them.

1. Beetcoin

Mobile app that acts as a nice UI on top of various Bitcoin exchanges. It should be possible to view pending trades, get current bid/ask prices and place new trades.

The twist: Sell it as a paid app and give away “free” Bitcoins. The app should be expensive enough that when you give away Bitcoins you still make a profit.

Why it will work: This would enable regular people to buy Bitcoins with their credit card by buying the app on the Android market.

Why it won’t work: It is possibly against most markets / credit card processors TOS.

2. Code reading web app

Reading other people’s code is one of the surest way to improve your programming skills. For each programming language, this app would list open source projects by difficulty level (from beginner to expert) and make it easy to browse and comment the code from within the website. The MVP could simply list links to Github repos. Inspiration comes from todomvc.com.

Use case: I just started to learn Javascript and I want to see some real world Javascript code. I go to the site, select the Javascript language and I can see a list of projects rated from Beginner level to Expert level. Each projects that are at the same difficulty level are grouped together. The beginner level should list simple “Hello world” apps while the expert level should be reserved for complex projects.

3. Prediction market, Hacker News style

Not sure what I meant when writing this. I think the idea is that it would be a news aggregator like Hacker News but when you vote up it costs you real money (you are investing in a vote). If the vote count goes up, you are rewarded for predicting correctly that the article was interesting to the community. The reward should be proportional to how many people up voted after you. I guess someone still needs to work out the “details”. The whole idea is to mix karma with money to self-moderate a community (most people care more about money than karma).

4. OAuth for payments

I’m not sure why I haven’t seen this yet in the wild. Probably due to legal compliance and security issues. But well, I think it would be cool if I could just buy stuff by clicking “Pay 10$” and whenever I click that button, I get the standard OAuth dialog asking me to authorize the payment. There should be a maximum amount by transaction which should be fairly low if security is an issue (50$?).

5. URL#hash renderer API

I first had this idea when developing a website with Backbone.js. All my URLs looked like domain/#a/b/c and I thought it would be nice if my server could proxy all requests to domain/a/b/c through an API that returns the rendered HTML of domain/#a/b/c.

Some websites are not crawlable or unusable if users don’t have Javascript enabled. This service takes an url of the form domain/#hash and returns the rendered HTML that a user would see if they had Javascript enabled. Web developers could use this service to easily offer a crawlable website that is friendly to visitors that have Javascript disabled.

6. Startups for front-end developers

Build a service that makes it possible to develop a full website completely on the client side (probably using Backbone.js or similar), interfacing with a list of predefined APIs. This startups’ job would be to take care of providing a list of easily accessible APIs and make it easy for designers to publish UIs that interact with the APIs. The startup should also take care of common issues like cross-origin request sharing, caching, etc. Eventually, there would be a market where dev

gipoco.com is neither affiliated with the authors of this page nor responsible for its contents. This is a safe-cache copy of the original web site.