Blog archives

Javascript MVC tutorial: create a todo list using Stapes.js in less than 100 lines of code (part 2)

In the first part of this tutorial we wrote a really simple todo list. In this part i’ll show you how to expand it with a templating mechanism, a way to remove the todos and how to use localStorage to save the todos between browser refreshes.

Templating

From the first part you might have noticed that i’ve added some HTML using jQuery in the controller. This is usually not how you should do things in a MVC framework. Instead of writing inline HTML you’re better of using templating.

Like with anything else in Stapes, you’re free to use any templating mechanism you want, but for now i’ll be using the popular Handlebars.js library.

We’ll start by adding the Handlebars.js library to the index.html file and adding a small inline template using a script tag. Add this before the first script tag in the index.html file:

The type="text/html" attribute will prevent the browser from parsing this text as Javascript. We’ll now include a new listTemplate variable to our app.js file to parse the template. Add this to the top of app.js.

In any part of the code you can now get the HTML for this template by simply calling listTemplate as a method.

Now, let’s use the template for our todo app! We’ll be creating a new listView and remove the old jQuery code from our controller. Because we have two views now we’ll be renaming TodosView to InputView. It’s usally best to use a view for a single element, and keep it as simple as possible.

Here’s the complete code for our new app.js

Try refreshing your browser and add some todos. Notice that the number at the bottom of the list (‘todos left’) increases every time you enter a new todo.

A closer look at ListView

Let’s take a closer look a the ListView.

The render function takes care of rendering the todos as a block of HTML code. It uses the template property we set on the view to get the html. The this.template method takes one parameter: a Javascript object that contains the data it should render:

The size method is a part of every Stapes module and returns the number of items. Let’s have a look at the part of the template:

So, whenever this template is rendered the size property is updated with the number of todos in the TodosModel.

The todos property is a little more complicated. getAllAsArray returns all items in the TodosModel as an array, so we can iterate over the items in the template:

Note the {{text}} property. We changed a little part of the InputView to make sure every item in the model has a text attribute. The {{id}} property is automatically added to every object whenever you call getAllAsArray. We’ll see why this is handy in a moment.

Removing todos

Adding todos is nice, but you might want to get something done as well! As you probably saw in your browser every todo now also includes a small checkbox. We’ll be adjusting the ListView to make it possible to remove todos.

Add a bindEventHandlers method to your ListView, just before the render method:

We also need to call this method, so add this to the end of the constructor in your ListView.

Now reload your browser, add some todos and try clicking the checkbox. Hurrah! We can finally get some stuff done ;)

A closer look at the remove function

So, how does the bindEventHandlers() function in ListView work? We add an event handler to all items with the class remove (all checkboxes have this class). Whenever one of them is clicked we get the id for the todo by looking at the parents and getting it from the data-id attribute we set earlier in the template.

After that it’s a simple call to Stapes’ remove function to remove the element by id.

Remembering stuff

We’ll be wrapping up this tutorial with a small addition to our model. Don’t you think it’s irritating to have an empty list every time you refresh the browser? Let’s use the new HTML5 window.localStorage feature to remember it between browser refreshes.

Note that localStorage is available in all recent browsers, including Internet Explorer 8. If you need to support older browsers there are plenty of alternatives to make it work on those browsers too.

So, let’s write some code. We’ll be using the JSON format to save our model into the browser’s localStorage. Change your TodosModel to this piece of code:

Change the init method of the TodosController to this:

Check it out! Add some todos, refresh your browser and voila, all your todos are saved!

A better look at the new TodosModel

The TodosModel module now has a new constructor that gets the todos from localStorage, parses the JSON and uses Stapes’ set on itself to add all the todos to the model. set works just like push, except that it takes key-value pairs and so it doesn’t automatically create new ids.

We use a nifty trick here: set also accepts an object with multiple key-value pairs, like our list of todos. The todos variable gets a Javascript object back from localStorage that looks like this:

Note that in your browser the ids will look different because they are randomily made up whenever you add a new todo.

The save method saves all of the todos in localStorage by getting them from the TodosModel using getAll, then converting them to JSON.

We changed the event handler for the change event in our controller to update the localStorage whenever an event is added or removed from the model. Also note the final line of the TodosController constructor: we need to do an initial render of the ListView to show the list of todos.

Wrapping it up

You should now have a completely functional, persistent todo list in your browser. If you want to experiment feel free to use the jsFiddle i’ve setup.

If you want to learn more you could read the Stapes.js documentation and play around with the more advanced todo example.

If you have any comments or questions feel free to post them in the comments section, send me an e-mail, or send a message to @hayify on Twitter.

Thanks for reading!

Blog archives

Javascript MVC tutorial: create a todo list using Stapes.js in less than 100 lines of code (part 1)

As a Javascript programmer you might have read the term ‘MVC’ or ‘Model-View-Controller’ here and there. Or, maybe a friend has recommend you look into a ‘MVC framework’ like Backbone or Ember.js.

So, what’s this whole MVC thing? You could try reading the Wikipedia article but it might be a little abstract. In practice MVC is really nothing more than separating your applications data (model) and presentation (view).

But why would you do such a thing? The most important reason is maintainability, your code becomes more readable and, hence, more maintainable. You’ll also notice that you will become a better programmer, and it becomes easier to add features to a project.

This still might sound a little abstract, so let’s write some code! We’ll be using a super tiny MVC framework called Stapes.js which, not completely coincidental, is something i wrote myself to learn MVC. Stapes is pretty relaxed about how you structure your code, so this approach is just one approach. Feel free to structure your code in every way you want.

For this tutorial i’ll assume you have some basic knowledge about HTML and Javascript and you know how to get a simple webserver running.

We’ll be writing a really simple todo (task list) application. There’s actually a really cool project called TodoMVC that collects todo examples written in multiple frameworks (here’s the one for Stapes). However, those examples are usually pretty complicated and might not give you the best introduction to MVC. So’ll we be doing something a lot simpler in this tutorial.

Setting up

We’ll start by setting up a HTML file. Open your favorite text editor and copy-paste this code, and save it as index.html.

Let’s add some Javascript! Create a new file called app.js and save it in the same directory.

We will be using jQuery for DOM manipulation. With Stapes you’re free to use any Javascript library you want, or just use vanilla DOM scripting. I’ll just assume everyone knows jQuery, so that’s why we’ll be using it.

Okay, let’s set up our TodoModel, TodoView and TodoContoller using the Stapes.subclass method:

Try reloading your webbrowser and entering a todo in the input field. If all went well you should be seeing new todos appearing.

Analyzing the code

Let’s analyze this code a little bit.

With Stapes it doesn’t really matter what you call your objects. Other MVC frameworks might force you into using pre-defined models or views. That’s not a bad thing per se, but with Stapes the philosophy is that you can manage conventions for yourself. So’ll we just end the module variable names with Model or View to indicate the type.

The subclass function creates a new class that you can later instantiate with new. Note how we have a property called constructor. This is the function that is executed when calling new and that you use to setup properties. All other properties in the object given to subclass become part of the class prototype.

Let’s take a look at the TodosView. The constructor exists of an event handler for the input field.

On to the code in constructor: note that we use the bind method on the function in the event handler. This is to fix a common problem in Javascript event handlers where this is scoped to the global window variable instead of the current object. bind on functions is included in all modern browsers, but if you’re using an older browsers (such as Internet Explorer 8) you might need to include a polyfill like the one from MDN.

Here’s the most important line of the view:

$input.val() gets the todo we entered in the input field. The push method of the model adds the todo to its internal data store and automatically assigns an unique id. This action also does something else, it triggers a change event that can be used to update a view. We listen to this event in the TodoController:

Every Stapes object can trigger events using the emit method. We can listen to these events using the on method.

Some methods automatically trigger events, such as push. An event can contain event data in the callback, which you can see in this example. The todoId variable holds the unique id the model automatically assigned when we did the push in the TodoView.

We want to get the text for this todo, so we use get on the model to get the todo text. We then append it using jQuery to the #todos list.

Wrapping it up

Here’s Model-View-Controller in its most basic form: a user action triggers an
event, that is used to update the model. The model fires a ‘change’ event, which is used by the controller to update the view.

If you want to experiment with this example try the jsFiddle i’ve setup.

Hungry for more? Read the second part of this tutorial and i’ll show you how to use templating, remove todos and save the todos to localStorage.

Blog archives

Waar moet je heen op De-Affaire?

Het tofste gratis festival van Nederland begint vanavond: de-Affaire, tijdens de zomerfeesten in Nijmegen. Met zoveel bandjes om de komende week te zien is de vraag natuurlijk: waar moet je heen, en waar niet?

Gelukkig hoef je je daar niet meer het hoofd over te breken: ik heb alles geluisterd en lijstjes gemaakt waar je zeker heen moet, wat eventueel leuk is, en wat je het beste links kan laten liggen. Inclusief Spotify playlists, wat voor soort muziek het is en waar het op lijkt.

Dit is leuk op de-Affaire 2012 (Spotify playlist)

  • Automatic Sam. Zondag 22.45 Boog.
    Lekkere vuige rock. Lijkt op: De Staat, zZz.
  • Bart Constant. Donderdag 20.30 Arc.
    Fraaie swingende vrolijke pop. Lijkt op: Beirut, About.
  • Bombay Show Pig. Vrijdag 22.15 Arc.
    Slepende gitaar indierock. Lijkt op: The Breeders.
  • The Dirty Denims. Woensdag 22.15 Lift.
    Punky puntige gitaarliedjes met rockhicks. Lijkt op: AC/DC, Ramones.
  • The Excitements. Zaterdag 22.45 Habana.
    Swingende ouderwetse jaren-vijftig soul. Lijkt op: Sharon Jones & the Dap-kings.
  • Fenster. Dinsdag 21.15 Boog.
    Rustige lo-fi popliedjes met electronica. Lijkt op: The Moldy Peaches. PJ Harvey.
  • Fránçois & The Atlas Mountains. Woensdag 20.30 Arc.
    Lekker poppy luisterliedjes, afwisselend Frans/Engels. Lijkt op: Baxter Dury.
  • Gnucci. Woensdag vanaf 20.00 bij Club Voerweg.
    Ragga, dance, of iets er tussen in. In ieder geval heel dansbaar. Lijkt op: M.I.A, Thunderheist.
  • Great Mountain Fire. Woensdag 21.15 Boog.
    Melancholische electronica met gitaaraccenten. Lijkt op: The Bony King of Nowhere, Daryll-Ann, Belle & Sebastian.
  • Gum Takes Tooth. Zondag 21.15 Boog.
    Gore vieze harde kutmuziek. Lijkt op: takkeherrie.
  • Jagwar Ma. Zondag 22.30 Club Voerweg.
    Soms ouderwets, soms hypnotiserend. In ieder geval afwisselend! Lijkt op: The Beta Band.
  • Kurt Vile. Zondag  20.15 Arc.
    Typische Amerikaanse lo-fi gitaarliedjes van de helft van War on Drugs. Lijkt op: Deerhunter, Destroyer, Sparklehorse.
  • Lou Barlow. Zondag 15.00 Arc.
    Lo-fi indieheld van Dinosaur Jr. en Sebadoh. Lijkt op: Red House Painters, Stephen Malkmus, Sonic Youth.
  • Molly Nilsson. Donderdag 21.15 Boog.
    Dromerige lo-fi gitaarliedjes van een verlegen meisje. Lijkt op: Sally Shapiro, Grimes, Cocteau Twins
  • Plants and Animals. Zondag 19.30 Boog.
    Catchy indierock met goede ritmes. Lijkt op: Wolf Parade, Grizzly Bear, Caribou.
  • Reptile Youth. Zaterdag 20.30 Arc.
    Het lijkt griezelig veel op The Rapture, maar goed, dansbaar is het wel. Lijkt op: The Rapture, dus.
  • Rilan & The Bombardiers. Donderdag 20.30 Habana.
    Ouderwets swingbare soul.
  • Sharon van Etten. Zondag 18.30 Arc.
    Emotionele breekbare singer/songwriter rock. Lijkt op: EMA. PJ Harvey. St. Vincent. The War on Drugs.
  • Skip & Die. Zondag 20.00 Club Voerweg.
    Elektrobeats uit de hele wereld om op te dansen. Lijkt op: M.I.A, Die Antwoord.

Dit is wel aardig op de-Affaire (Spotify playlist)

  • Bombino
  • Capeman
  • Ewert and the Two Dragons
  • Fresku
  • The Hickey Underworld
  • Hjálmar
  • Jesca Hoop
  • The Jezabels
  • Kapok
  • Le 24
  • Locked Groove
  • Los de Abajo
  • Near Earth Object
  • Orchestra of Spheres
  • Rats on Rafts
  • Red Fang
  • Rina Mushonga
  • Sam A La Bamalot
  • Steve Mensink

Hier hoef je echt niet heen op de-Affaire (Spotify playlist)

  • Baroness
  • Boef en de Gelogeerdee Aap
  • Chagall
  • Drive Like Maria
  • Dylan LeBlanc
  • Honningbarna
  • Jah6
  • Jazzsteppa
  • Kabel
  • Kapok
  • kiss the anus of a black cat (sic!)
  • Kutz
  • Morgan O’Kane
  • A Polaroid View
  • Proper Outfit
Blog archives

Wat er mis is met de iOS apps van de Volkskrant (en hoe het beter kan)

Sinds een paar maanden heb ik een iPad. Leuk om dingen op te lezen, zoals bijvoorbeeld de krant. Zelf lees ik dan het liefst de Volkskrant, maar helaas werkt dat voor geen meter. Waarom? Lees dit artikel. Ook voor hoe het dan wel moet.

Volkskrant op iPad

De Volkskrant heeft besloten om een Newsstand-app te maken voor de iPad. Dat betekent dat ze abonnementen en losse nummers mogen verkopen, maar wel 30% moeten afdragen aan Apple. Elke nacht wordt (in theorie) de complete krant gedownload via wi-fi en kun je er doorheen bladeren (layout hetzelfde als in de papieren versie) en artikelen lezen op een iPad-vriendelijk formaat.

Bugs en tekortkomingen

De app zelf ziet er aardig uit, maar in de praktijk zijn er ontzettend veel bugs en tekortkomingen:

  • Artikelen die in de papieren krant over meerdere pagina’s zijn gedrukt (bijvoorbeeld een inleiding op de voorpagina die verder gaat op pagina 10) zijn in de digitale versie niet samengevoegd. Je komt dus regelmatig artikelen tegen met de op een iPad lachwekkende zin ‘Lees verder op pagina 10’.
  • Puzzels zijn niet in te vullen. Waarom zitten ze dan toch in de digitale krant?
  • De krant zelf duurt lang om te downloaden (een gemiddelde krant is schat ik rond de 200mb). Vandaar de mogelijkheid om ‘m ‘s nachts op te halen via wi-fi. Maar als je op 3G zit en de krant wilt ophalen heb je een probleem: het duurt superlang en je databundel is zo op.

Al die tekortkomingen zouden nog tot daar aan toe zijn als de krant niet zo ontzettend vaak half, incompleet of zelfs helemaal niet binnen komt. Zie de afbeelding: vanochtend kreeg ik de tekst van de krant wel binnen, maar niet de afbeeldingen en de pagina’s.

De app crasht regelmatig, en dan ben je je ‘state’ (de plek waar je was in de krant) volledig kwijt en moet je helemaal overnieuw bladeren naar waar je was gebleven.

Stelt u zich eens voor dat je de papieren krant regelmatig half, kapot of helemaal niet in de bus kreeg. Wat zou u dan na een paar weken doen?

Prijs / kwaliteit

De bottom line: hoeveel betaal je voor het abonnement? 24 euro per maand. Dat is maar 3 euro minder per maand dan de papieren krant. En voor die 3 euro meer krijg je de iPad-versie er geheel gratis bij.

De logische vraag is: waarom zou iemand in vredesnaam voor 24 euro per maand zo’n slecht product willen?

Volkskrant op de iPhone

Behalve de iPad-versie is er ook een iPhone versie. Helaas is die zo mogelijk nog slechter. De app heeft al bijna een jaar geen update meer gekregen, zodat cruciale bugs (zoals bijvoorbeeld het volledig ontbreken van afbeeldingen in teksten) nog steeds niet zijn gefixt.

Ook de iPhone versie crasht regelmatig en kranten komen vaak half, of helemaal niet binnen.

Het enige lichtpuntje: voor de iPhone-versie betaal je slechts 8 euro per maand.

Probleemkindje

Het is dus duidelijk dat de iOS-strategie van de Volkskrant faalt. Zowel de iPad als iPhone-versie hebben al maanden geen updates meer gekregen, er zijn ontzettend veel bugs en de apps crashen regelmatig. De enige reden die ik me kan voorstelen waardoor dat komt is omdat er vanuit de Volkskrant helemaal niemand zich met dit project bezig houdt. Het idee is blijkbaar geweest om een app te maken ‘en dan zijn we klaar voor de toekomst’.

Helaas werkt het in de praktijk niet zo: het laten slagen van een app vergt een team van mensen die er continu opzitten, de kwaliteit in de gaten houden en de apps beter maken.

Een andere aanpak

Goed, de Volkskrant iOS-apps falen dus. Maar hoe moet het dan wel? Ik heb geen biet verstand van kranten, maar ik weet wel wat ik prettig vind werken op mijn iOS-apparaten.

Maak één app voor iPad en iPhone. Geen newsstand-app, want dan draag je 30% af aan Apple. Dan kun je geen losse nummers of abonnementen meer via de app verkopen, maar dat doe je lekker via de website, net zoals Spotify. Geen verschil tussen iPad en iPhone-abonnement: voor een tientje per maand kun je op beide apparaten de krant lezen.

Schrap het idee dat de digitale krant er net zo uit moet zien als de papieren krant. Kijk naar apps als Zite of Flipboard om te zien hoe je een echte digitale krant maakt. Vraag slimme techneuten om iets te bedenken waardoor je het aantal mb’s beperkt zodat het ook over een 3G-connectie is te downloaden. Haal alles er uit waar je geen tijd voor hebt om het goed digitaal uit te voeren (zoals de puzzels).

En zorg voor iemand die elke dag de complete krant checkt op fouten, die er voor zorgt dat er geen half functionerende kranten worden gedownload en reageert op feedback van eindgebruikers.

Misschien kan ik dan eindelijk eens fijn de krant lezen op mijn iPad.

Blog archives

Stapes 0.5 released

I’ve just released version 0.5 of my little Javascript MVC framework, Stapes.js.

New features and improvements in this release are focused around events. The most important one is the ability to add Stapes’ event handlers to any Javascript object or function:

var person = {
    "sayName" : function() {
        this.emit('name', 'Johnny');
    }
};

Stapes.mixinEvents(person);

person.on('name', function(name) {
    console.log('my name is: ' + name);
});

person.sayName(); // 'my name is Johnny'

So you don’t need to create a Stapes object to get event handlers in an object.

mixinEvents also works with functions and the new, operator, just make sure you set the mixin in the constructor.

var Person = function(name) {
    Stapes.mixinEvents(this);
    this.name = name;
}

Person.prototype.sayName = function() {
    this.emit('name', this.name);
};

var p = new Person("Emmylou");

p.on('name', function(name) {
    console.log('my name is: ' + name);
})

p.sayName(); // 'my name is Emmylou'

The cool thing is that all mixed-in events are also thrown on the global Stapes
object, so you can also do stuff like this:

Stapes.on('all', function(data, e) {
    console.log(e.type + ':' + data);
});

p.sayName(); // 'name:Emmylou'

The other big feature of 0.5 is the addition of the off method for event handlers. I haven’t come across many usecases where you need this, but it is an obvious addition if you also have on and emit methods.

So, please check out the new release! What would you like to see in the 0.6 release?

Blog archives

haykranen.nl 3.0

The last big redesign of this website was released on january 1st 2007. Quite a long time ago, considering Facebook was still in its infancy, people surfed with Internet Explorer 6 and the iPhone wasn’t released yet (that happened nine days later).

So, what kept me from redesigning this site? I guess a lack of time, or interest, or both. I’ve started work on this new redesign somewhere in autumn 2011, and the files on my laptop tell me i’ve been thinking about a new design since at least summer 2010.

For this new design i decided to go with the mobile first approach: focus on the most important stuff first, make that as nice and simple as possible, than go for fancy bells and whistles. Try viewing this website on your phone or tablet, it will look pretty nice as well.

This also means performance and bandwidth is really important. The current homepage loads under a second and uses as little HTTP requests as possible. I’ve switched to using Zepto instead of jQuery as a Javascript framework for reduced filesize and optimization on mobile.

I’ve switched to English for the main pages and navigation. I’ve tried a multi-language approach for the old site and failed. I’ll still be blogging in Dutch from time to time, but i won’t be bothered by trying to invent some way to make the common interface elements available in both languages.

I’m interested to hear what you think about this redesign. Are you missing anything? Things you don’t like? Please let me know in the comments.

And i surely hope the next redesign won’t have to wait until 2017 :)

For those of you who are experiencing nostalgia now, here are some screenshots of previous versions of the site (click for a bigger version):

Version 2.0 (designed end 2006)

Version 1.0 (summer 2005)

Blog archives

Speelschema Nederlands elftal EK 2012


Foto: Steven Depolo / CC-BY

U kent die situatie: u wilt een feestje organiseren (of verkiezingen, ook leuk). U heeft alles al gepland, de ranja ingekocht, mensen uitgenodigd, en dan bekruipt u dat gevoel: speelde het Nederlands elftal niet op mijn feestje?

Om dat probleem te voorkomen: hier zijn ze: alle mogelijke data waarop ‘onze jongens’ het gras betreden.

Groepsfase

  • Zaterdag 9 juni 18:00 – Nederland – Denemarken
  • Woensdag 13 juni 20:45 – Nederland – Duitsland
  • Zondag 17 juni 20:45 – Portugal – Nederland

Finales

Als Nederland 1ste in de groep wordt:

  • Vrijdag 22 juni 19:45 – Kwartfinale
  • Donderdag 28 juni 18:45 – Halve finale

Als Nederland 2de in de groep wordt:

  • Donderdag 21 juni 18:45 – Kwartfinale
  • Woensdag 27 juni 20:45 – Halve finale

Als Nederland in de finale komt:

  • Zondag 1 juli 20:45 – Finale
Blog archives

Het lijstje van 2011

Jep, het is weer zover. Geen jaar gaat voorbij zonder dat de muziekliefhebber zich wijd aan het maken van het lijstje. Het beste, mooiste, bijzonderste van 2011.

Over het algemeen vond ik 2011 wat tegenvallen. Weinig wat er echt heel erg uitsprong, geen grote klassiekers. Desondanks genoeg platen om een top 20 mee te vullen.

Zoals ik vorig jaar al schreef is de introductie van Spotify een bijzonder evenement geweest. Alle albums op mijn lijstje van dit jaar zijn dan ook te luisteren op Spotify door te klikken op het  icoontje.

Verder heb ik ook een YouTube-mix gemaakt met van elke plaat mijn favoriete nummer. En ook die playlist (met wat aanvullingen) kun je beluisteren via Spotify.

YouTube Mix

Hay’s 20 platen van 2011

1. James Blake – James Blake

Nee, geen grote verrassing, en soms is James wat saai. Maar 2011 is het jaar van dubstep, en James is de koning. Toch wel heel erg goed.

Ideale combinatie: luister na James Blake z’n twee EP’s uit 2009: CMYK en Klavierwerke.

2. Oneohtrix Point Never – Replica

Superabstracte bizarre instrumentale muziek, maar toch prettig in het gehoor. Op elk nummer lijkt er een nieuwe plaat te beginnen. Muziek voor de 21ste eeuw.

3. The Field – Looping State of Mind

Nog steeds: oneindig rekken van ultrakorte samples met een simpele 4-to-flour beat, maar waarom ook niet? The Field klinkt op deze plaat warmer dan ooit. Ideale muziek voor als je ‘in de zone’ bent.

4. Cut Copy – Zonoscope

Cut Copy is volwassen geworden. Heerlijk aanstekelijke electropop met een dansbaar randje.

5. Wilco – The Whole Love

Verrassende nieuwe plaat van een band die alles al eens gedaan heeft. En dat nu allemaal op één plaat doet. Supergoed.

6. araabMUZIK – Electronic Dream

Het lijkt een goedkoop concept: pak een hoop foute househits uit de jaren negentig, remix ze een beetje en hoppa: een plaat. Saai? In tegendeel. Heel goed. Het werkt.

7. Bon Iver – Bon Iver

De intimiteit van zijn eenzame-man-op-een-gitaar debuutalbum is hij kwijt, maar het geluid is wel veel rijker geworden. Heel mooi. Toch, ietwat degelijk en niet zo spannend.

8. The War on Drugs – Future Weather

9. The Weeknd – House of Balloons Gratis Downloaden!

10. Alamo Race Track – Unicorn Loves Deer

11. The Streets – Computers and Blues

12. Tune-Yards – W H O K I L L

13. Gang Gang Dance – Eye Contact

14. St. Vincent – Strange Mercy

15. Unknown Mortal Orchestra – Unknown Mortal Orchestra

16. Little Dragon – Ritual Union

17. Washed Out – Within and Without

18. Azari & III – Azari & III

19. Gorki – Research & Development

20. Kate Bush – 50 Words for Snow

Concert van het jaar

Simpel: Sufjan Stevens in het muziekgebouw in Eindhoven, begin dit jaar. Misschien wel het beste concert wat ik de afgelopen vijf jaar heb gezien. Kippenvel, de hele tijd. Ook al speelde Sufjan slechts één nummer van zijn beste plaat Illinois toch kon hij de hele zaal urenlang ontroeren en boeien met zijn folkpop met een elektronisch randje.

Ook erg goed dit jaar: dEUS op Lowlands (hele concert op 3voor12) en natuurlijk Kap Bambino op De-Affaire!

Meer lijstjes

Uiteraard zijn er meer lijstjes. Ik verwijs u graag door naar Pitchfork, Best Ever Albums, Metacritic, Kindamuzik, Tiny Mix Tapes, NME, The Guardian, Nils Breunese, Menni en Sander Spek.

En wie smult van archieven (ik ken er wel een paar): hier zijn mijn lijstjes van 20102009, 2008, 2007, 2006, 2005 en 2004.

Blog archives

logrotate, virtual hosts on Apache and 100% CPU

I got a typo in my logrotate config which pretty much killed my VPS.

My Apache server runs a lot of virtual hosts, i didn’t want to type them all out for logrotate, so i created something like this to handle it:

/var/www/*/logs/*.lo* {
        daily
        missingok
        rotate 7
        compress
        delaycompress
        notifempty
        create 640 root adm
        sharedscripts
        postrotate
                if [ -f "`. /etc/apache2/envvars ; echo ${APACHE_PID_FILE:-/var/run/apache2.pid}`" ]; then
                        /etc/init.d/apache2 reload > /dev/null
                fi
        endscript
}

Note the ending * at the first line. I didn’t know what got into me, but this caused logrotate to rotate the rotated logfiles, hence 100% CPU and hence, a broken system.

I fixed it (by replacing the ‘*’ with a ‘g’), but logrotate still didn’t work. CPU stayed at 100%, logs didn’t rotate. So i ran a strace -f logrotate and got lots of these:

stat64("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2917, ...}) = 0
stat64("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2917, ...}) = 0
stat64("/etc/localtime", {st_mode=S_IFREG|0644, st_size=2917, ...}) = 0

A little bit of Googling turned up this blogpost: apparently lograte‘s own log got corrupted. A simple rm /var/lib/logrotate/status did the trick and everything worked perfectly again.

Blog archives

Using the :first-of-type pseudoselector instead of :first-child

Consider this case: you have a blogpost with an image, a heading, and some text. You want a little margin on the top of every heading to divide the different sections. Your HTML might look like this:

<article>
    <img src="photo.jpg" alt="A nice photo" />
    <h3>My heading</h3>
    <p>Text. Bla bla bla</p>

    <h3>Another heading</h3>
    <p>Even more bla bla</p>
</article>

Your CSS might looke like this:

img {
    float: right;
    margin: 0 0 10px 10px;
}

h3 {
    font-size: 24px;
    margin-top: 24px;
}

p {
    font-size: 16px;
    margin: 12px 0;
}

Now here’s a problem. The very first <h3> will have an ugly margin at the top, so it doesn’t line up with the image. How would you style it so that it won’t have a margin at the top? My first guess was to use the :first-child selector:

article h3:first-child {
    margin-top: 0;
}

However, that doesn’t work. The spec is not very clear about it: but here’s the problem: :first-child only selects the very first element and doesn’t care about the element you give it. That’s great if all your elements are the same (such as <li> elements in a list) but it sucks when having a case like this.

Fortunately, there’s a new CSS3 property that’s perfect for this case. It’s called :first-of-type and does exactly what you want.

article h3:first-of-type {
    margin-top: 0;
}

Browser support is mostly pretty good, although you’re out of luck on Internet Explorer 8 and earlier.