Part of my job over the past few months has involved automating some of the steps of producing an internal company email newsletter as well as producing a new responsive HTML layout for it. I’ve implemented this using Handlebars as the template system. And I’ve learned a lot about how different email clients deal with HTML content. Especially Zimbra.

The Zimbra Web UI is used by a significant proportion of the readership of the newsletter and has some interesting features that affect HTML emails.

The particular feature I had to grapple with was the UI taking any text in a HTML email that looks like a date (including words with ‘tomorrow’ or ‘today’) and turning it into a link that you can use to see events on that date. This would be great if your email contained the text “Are you free to discuss the proposal tomorrow?” because you can just mouse over tomorrow and see a pop-up of your events for tomorrow. I could see how that is useful.

But what if that text isn’t really a date reference? What if it is heading text? Like if your newsletter was called “Tomorrow’s News Today” and you had spent a lot of time styling that in accordance to your branding. Zimbra would insert links into your heading and override your styling. Which sucks.

However it turns out that Zimbra only looks at whole words on a per tag basis.

This means that this will get links inserted into it:

<h1 class="title-brand">Tomorrow's News Today</h1>

but this won’t:

<h1 class="title-brand"><span>T</span>omorrow's News <span>T</span>oday</h1>

And so long as you aren’t applying special styles to those <span> tags it won’t look any different and Zimbra won’t fiddle with it.

So I wrote a simple handlebars helper to take care of this and wrap the first character of each word in a <span>.

handlebars.registerHelper('spanner', function(content) {
    var words = content.split(' ');
    words = words.map(function(word) {
        return "<span>" + word[0] + "</span>" + word.substring(1);
    })
    return words.join(' ');
});

You would use it like this:

<h1 class="title-brand">{{{ spanner title }}}</h1>

It would probably be preferable to write this using a single regular expression string replace operation instead of a split, map, and join. However my patience with regex was short that day. ;-) This works for now.