Building a simple blog with NodeJS and Express

After installing NodeJS and creating a basic web application with
Express
I wanted to get deeper into the world of node and build
another simple, but useable web app. Because I like to blog, I decided
to build a blog.

You can check out the result at https://github.com/MoriTanosuke/blode/
and clone it.

I decided to stick with express and jade as my templating
engine, because I already now how to use those. But because this blog is
made with jekyll and I like to think that I can eventually replace
the jekyll blog with a node blog, I wanted my blog entries written
in Markdown. Fortunatly, node can easily display markdown with
node-markdown.

I started with a simple route that walks down into a directory “blog”,
gets all files and renders a template when the files are fetched:

exports.list = function(req, res){
  var walk = require('walk'), fs = require('fs'), options, walker;
  // walk into directory "blog"
  var walker = walk.walk('blog');
  var fs = new Array();
  walker.on("file", function(root,file,next){
    // get the file, but remove file extension
    var f = root + "/" + file['name'].substring(0, file['name'].lastIndexOf('.'));
    // push without /blog prefix
    fs.push(f.substring(f.indexOf('/')));
    next();
  });
  walker.on("end", function() {
    res.render('blog', { title: 'Entries', files: fs })
  });
};

Then I created a simple view named ‘blog’ which displays all the files:

h1= title
!=partial('listing', {files: files})

Ok, I cheated a little bit, because the actual file listing is done in a
partial, which basically is a reusable part of a view. The partial
‘listing’ isn’t complicated either:

ul
  - each file in files
    li
      a(href='#{file}') #{file}

As you can probably tell, this jade partial will render a simple unordered list with links
to the given files. Ok, so now I have a list of files under directory /blog. What happens
when I click one of the links?

Another route takes over:

exports.entry = function(req, res){
  var md = require('node-markdown').Markdown;
  res.render('entry', { content: md('' + require('fs').readFileSync('blog/'
     + req.params.year + "/" + req.params.month + "/" + req.params.day + "/"
     + req.params.title + ".markdown")), title: req.params.title });
};

Now this route builds a filename from the given parameters, reads its
content, renders the content as markdown and renders the template ‘entry’:

div.entry !{content}

div.nav
  ul
    li
      a(href='/') back

div.comments
  p Feel free to add your comment system here.

Again, a very basic template. I simple put all the markdown into a
div with class entry, add a link to the homepage and another div
for a later addition of comments, probably using disqus.

Now I have 2 routes: one route walks through my filesystem and gets a list
of files, another route displays the given content and adds a very basic
navigation. What’s missing at this point is the connection between the
routes.

Here is the relevant part from my app.js file that connects my routes
with actual URLs the user enters into the browser address bar:

app.get('/', routes.list);
app.get('/:year/:month/:day/:title', routes.entry);
app.get('*', function(req, res){ res.send('Uh, what?', 404); });

The first route shows the homepage with the list of entries. The second
route displays an entry when the user clicked a link. The third route is
an error handler that will display a very helpful error message when the
user enters a non-existant URL.

Remember, if you want to check out my code, clone me from github and run
the blog on your own machine:

    git clone git@github.com:MoriTanosuke/blode.git
    cd blode
    node app.js

Now you can open http://localhost:3000 and check the blog out.

For my development I used a very nice script, node-supervisor. It
watches your files and restarts node when needed. That way every time I
save a file in my editor, the server restarts and I can reload the page to
see my changes. Just run the application with supervisor instead of node:

npm install node-supervisor
   supervisor app.js

I really like my development cycle fast and without manually restarting stuff
every couple of minutes.

The one thing gone awry

When I tried to put a basic stylesheet in place, I noticed that I couldn’t
open the stylesheet at http://localhost:3000/stylesheets/style.css. I thought
about this for a couple of minutes and verified that the file is actually
in the directory /public/stylesheets in my application.

After searching the internets I found that in my app.js the following lines
were present:

app.configure(function(){
  // ...
  app.use(app.router);
  app.use(express.static(__dirname + '/public'));
});

If I got the explanation right, this means that my own routes come before
the static assets. So when I tried to open my stylesheet the error handler
kicked in because none of my 2 other rules applied. The solution to this is
re-ordering the configuration:

app.configure(function(){
  // ...
  app.use(express.static(__dirname + '/public'));
  app.use(app.router);
});

Now the static assets are always served before my own routes apply.
Everything works, my stylesheet is in place.

Install NodeJS with NVM

Today I started my first steps into the world of server-side javascript with nodejs. First thing was installing NVM, the node version manager. You can do that with this simple steps:

git clone git://github.com/creationix/nvm.git ~/.nvm
. ~/.nvm/nvm.sh

After that you can go ahead and install nodejs:

nvm install v0.7.1

Now you need to download an IDE, a compiler, an enterprise service bus… oh no, wait. Just open your texteditor, paste the following text:

var http = require('http');
http.createServer(function (req, res) {
  res.writeHead(200, {'Content-Type': 'text/plain'});
  res.end('Hello Worldn');
}).listen(1337, "127.0.0.1");
console.log('Server running at http://127.0.0.1:1337/');

save it as simpleserver.js and then run it with

node simpleserver.js

Now you can point your browser to http://127.0.0.1:1337/ and you’ll see the response of your first application with nodejs.

Know your CRLF in git

Today I wanted to install nodejs on my debian machine, and I got stuck with strange errors about command not found. I hate to admit it, but it was the fault of strange CRLF and the fix was setting my git defaults to a sensible value:

git config --global core.autocrlf false

If you want the reasoning behind this, read http://code52.org/line-endings.html and then set it. But set it.

After that I could install nodejs with one simple line of nvm. I’ll write about that soon.

Das erste Brot

Heute habe ich das erste Mal (ok, das zweite Mal, aber das erste Mal wollt ihr ganz bestimmt nicht wissen…)
ein eigenes Brot gebacken. Ich habe dazu meinen eigenen Sauerteig angesetzt und mit einem einfachen
Weizensauerteigrezept weiterverarbeitet. Die Zutaten waren ungefähr

  • 350g Sauerteig
  • 350g Weizenmehl
  • 20g Salz
  • 250ml Wasser
  • 10g Hefe

Das ganze habe ich zu einem Teig vermischt, der zwar recht klebrig war, sich aber mit etwas Mehl gut
genug behandeln liess, um ihn in eine kleine Kastenform zu geben.

Vor dem Backen

Da drin hab ich den Teig dann ca. 20min gehen lassen. Danach für 10min bei 250°C in den Ofen und anschliessend
bei 180°C für 60min fertigbacken lassen.

Das Ergebnis:

Nach dem Backen 1
Nach dem Backend 2

Using rvm with cygwin

If you want to install rvm with cygwin do the following:

  • install cygwin
  • make sure you select ncurses and curl (if you don’t install ncurses, you’ll get a lot of tput: command not found)
  • execute this shell bash -s stable < <(curl -s https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer )
  • install ruby with this command rvm install ruby-1.9.2

Nach dem Hack – Account wieder freigeschaltet

Das ging schneller als erwartet: Mein Xbox-Account ist wieder freigeschaltet und für die geklauten MS Points (ich würde gern auf die Wikipedia linken, aber da haben die Löschtrolle mal wieder zugeschlagen…) habe ich eine Gutschrift bekommen, die demnächst in meinem Account auftauchen wird.

Vielen Dank, Xbox-Team!

Mein Xbox Live Account wurde gehackt

Gestern abend habe ich in meinen Erfolgen etwas seltsames bemerkt: Ich hatte plötzlich zwei Erfolge für FIFA 12 – obwohl ich das Spiel weder gespielt habe noch besitze.

Irgendwie habe ich nicht schnell genug geschaltet, aber es war ohnehin zu spät: Heute habe ich bemerkt, dass alle meine MS Points verschwunden sind. Ich hatte diese Woche gerade erst welche aufgeladen, weil ich mir Trine 2 kaufen wollte. Damit das günstig wird, habe ich natürlich gleich 4200 Punkte gekauft… das werd ich demnächst auch nicht mehr machen. Nur noch so viele Punkte wie nötig.

Ich habe heute gleich den Microsoft Support angerufen und den Vorfall gemeldet. Mein Konto ist jetzt erstmal gesperrt und diese Transaktionen werden untersucht. Soweit so gut. Ausserdem habe ich auf http://xbox.com die automatische Anmeldung meines Profils auf allen Konsolen deaktiviert.

Ich werde auch auf der Playstation meine Zahlungsoptionen entfernen. Nach dem Sony-Fiasko in 2011 hätte ich das schon längst erledigen sollen, aber jetzt ist die Zeit reif.

Und in Zukunft werden a) Zahlungsmittel nur noch eingegeben, wenn es keine Prepaid-Variante gibt und b) in allen Diensten eine Email-Adresse auf meiner Domain http://kopis.de verwendet – damit ich die auf jeden Fall unter Kontrolle habe…

Google macht anständige Sicherheit mit dem Google Authenticator vor – sowas sollten langsam alle Dienstleister einführen, die persönliche Daten speichern… aber davon werden wir wohl noch lange träumen.

Hinweis: Ich habe jetzt gelesen, dass man evtl einen EA-Account braucht, damit dieser Hack verwendet werden kann. So einen habe ich natürlich auch, weil ich Dragon Age spiele… auch da habe ich sofort meine eigene eMail eingetragen und das Passwort geändert.

Update: Mein Account ist wieder frei.

Was sind Feature Toggles?

Ich hab mich entschlossen, einen Feature Toggle in eine Anwendung
einzubauen. Das ganze soll dazu dienen, ein Feature zu einem späteren
Zeitpunkt einzuschalten, obwohl der entsprechende Code schon
implementiert ist. Ich habe nur eine einzige Stelle, an der ich diesen
Schalter brauche und er sitzt sehr weit vom Benutzer entfernt im
Backend-Code. Damit will ich schnell auf eine Entscheidung aus dem
Business reagieren, die wir dann ohne große Vorlaufzeit durch das
Umsetzen eines Properties in einer Datei umsetzen können.

Damit begebe ich mich auf dünnes Eis und ich muss jetzt zu jeder
passenden und unpassenden Gelegenheit folgende Worte fallen lassen:

Ein Feature Toggle ist ein temporärer Trick, mit dem man Features
implementieren und testen kann, aber noch nicht freigeben muss.

Und weil andere das schon viel besser gesagt haben, will ich hier noch
ein kurzes Zitat aus Martin Fowlers Artikel zu Feature Toggles
wiedergeben:

It’s very important to retire the toggles once the pending features
have bedded down in production. This involves removing the definitions
on the configuration file and all the code that uses them. Otherwise
you will get a pile of toggles that nobody can remember how to use.

Es ist also wichtig, dass dieser Feature Toggle mit dem nächsten
vollständigen Release wieder entfernt wird. Ansonsten findet man sich
schnell mit einer explodierenden Anzahl von Kombinationen der Toggles
wieder und niemand weiß mehr so genau, was die einzelnen Schalter jetzt
ein oder ausschalten. Ausserdem wird der Code schnell unübersichtlich,
weil man die Schalter wahrscheinlich durch IF-Abfragen implementiert hat
und jeder Schalter die Anzahl der Programmpfade erhöht.

Gute Vorsätze für 2012

Ich habe natürlich keine guten Vorsätze für 2012 gefasst, weil ich diese “Ich wünsche mir was zu Neujahr”-Aktion ziemlich sinnlos finde. Wenn man etwas ändern will, wartet man nicht bis zum 1. Januar, sondern man fängt einfach an.

Trotzdem: Wenn in eurem Fitnessstudio jetzt die wilden Horden von Fitnesswilligen auftauchen, dann solltet ihr nicht zu laut darüber meckern – auch wenn die meisten Ende Januar wieder verschwunden sind. Ein bißchen zu tun ist immer besser als gar nichts zu tun.

Gebt also Hilfestellung, wenn jemand etwas verloren aussieht und seid nicht zu unfreundlich. Vielleicht helft ihr dann sogar einem der Fitnesswilligen, etwas länger als 4 Wochen durchzuhalten.