Mikael's blog

A developers seventh time trying to maintain a blog

A Tiny Bug

I’ve been using (and still am in production) an old JavaScript function called parseInt when parsing my DateTimes for comments and posts. For some reason it showed some weird behavior today.

I noticed a comment that was written on December 0. I looked it up in the database and it turns out it was actually written on December 8. Now the 8 should have been parsed from the DateTime 2011-11-08 ... into the string "08" and then I assumed parseInt should have gotten rid of that extra 0 for me.

I found my problem in the parseInt documentation over at w3schools.

The parseInt() function parses a string and returns an integer.

The radix parameter is used to specify which numeral system to be used, for example, a radix of 16 (hexadecimal) indicates that the number in the string should be parsed from a hexadecimal number to a decimal number.

If the radix parameter is omitted, JavaScript assumes the following:

If the string begins with “0x”, the radix is 16 (hexadecimal)
If the string begins with “0”, the radix is 8 (octal). This feature is deprecated
If the string begins with any other value, the radix is 10 (decimal)

parseInt works fine for the strings “01” through “07” and of course for any string beginning with a “1”. The deprecated “string begins with a zero”-feature was the culprit.

So today I learned something new; use Number() instead.

by Mikael Lofjärd

Client-side JavaScript Initialization

Yesterday I started using the BundleController with my JavaScript files on the client-side. I also deployed my ViewManager so that all my views now uses the bundled and minified JavaScript file produced when I start (or restart) my Node.js server.

This meant that all my JavaScript was being run on every page in the blog, and while it isn’t that much JavaScript yet I still wanted to improve on it.

I decided to make use of some closure magic and built something like this:

if (typeof(BlogPageFunctions) == 'undefined') {
  BlogPageFunctions = {};
}

BlogPageFunctions.admin = function () {

  // query some objects with jQuery here,
  // bind up some events etc.
  ...

}

I use the above pattern on all my page specific JavaScript code. For now, this amounts to two functions living on the BlogPageFunctions object, admin and comments. I made these regular functions instead of IIFEs because I only want them to run on their respective pages.

So how do I make them load? I could of course just written some script code into the template itself, but that would have created a lot of copy-and-paste code since it would have to include jQuery’s if-document-ready-stuff on every page and I wanted to keep the intrusion of JavaScript inside my templates as minimal as possible.

If you remember my BundleController it had a sorting function in it that was used to prioritize certain JavaScript and CSS files so that they would load before others. I used that to make sure that if I have a JavaScript file named init.js then I would add it AFTER all my other files in the bundle.

Inside init.js is where I execute the initialization code for each page:

$(document).ready(function () {

  if (typeof(BlogPageMetaData) != 'undefined') {
    for (var i in BlogPageMetaData.init) {
      BlogPageFunctions[BlogPageMetaData.init[i]]();
    }
  }

});

But what’s this BlogPageMetaData thing you ask? That’s what I put into my templates for the pages that need some kind of JavaScript on them. This code is from the top of my admin page template:

{{>header}}
  <script>
    if (typeof(BlogPageMetaData) == 'undefined') {
      var BlogPageMetaData = {};
    }
    BlogPageMetaData.init = ['admin'];
  </script>
  <section class="admin">
  ...

I create a BlogPageMetaData object (if it doesn’t exist already for some reason) in the global scope and then I add an array of function names for init.js to call when the page has finished loading.

This way I get the best of two worlds; I get to have ONE JavaScript file that is cachable by the browser, and I don’t run unnecessary JavaScript code on pages that doesn’t need it.

by Mikael Lofjärd

Architecture in JavaScript - Closures

Today is Tuesday, which for me means I’ve held another tutorial at work. Today it was less hands-on and more of me just talking and showing examples on the projector using the wonderful jsfiddle JavaScript quick-hack-tool.

My talk today was mostly about closures, so I thought I should write something here on the subject as well.

I find that it’s not that easy to explain closures using just words, but if I were to try it would go something like this.

  • A closure is a functions variable scope that still exists after the function has executed.
  • A closure only exist as long as something else has a reference to something that needs it.
  • A closure is created when an outer function has inner functions.

If you have no idea what I meant with any of that, then I hope these examples will clear things up: (I know they did for me)

Example 1

function saySomeThing(something) {
  var text = 'Hello ' + something;
  var innerFunction = function () {
    alert(text);
  };
  return innerFunction;
}

var say = saySomeThing('World');

When saySomeThing('World') is called, it returns an inner function. A closure is created that lets innerFunction access the text variable even after saySomeThing has finished executing.

If we were to run say(); after this it would popup an alert with the text Hello World.

Now, if you’re used to languages without closures, it would be easy to think that innerFunction has been “pre-compiled” into alert('Hello World'); but that is not the case. In fact, if we were to run say.toString(); the output would be function () { alert(text); } even though our say variable is clearly not in the same scope as text. But it works because the function pointer to innerFunction that saySomeThing returns contains a reference to the closure created when we executed saySomeThing('World');.

Every call to saySomeThing would create a new closure. If the old closure is no longer referenced, for example if we were to run say = saySomeThing('Goodbye'); then the old closure previously reference by the say variable would be garbage collected.

Example 2

var AlertNumber, IncreaseNumber, SetNumber;

function setupGlobals() {
  var num = 10;

  AlertNumber = function () { alert(num); }
  IncreaseNumber = function () { num++; }
  SetNumber = function (x) { num = x; }
}

In the above code, every call to setupGlobals would create a new closure and thus create a new num variable with the value 10, but a call to IncreaseNumber would reference the current closure and increase the internal num variable by 1.

Closures in C#

A question that I got today was: “What other languages uses closures?“. I know there are a few I’ve read about somewhere on the internet but I couldn’t really name them right there and then.

But then on my way home I started thinking about C# and I had an idea. Wouldn’t closures be possible now that C# has anonymous functions (lambdas), anonymous objects and the Action<> and Func<> types? And it is. If I would have googled it instead of trying for myself I would have found that out in about 2 seconds, but where’s the fun in that?

public object Closure()
{
  var number = 10;

  Action showNumber = () => MessageBox.Show(number.ToString());
  Action increaseNumber = () => number++;
  Action<int> setNumber = (i) => number = i;
  return new { showNumber, increaseNumber, setNumber };
}

dynamic a = Closure();

This is almost the same example as before, but in C#. If we were to call a.showNumber() it would show a message box with the value 10 in it. And it would increase number by 1 every time we call a.increaseNumber(). It also creates a new closure every time we call Closure().

In C# this same functionality would probably be easier to understand if turned into a class instead, but having a deeper understanding about how closures work is almost a requirement if you’re going to do any kind of serious JavaScript development. At least that is my opinion.

by Mikael Lofjärd

Broken Archive

Turns out I broke the archive yesterday when there were suddenly two months to render posts for. It was a simple array indexing problem and now it’s up and running again.

by Mikael Lofjärd

Handling Views in node.js

This weekend, my wife and daughter have been away up north, visiting my in-laws. I thought this would be a great opportunity for me to buffer up on some blog posts, but it seems like my inspiration mostly left with them.

Last Tuesday at my weekly tutorial at work we did a bit of work with jQuery and Mustache. On my blog I use Mustache, not only on the client side, but on the server side as well. As I enjoy using the MVC pattern, I have tried to implement it to the best of my extent.

First things first

Mustache is a light weight templating engine with emphasis on simplicity. It’s been implemented for a lot of languages and one of them is JavaScript.

In Mustache, a template looks like this:

Hello, my name is {{name}}!

In my case the templates involve a lot of HTML, but nevertheless it’s simply a string with {{ and }} used for marking up where the values should be inserted.

The JavaScript Mustache library has only one single method exposed; to_html.

to_html can take 2-4 arguments where the first is the template string and the second is the object with the values in it. In the JavaScript case that is a JSON object which suits me just fine since that what I use everywhere else in the blog. The other two arguments are used for partials and streaming the rendered template.

The ViewManager

This is what my ViewManager looks like:

/*****************************************
 *   View Manager
 *****************************************
 *   Author:  mikael.lofjard@gmail.com
 *   Website: http://lofjard.se
 *   License: MIT License
 ****************************************/

var ViewManager = (function () {

  var fs = require('fs');
  var path = require('path');
  var mu = require('mustache');

  var env = require('./environmentManager').EnvironmentManager;

  var templatesCached = false;
  var templates = {};
  var partials = {};

  return {

    init : function (templatePath) {

      if (!templatesCached) {
        console.log('ViewManager: Populating template cache');
        templates = {};
        var allTemplateFiles = fs.readdirSync(templatePath);

        for (var file in allTemplateFiles) {
          console.log(' - Adding ' + allTemplateFiles[file] + ' to template store');
          var filePath = path.resolve(templatePath, allTemplateFiles[file]);
          templates[allTemplateFiles[file]] = fs.readFileSync(filePath, 'utf-8');
        }
        partials.header = templates['header.partial.mu'];
        partials.footer = templates['footer.partial.mu'];

        templatesCached = true;
      }
    },

    renderView : function (response, viewName, model) {
      if (typeof(model.header) == 'undefined') {
        model.header = {};
      }
      model.header.trackingCode = env.trackingCode();
      model.footer = {};

      env.info('ViewManager: Rendering view ' + viewName);
      response.writeHead(200, { "Content-Type" : "text/html" });
      var html = mu.to_html(templates[viewName + '.mu'], model, partials, function (line) {
        response.write(line);
      });
      response.end();
      return;
    }
  };
    
}());

typeof(exports) != 'undefined' ? exports.ViewManager = ViewManager : null;

Upon initialization, I read all my template files from disk into memory. I also assign my partial templates to a partials object to pass on to Mustache. My partials are mainly what comes before and after themain content of each page on the blog. The other templates just contain the main content for each page.

This is the template for when you click on one of the tags in the tag cloud:

{{>header}}
  <section class="comments">
    <header>
      Posts tagged with {{tag}}
    </header>
    <div class="taggedposts">
    {{#posts}}
      <div class="taggedpost">
        <header><a href="/post/{{readableKey}}">{{title}}</a></header>
        {{outtake}}
        <footer>written on {{readableDateTime}} by {{author}}</footer>
      </div>
    {{/posts}}
    </div>
  </section>
{{>footer}}

The {{>header}} and {{>footer}} tags are what renders the partials. Each partial uses a property on the model as its context so my renderView method assigns properties calles header and footer to my model.

The {{#posts}} and {{/posts}} tags are iterator tags. The template code between them gets run for every object in the posts array in my model.

How to use it

Well how to use it is really up to you, but here’s how I do it from my controllers:

tag : function (request, response) {
  var tag = request.params.tag;

  db.view('posts/byTagAndDateTime', {
    startkey : [tag, 1],
    endkey : [tag],
    descending : true
  }, function (err, doc) {
    if (err) {
      env.info("CouchDB: DB Read error");
      staticFileController.error(request, response, 404);
      return;
    }

    var model = {};
    model.posts = new Array();

    for (var i in doc) {
      var post = doc[i].value;
      post.readableDateTime = misc.prettyDate(doc[i].key[2]);

      model.posts.push(post);
    }

    model.tag = tag;
    viewManager.renderView(response, 'tag', model);
    return;
  });
}

Line 26 is where the action is.

If you want to read more about Mustache, the check out its GitHub page and that of its JavaScript implementation.

by Mikael Lofjärd

Automatic Minification and Bundling with node.js

Scott Guthrie recently wrote about the new minification and bundling process that has been built for ASP.Net 4.5.

I read his blog post, liked what I read and then I though of doing the same thing for my blog. I’ve been looking at minification programs for a while but I’ve put it off so far because I didn’t want to add another step to my manual deployment process. Now I’m thinking I don’t have to have another step. I could do it “automagically”.

The BundleController

/*****************************************
 *   Bundle Controller
 *****************************************
 *   Author:  mikael.lofjard@gmail.com
 *   Website: http://lofjard.se
 *   License: MIT License
 ****************************************/

var BundleController = (function () {
    
  var url = require('url');
  var fs = require('fs');
  var path = require('path');

  var cssmin = require('cssmin');
  var jsmin = require('uglify-js');

  var env = require('../environmentManager').EnvironmentManager;
  var dm = require('../domainManager').DomainManager;

  var config = null;
  var staticFileController = null;
    
  function sortCss(a, b) {
    if (a === 'normalize.css')
      return -1;
    if (b === 'normalize.css')
      return 1;
    if (a === 'shCore.css')
      return -1;
    if (b === 'shCore.css')
      return 1;
    return (a &lt; b) ? -1 : ((a &gt; b) ? 1 : 0);
  }

  function sortScripts(a, b) {
    if (a === 'lofjard.js')
      return -1;
    if (b === 'lofjard.js')
      return 1;
    return (a &lt; b) ? -1 : ((a &gt; b) ? 1 : 0);
  }

  function createCssBundle() {
    var wwwRoots = dm.getAllWwwRoots();

    for (var i in wwwRoots) {
      var cssPath = path.join(wwwRoots[i], config.css.path);
      var bundleFilePath = path.join(cssPath, '_bundled.css');
      console.log('BundleController: CSS bundle path is ' + bundleFilePath);
      try {
        fs.unlinkSync(bundleFilePath);
      } catch (ex) {}

      var files = fs.readdirSync(cssPath);
      files.sort(sortCss);
      var bundleData = '';

      for (var filename in files) {
        console.log(' - Bundling CSS ' + path.join(cssPath, files[filename]));
        var file = fs.readFileSync(path.join(cssPath, files[filename]), 'utf-8');
        bundleData += (file + '\n');
      }

      if (config.css.minimize) {
        bundleData = cssmin.cssmin(bundleData);
      }

      fs.writeFileSync(bundleFilePath, bundleData, 'utf-8');
    }
  }

  function createScriptsBundle() {
    var wwwRoots = dm.getAllWwwRoots();
    for (var i in wwwRoots) {
      var jsPath = path.join(wwwRoots[i], config.scripts.path);
      var bundleFilePath = path.join(jsPath, '_bundled.js');
      console.log('BundleController: JavaScript bundle path is ' + bundleFilePath);

      try {
        fs.unlinkSync(bundleFilePath);
      } catch (ex) {}

      var files = fs.readdirSync(jsPath);
      files.sort(sortScripts);
      var bundleData = '';

      for (var filename in files) {
        console.log(' - Bundling JavaScript ' + path.join(jsPath, files[filename]));
        var file = fs.readFileSync(path.join(jsPath, files[filename]), 'utf-8');
        bundleData += (file + '\n');
      }

      if (config.scripts.minimize) {
        var ast = jsmin.parser.parse(bundleData);
        ast = jsmin.uglify.ast_mangle(ast);
        ast = jsmin.uglify.ast_squeeze(ast);
        bundleData = jsmin.uglify.gen_code(ast);
      }

      fs.writeFileSync(bundleFilePath, bundleData, 'utf-8');
    }
  }

  return {
    init : function (configInit, staticFileControllerInit) {
      config = configInit;
      staticFileController = staticFileControllerInit;
      createCssBundle();
      createScriptsBundle();
    },

    bundleScripts : function (request, response) {
      request.url = path.join(config.scripts.path, '_bundled.js');
      env.info('BundleController: Rewriting request as ' + request.url);
      staticFileController.file(request, response);
      return;
    },

    bundleCss : function (request, response) {
      request.url = path.join(config.css.path, '_bundled.css');
      env.info('BundleController: Rewriting request as ' + request.url);
      staticFileController.file(request, response);
      return;
    }
  };
    
}());

typeof(exports) != 'undefined' ? exports.BundleController = BundleController : null;

Nothing wierd here. It just bundles my scripts in alphabetical order, except for a few scripts and css files that are prioritized. Normalize.css gets top place in the bundling process and so would jQuery if I would host it myself.

I use node-cssmin for CSS minification and UglifyJS for JavaScript minification. None of this is in the production code yet since it was completed about 15 minutes ago and I need to do more testingon the JavaScript side, but on the development server the CSS bundling and minification works like a charm and has cut my CSS size by one third, but most importantly it has replaced 4 http requests with just one and cut the time for fetching css by 3/4.

The BundleController gets its configuration from index.js and it looks like this:

var bundleConfig = {
  scripts: {
    path: '/scripts',
    minimize: true,
    compress: true
  },
  css: {
    path: '/css',
    minimize: true,
    compress: true
  }
}

For now I don’t act on the compress property, but when I find a good way to send gzip files if the client supports it through node-static then at least I already have it configured.

I also added two new routes to my configuration:

routes['blog:/scripts'] = masterController.bundleScripts;
routes['blog:/css'] = masterController.bundleCss;

That’s really all there is to it. If I request lofjard.se/css/normalize.css I get the regular, untouched CSS file, but if I go to lofjard.se/css I get the minified version of all CSS files in the /css directory.

by Mikael Lofjärd

Architecture in JavaScript - Inheritance

There’s been a lot of debate over the years about whether JavaScript is an object-oriented language or not. Most of these discussions seem to pan out into arguments over inheritance.

JavaScript, by design, lends itself well to inheritance through extension. However, JavaScript can support lots of different types of inheritance. I’m going to talk about a few of them today.

Consider the following code:

function Car() {
  this.color = "Blue";
  this.brand = "unknown";  
}

function Ford() {
  var o = new Car();
  for(var i in o) {
    this[i] = o[i];
  }
  this.brand = "Ford";
}

var myCar = new Car();
var myFord = new Ford();

The myCar object would have the properties color and brand. The Ford() constructor method creates inheritance by creating a Car and copying all its properties. It then sets its brand property to a new value.

Ford now inherits from Car. But what if we want it to be able to inherit things in a more flexible way?

function Car() {
  this.color = "Blue";
  this.brand = "unknown";  
}

function Train() {
  this.color = "Red";
  this.brand = "unknown";  
}

function Ford(F) {
  var o = new F();
  for(var i in o) {
    document.write('  - i: ' + i + ' -   ');
    this[i] = o[i];
  }
  this.brand = "Ford";
}

var myCar = new Car();
var myFord = new Ford(Car);
var myOtherFord = new Ford(Train);

Now we would have a blue Ford car and a red Ford train. This could be done in another way:

function Car() {
  this.color = "Blue";
  this.brand = "unknown";  
}

function Train() {
  this.color = "Red";
  this.brand = "unknown";  
}

function Ford(o) {
  function F () {}
  F.prototype = o;
  var a = new F();
  a.brand ="Ford";
  return a;
}

var myCar = new Car();
var myTrain = new Train();
var myFord = new Ford(myCar);
var myOtherFord = new Ford(myTrain);

Oh My God! Now we’re inheriting from objects instead! And using prototype! Why don’t we go a step further?

function object(o) {
  function F() {}
  F.prototype = o;
  return new F();
}

function Car() {
  this.color = "Blue";
  this.brand = "unknown";  
}

function Train(o) {
  var a = new object(o);
  a.color = "Red";
  a.brand = "Märklin";
  return a;
}

function Ford(o) {
  var a = new object(o);
  a.brand ="Ford";
  return a;
}

var myCar = new Car();
var myFord = new Ford(myCar);
var myTrain = new Train(myFord);

Now we have objects inheriting objects inheriting objects. How object-oriented isn’t that?

Of course, for these extremely simplified cases, why would I need inheritance anyway? In fact, I can’t really figure out what I would need inheritance for anyway in JavaScript. Prototype extensions seem much more flexible to me. But if, in the future, I ever find a use for it, I’ll make sure to write about it here.

Also, make sure you read Mr. Crockford’s old (2001) post on Classical Inheritance in JavaScript. There are quite a few really funny ways to do this in there although I would not use them myself.

So to sum it up; if you think you need inheritance then please look closer at prototype extensions as an alternative. If you really need inheritance then know that it can be achieved.

by Mikael Lofjärd

The Logarithmic Tag Cloud

A few days ago I sat down and tagged all my posts. Last night I decided to write a tag cloud.

The first try

I started out with a simple linear scale:

var countDiff = maxCount - minCount;
var sizeDiff = maxSize - minSize;
if (countDiff == 0) countDiff = 1; // no divide by zero

for (var i in doc) {
  var weight = (doc[i].value - minCount) / countDiff;
  var size = minSize + Math.round(sizeDiff * weight);
  model.tags.push( { tag: doc[i].key, size: size , count: doc[i].value } );
}
  • maxCount - The highest occurance of any tag.
  • minCount - The lowest occurance of any tag.
  • maxSize - The biggest allowed font size.
  • minSize - The smallest allowed font size.
  • doc[i].key - The name of the current tag.
  • doc[i].value - The occurance of the current tag.

It rendered, but something looked odd. The linear scale isn’t really that pretty in a tag cloud. Especially not when a few tags (in my case #blog and #nodejs) has a substantially bigger weight than the rest. I wanted things to be readable with a minimum font size and a maximum font size set by me so that it couldn’t break the page layout.

I fiddled around for a while with a few other (not so successful) algorithms and then I almost gave up.

Logarithms to the rescue

I finally thought of the logarithmic scale and after a couple of attempts it looked like my idea of a nice tag cloud.

var countDiff = Math.log(maxCount) - Math.log(minCount);
var sizeDiff = maxSize - minSize;
if (countDiff == 0) countDiff = 1; // no divide by zero

for (var i in doc) {
  var weight = (Math.log(doc[i].value) - Math.log(minCount)) / countDiff;
  var size = minSize + Math.round(sizeDiff * weight);
  model.tags.push( { tag: doc[i].key, size: size , count: doc[i].value } );
}

If you haven’t noticed it in the top menu yet you can check it out here.

by Mikael Lofjärd

Oh Crap: Redux

The commenting system had stopped working again. Christ, I really need to pay more attention to it. It’s probably been down since at least Thursday.

On the other hand, I managed to remove my old CouchDB views without crashing the server. I can keep telling myself that something worked out the way it should.

by Mikael Lofjärd

Refresh

I’ve done a fair bit of CSS and HTML work today, so you might need to hit F5 and refresh your cache if the site looks weird. =)

by Mikael Lofjärd

Sorry, sharing is not available as a feature in your browser.

You can share the link to the page if you want!

URL