Hamlet Version 0.2
May 9, 2010
This version isn't quite released yet, and I haven't had a chance to update the documentation, but I wanted to get the list of changes out there while it's still fresh.
The API has not changed at all, but the syntax of Hamlet templates has changed significantly. This is based on some real-world experience. Just to give a little frame of reference, I tested migrating the codebase for Search-Once.com to the new Hamlet, and the result was a net 322 reduction in lines of code.
Reversal of identifiers
The first major change is a reversal of the order of identifiers in references. In other words, you previously would write
person.name, which got translated to the Haskell code
name person. I originally chose that ordering to fit in with the object-oriented nature of many templating systems.
After much use, I've decided it just feels wrong to have identifiers in the reverse order to how Haskell naturally treats them. This is especially true when not dealing with objects; if you are just applying functions, everything is backwards! So now, to apply the function
name to the value
person, you simply write
Previously, a Hamlet template would generate a function which would take some value, and it would apply all the references inside the template to that value. For example:
would roughly generate the following:
\arg -> hamletOutput (name arg)
However, there are many templates that don't need that argument. Also, there are many times when you want to call a function without passing it any arguments. So now, arguments are gone! To get the same effect as above, you would write the following:
\person -> [$hamlet|$name.person$|]
- A number of minor bug fixes. If you care to see what those are, look at the Git log.
- Added $maybe. Very useful for error messages.
- You can use constructors directly in your references. Very useful when constructing URLs.
- You can now include query-string parameters along with your URLs. The syntax is
variableName :: (url, [(String, String)])
- Beginning-of-line escaping. If you begin a line with a backslash, the backslash is dropped and the rest of the line is treated as content. This makes it possible to start a line with a pound or period without it being interpretted as tag information. As a special case, a line containing only a backslash is converted to a newline.