Mike Fallows

Compiling `.kit` files with Grunt

This week I needed to hand over some files to another development team. I was originally commissioned to create some email templates way back in early 2013 for Campaign Monitor and, apart from some small tweaks and additions, the templates have hardly changed since. You can view an archived version of one of the earliest. But this is a better one. Design credit to my good friend Eóin MacManus.

The templates made some heavy use of <repeater> regions, a feature of Campaign Monitor’s templates that I utilised to allow multiple sections with different colour backgrounds. Because this was email, it required a lot of inline CSS and a lot of code repetition to achieve the desired result. I was using CodeKit a lot at the time and the app had just introduced the .kit file feature. Kit files added variables and imports to HTML via CSS-style comments which reduced the amount of code I needed to write substantially.

This worked great for the best part of a decade as the sole developer on the project: I could easily make a small adjustment and compile the files quickly with my copy of CodeKit.

Now that I needed to pass the files on to another team, I wanted to do so without the requirement of a proprietary app to compile the templates. A quick search and I discovered there was an open source node-based compiler for .kit files and a Grunt plugin that leveraged it. I was aware of Grunt as an alternative task runner to something like CodeKit and it had a reputation for having a straightforward build pipeline so it seemed like a good solution.

First I installed Grunt and the CodeKit plugin:

npm i -D grunt grunt-codekit

Then I set up a simple Gruntfile.js config file that would compile my newsletter template to HTML:

module.exports = function(grunt) {

grunt.initConfig({
codekit: {
'build/newsletter/newsletter.html': 'src/newsletter/newsletter.kit'
},
});

grunt.loadNpmTasks('grunt-codekit');

grunt.registerTask('default', ['codekit']);
};

Now all I needed to do was run grunt at the root of the project and my src/newsletter/newsletter.kit file would be converted to HTML at build/newsletter/newsletter.html. Easy as that!

When you add a new template to Campaign Monitor you need to upload the HTML template and also any images the template uses as a separate zip file. Now that I’d got this far I figured I could make that final step easier too. First I installed the grunt-zip plugin:

npm i -D grunt-zip

Then I added the zip task to my Gruntfile so that my images were zipped into my build folder ready to be uploaded.

module.exports = function(grunt) {

grunt.initConfig({
codekit: {
'build/newsletter/newsletter.html' : 'src/newsletter/newsletter.kit'
},
zip: {
'build/newsletter/img.zip': 'src/newsletter/img/*'
}
});

grunt.loadNpmTasks('grunt-codekit');
grunt.loadNpmTasks('grunt-zip');

grunt.registerTask('default', ['codekit', 'zip']);

};

There are potentially a bunch more steps I could add like optimising the images and minifying the HTML but as Campaign Monitor already applies its own optimisations there’s no need to overengineer this solution (as much as I’d love to).

Tagged • email