ANNOUNCE: HStringTemplate -- An Elegant, Functional, Nifty Templating Engine for Haskell

HStringTemplate is a port of Terrence Parr’s lovely StringTemplate (http://www.stringtemplate.org) engine to Haskell. It is available, cabalized, at: darcs get http://code.haskell.org/HStringTemplate/ As interest has grown in using Haskell for web applications, there has been an increasing buzz about the need for a good templating engine in Haskell. Why might we need this? After all, Haskell has lovely combinator libraries for generating HTML programmatically, enforcing good form through its type system. But sometimes, we don’t want well-formed HTML. We want the ugly stuff that floats around to deal with eight varieties of browser incompatibilities and the latest silly ajax trick. Or sometimes we’re working with a team of graphic designers, and they want to work in almost-HTML. Or sometimes we just want to be able to change the design of a web application on the fly, completely independent of our program logic, and of, heavens forbid, recompiling and possibly messing with a live application. So template engines are popular, and indeed, considered a key part of most web frameworks out there. One problem — they’re mainly awful, imperatively-conceived behemoths that capriciously mix program logic with display and, consequently, entail a great deal of overhead. Enter StringTemplate, a nifty and fairly-well developed template format that’s both pure and functional, and therefore pretty much the only one of its kind. Indeed, it also seems to be getting heavy use in code generation because its paradigm maps neatly to traversing parse-trees. HStringTemplate is not feature-complete, and indeed is only at version 0.1. But it should implement pretty much everything in the standard StringTemplate 3.0 grammar, only nicer, because it’s in Haskell. There are scads of different recursive constructs and ways to handle inclusion and inheritance. Furthermore, HStringTemplate handles conditionals, and sports also a very Haskellish implementation of custom rendering. Templates can be constructed that return strings, ShowSs, bytestrings, or even pretty printer Docs that handle wrapping, indentation, and fill elegantly. Even better, these templates are parsed and compiled only once, after which point there isn't a syntax tree anymore, just a function that operates on the environment of attributes that have been passed to it. Where I take it from here depends in part on what sort of response I get, so patches, gripes, API comments and feature requests are all more than welcome. Please note that I'm still working in 6.6.1. Everything should be in place to compile properly with the base split, but if it isn't, again, patches more than welcome. Full announcement at: http://fmapfixreturn.wordpress.com/ --SC

s.clover:
HStringTemplate is a port of Terrence Parr’s lovely StringTemplate (http://www.stringtemplate.org) engine to Haskell.
It is available, cabalized, at: darcs get http://code.haskell.org/HStringTemplate/
Looks very useful! Will this be on hackage.haskell.org soon? I can't wait to: cabal install HStringTemplate :) -- Don

I'm absolutely planning to get it up there, but it needs a bit more work first. Just today, gwern sent a bunch of very nice patches that cleaned up some -Wall messages, and fixed a build issue with 6.8. And then, thanks to an email from Martin Lütke, I realized that I had foolishly not exported a function to query groups, because I was too worried about functions to compose them! So yeah, letting your baby out into the world is a bit scary, but everyone's been quite helpful and supportive so far, and hopefully I'll feel ready to get it on hackage in the next week or two. (Of course, after that, I'm now puzzling over the best typesafe ways to represent html entity encoding and url escaping, planning to pull together some more documentation on all the loveliness of the stringtemplate grammar, there are more quickcheck properties to be written, you know.. the usual. :-) ) --S On Jan 14, 2008, at 3:09 AM, Don Stewart wrote:
s.clover:
HStringTemplate is a port of Terrence Parr’s lovely StringTemplate (http://www.stringtemplate.org) engine to Haskell.
It is available, cabalized, at: darcs get http://code.haskell.org/HStringTemplate/
Looks very useful! Will this be on hackage.haskell.org soon?
I can't wait to:
cabal install HStringTemplate
:)
-- Don

On Jan 14, 2008 9:47 AM, Sterling Clover
HStringTemplate is a port of Terrence Parr's lovely StringTemplate (http://www.stringtemplate.org) engine to Haskell.
It is available, cabalized, at: darcs get http://code.haskell.org/HStringTemplate/
Template systems have been a crucial missing part of Haskell web development. I am very happy to hear about this project, and will definitely be looking at this in the near future! Thanks, Bit

On Jan 14, 2008 2:47 AM, Sterling Clover
HStringTemplate is a port of Terrence Parr's lovely StringTemplate (http://www.stringtemplate.org) engine to Haskell.
This is very cool. Your docs describe a function, cacheSTGroup: cacheSTGroup :: Int -> STGen a -> STGen a Given an integral amount of seconds and a group, returns a group cached for that span of time. Does not cache "misses." How does this work without breaking referential transparency? Shouldn't it be in the IO monad if it is time-dependent? Graham

Graham, I'm sort of playing fast and loose with referential transparency here, as I actually am with stringTemplateFileGroup as well. They both use unsafeIO to do what they want, and in corner cases could give silly, though not dangerous results (i.e., in the sense of being hazardous to your program, these calls are substantially less worrisome than head). stringTemplateFileGroup could conceivably be in IO, if it was strict in reading all the files in the directory it was passed, but cacheSTGroup would force every access to a group to take place in IO, which would make the library somewhat of a pain to work with. My semi-justification for this is that its referentially- transparent-enough for most use cases, in that just about the only thing one would be doing with a StringTemplate result would be outputting it again in some form anyway. In my experience, being able to "hot-edit" templates for a live app is a key benefit of a templating system, and forcing everything into IO to get that seems like an undue burden on end-users. On the other hand, I'm also open to implementing an IO API that's safe and renaming the current functions to something somewhat scarier, or moving both them and their IO equivs to distinct modules so that end users could choose which to import. A number of options seem reasonable here. --Sterl. (btw, I fixed the typo you emailed me about in the repo, and also made a few other changes I documented at http:// fmapfixreturn.wordpress.com/) On Jan 16, 2008, at 8:19 PM, Graham Fawcett wrote:
On Jan 14, 2008 2:47 AM, Sterling Clover
wrote: HStringTemplate is a port of Terrence Parr's lovely StringTemplate (http://www.stringtemplate.org) engine to Haskell.
This is very cool.
Your docs describe a function, cacheSTGroup:
cacheSTGroup :: Int -> STGen a -> STGen a Given an integral amount of seconds and a group, returns a group cached for that span of time. Does not cache "misses."
How does this work without breaking referential transparency? Shouldn't it be in the IO monad if it is time-dependent?
Graham

[removed haskell@ from the cc: list, which I think is conventional if discussion continues] Graham Fawcett wrote:
On Jan 14, 2008 2:47 AM, Sterling Clover
wrote: HStringTemplate is a port of Terrence Parr's lovely StringTemplate (http://www.stringtemplate.org) engine to Haskell.
This is very cool.
Your docs describe a function, cacheSTGroup:
cacheSTGroup :: Int -> STGen a -> STGen a Given an integral amount of seconds and a group, returns a group cached for that span of time. Does not cache "misses."
How does this work without breaking referential transparency? Shouldn't it be in the IO monad if it is time-dependent?
If the result is always the same, but only efficiency varies, then you could argue it's still referentially transparent. Of course, if the result isn't always the same (template file could be changed underneath you) then it isn't... the list is already aware of my views on behind-the-scenes lazy IO :) Jules

On Jan 13, 2008 11:47 PM, Sterling Clover
HStringTemplate is a port of Terrence Parr's lovely StringTemplate (http://www.stringtemplate.org) engine to Haskell.
Reading about the original library, I'm impressed. Can you add some examples to your darcs repository showing how to use your library? Or do you have some posted somewhere? Justin

HStringTemplate is a general purpose templating system, geared especially towards HTML and based on Terrence Parr’s Java library. On Hackage at: http://hackage.haskell.org/cgi-bin/hackage-scripts/ package/HStringTemplate-0.2 Development version at: darcs get http://code.haskell.org/ HStringTemplate/ Haddocks at: http://code.haskell.org/HStringTemplate/dist/doc/html/ HStringTemplate/Text-StringTemplate.html Additional documentation on the grammar at: http://www.antlr.org/wiki/ display/ST/StringTemplate+3.1+Documentation as well as in some posts at http://fmapfixreturn.wordpress.com Lots of cleanup, lots of additions, hopefully this is an extremely usable release. Still no group or interface files, but I suspect that those are mainly useful for code-generation, which seems like something Haskell programmers would want to use something other than a templating system for in any case. On to the good stuff: * Now on hackage! * Generics. Not one but two types. One set of simple bindings for the standard Data class, and one for syb-with-class. (Alex Drummond’s RJson library, which is really cool, was very helpful in figuring out how to do this). * A withContext method that turns any set of name-value bindings into the context for a StringTemplate. Along with the syb-with-class bindings, this should make for relatively seamless interoperability with HAppS. * Lots of other additional bindings for working with standard time formats, numeric types, etc. * Encoders. A standard mechanism for HTML-escaping strings (or javascript-escaping, or urlencoding them, or etc.) that A) ensures it happens uniformly and B) ensures it happens no more than once. * Improved pretty printing support, eliminating corner-cases where wrapping did not occur. * Creation of directory groups is now done properly in the IO monad, with caching functionality moved to the scarily-named unsafeVolatileDirectoryGroup. * 80% Top-Level testing coverage in the base. (And more to come, but I only have so much time). And of course, patches and feedback always welcome. --Sterl
participants (6)
-
Bit Connor
-
Don Stewart
-
Graham Fawcett
-
Jules Bean
-
Justin Bailey
-
Sterling Clover