• Quick Fix: Bring Back the Scroll Buttons to GMail

    There’s been some noise on the ‘net about missing scroll up/down buttons in the new Google design. Note that this only affects the browsers based on WebKit (Chrome, Safari and some KDE browsers, to name a few). Here’s a way to fix that.

  • Mostly Shiny: Vector Graphics with MVVM in the Browser

    I’d like to show you how to make two great libraries work together: Raphael and Knockout. I’ve built the basics of a purely browser-based application for creating simple graphs (as in “graph theory”). This article was supposed to be a longish explanation of how it all works, but unfortunately I’m really short on time.

    • The working example is here
    • And the docco-annotated source code is here

    Some links and introductions are in order

    Raphaël: ”a small JavaScript library that should simplify your work with vector graphics on the web”. It also includes a handy light-weight event framework called “eve” (yes, another one; yes, its good enough to exist). It’s a very useful common interface to SVG and VML (which is what IE supports instead of SVG).

    Knockout: a library implementing MVVM for the browser, with dependency tracking and template support using jquery.tmpl.

    MVVM: a design pattern that can be considered an alternative to MVC in some respects. The idea is that view-models (VM) and views (the first V) are bound once, and they automatically update anything connected to them when they change, while updating some kind of storage (the first M). The storage is neglected in the example, but it’s supported just fine by Knockout.

  • Linux Server Security Tips


    (I am not a disclaimer. Oh wait, yes I am.)

    I’m not a system administrator by training. All of this information can be found online; this is only a collection that I hope may come in handy for someone. Let me emphasize that you don’t get a secure system just by following these instructions. That said, I’ve listed all the security measures I’ve taken to protect the server running this blog at the time of writing; this setup is good enough for me. Still, the server has no sensitive information, and I’m not a sysadmin.

  • Proposal: a Community-powered Collection of PHP Best Practices

    Scott Griepentrog kindly rented a domain to use for this purpose and set up a publicly accessible Google Sites page. All that’s missing now is great content (actually, maybe not, if you’re from the future). You can find the wiki at http://phpfu.org


    We all know the old argument on why PHP is often seen as a “bad” language: the barrier of entry is low, so lots of people will write PHP code without learning the fundamentals. However, the arguments usually stop there. Known fact, there’s nothing we can do. But maybe there is?


    Let me be clear: I don’t want to teach design patterns to everyone who makes a worship site for their dog. What I’d like to see, and what I’m really missing, is a central repository of best practices for solving common middle to high-level problems. Ideally in a wiki format. What would this bring to the table? It would tell you that is, indeed, thoroughly solved, and also how it’s done. It can also be thought of as a FAQ of sorts, or a collection of best practices (emphasis on best).

    Yes, Google is usually your friend. What Google doesn’t do is code review of blogs and tutorials. Let me give a trivial example: I’ve googled really hard when I needed to implement a secure authentication scheme. What I found was tens of “simple login script with PHP and SQL”. What I finally ended up with is basically what Phpass is doing – dynamic and static salts, bcrypt, you know the drill. It’s not as extensible or general, but the theory (and probably the security) is there. What I didn’t know was that Phpass existed. My Google-fu must have been weak that day or something.

    I just looked until I found something good enough and went with it. I feel this is characteristic of a lot of development, and not always a bad thing. On the other hand it takes real experience to know what’s good enough, and this experience can come at a high price (especially when considering security).

    So what would this proposed wiki say on the topic of secure password storage?

    Probably something like: “Use Phpass”. There, it’s not that complicated. Probably include a few good samples of using it, and we’re golden. A full framework-independent example of a complete secure authentication scheme would be killer. Mention OpenID as a full-fledged alternative, probably.

    Yes but this still assumes that the developer who needs the information realizes that s/he needs it!

    Indeed. However, by making it explicit that such-and-such information can be found here, it’ll be constantly at the back of the developers mind. If it’s easy to reach, maybe we’ll start looking even when we have a full solution in mind. You know, just in case. We can do that now, but (a) making sure we don’t miss a good resource because it’s three pages down in DuckDuckGo and (b) making it really quick to check on a topic instead of reading several articles can only be a good thing.

    Why is it that only PHP need such a resource?

    This is a valid question. I’m pretty sure some languages/frameworks already have this (probably called a manual or somesuch). It’s usually the documentation of a framework, so of course the documentation of PHP-the-language can’t be expected to contain these things.

    Why doesn’t this exist already?

    I can probably be convinced that not even PHP needs this. Or is there such a site out there already, and I just missed it? If there isn’t, why not? Is it redundant, not worth it? Does everyone just go with “good enough”?

    Is this feasible? Let’s start one!


    Phpass being the bestestest password storage solution is not the point of the post. Feel free to name alternatives. Also, most of this rant is based not on any statistical data, only my “gut feeling”.

  • Node.js, Express and CoffeeScript

    The solution oultlined here uses the compiler Connect middleware, which was removed in Connect 1.7 (and therefore in newer Express.js versions). The new alternative is connect-assets. Thanks to Marcel Miranda for pointing this out.

    I’ve been working on a moderately complex hobby project for a while using Node.js and CoffeeScript. This is the first of a few posts on what I’ve learned so far. This time: using CoffeeScript on the client- and the server-side and auto-compiling client side scripts on the fly with Express.

    The goal of the project is, by the way, to illustrate some common algorithms in the browser. You can check it out at GitHub: , or see a running version at http://algo-abesto.dotcloud.com. The blank area next to the controls is where you can draw your graph.

    Server side

    The theory is simple: CoffeeScript code is equivalent to JavaScript code. Node.js can thus be programmed in CoffeeScript. In practice, things turn out to be just as simple: write your code in CoffeeScript, use the file extension .coffee, and use coffee app.coffee to start your application. Even require works out of the box. You can see an example here (using Express)

    Client side

    This section assumes you’re using the Express web framework.

    Express has support for compilers, and a compiler is shipped for CoffeeScript. Setting up the paths is not well documented, unfortunately. Here’s how it works: for each compiler you’ll specify a src and a dest folder, without a trailing /. The request path sent by the browser is appended to this.

    http://localhost:9000/js/foo/bar.js will map to the source file src/foo/bar.coffee and the compiled file dest/foo/bar.js. If the compiled file doesn’t exist or is older than the source file then it will be (re)compiled. If there’s an error during compilation, then the browser will receive a 500 error.

    What will NOT be done is:

    • Express won’t remove the compiled file if the source file is removed
    • Express won’t create any missing directory structure. If dest/foo doesn’t exist, then Express will return a 404 error to the browser. If you know how to work around this, please write a few lines :)

    Note: this was originally posted to a previous version of this blog on 01. November 2011.