A couple of days ago I ran across a really neat boilerplate for mobile-friendly development called Skeleton. This seemed great, and because I do my web development in Haskell and use Jasper’s excellent blaze-html, I wanted the
index.html coded in Haskell.
No problem, right? Wrong.
As soon as you look at the
index.html file, these top lines raise concern:
Can blaze-html do comments like that, or more complex still, are its combinators capable of closing the final
if statement but leaving the HTML tag unclosed?
The answer to this is yes, although I admit my solution is kind of hackish. As I got farther into this, I began to realize that perhaps I should have just hard-coded these if statements with
preEscapedText and moved on with my life, but it was too late at this point. I was already deep in
The first realization is that, due to the nature of the combinators, I had to define my own
body tags that would allow me to:
htmltag without closing it
bodytag but close both it and
This resulted in:
Parent is used to define the opening and closing tags. Note that the missing
> is intentional in the opening string: blaze adds it automatically after appending any attributes.
Next came actually allowing for the creation of the comments. This was actually quite simple after
StaticString/OverloadedStrings were understood.
comment is very similar to
htmlBody from above, but with one key difference: the addition of
ss. This is needed to repack the
StaticString that blaze uses for efficiency, which is typically created automagically via the
OverloadedStrings language pragma.
Usage is actually quite simple once the combinators are setup, which was of course my goal all along. First, I created
htmlTag, a function with the specific task of outputting just the conditional HTML tags:
I was then able to use this effortlessly in the
skeletonBase code that actually output the template:
And at last, we have HTML conditional comments in blaze!
As mentioned before, I know this seems a bit hackish, but it feels less hackish (and more fun!) than the alternative of just shoving a hard-coded string into the template via
preEscapedText. Plus, it was a great reason to get to know blaze’s internals a bit better.
If you can think of a better way to do this, please do let me know.