I use compiled Heist. My splices only do run-time work (no load-time work). I have a template.tpl
like this:
<html>
<head>
<title><titleSplice/></title>
</head>
<body>
<bodySplice/>
</body>
</html>
This is how I do things:
- Within the Snap action for a
/:param
route, I userenderTemplate heistState "template"
to obtain aMyHeistRuntimeMonad Builder
. - I can pass the
:param
value to my splice by putting it into my runtime monad via ReaderT:type MyHeistRuntimeMonad = ReaderT String IO
. (Where theString
is for the passed in:param
value.)
And that is my problem. The only way to pass data from my routes to my splices is through the heist runtime monad. This makes things a bit complicated. My questions:
- Is there no alternative to
renderTemplate
that allows me to pass data directly to the template? For example, something like this:renderTemplate' "template" [("titleSplice", "myTitle"), ("bodySplice", "myBody")]
. - If this is not possible, why not? I'm just wondering why things were designed the way they were. I don't quite get it.
The example that you're focusing on with the runtime data of
[("titleSplice", "myTitle"), ("bodySplice", "myBody")]
is MUCH less powerful than the model that Heist exposes. Your model is simple tag name substitution. Heist's splice model isNode -> m [Node]
. This allows it to do very powerful things like the cache tag, the markdown tag, and even head merging with the html tag.The monad transformer approach Heist uses was a simple and obvious implementation that makes all runtime data accessible to splices. It also thinks of splices as a universal API provided by the backend that can be used anywhere by front end designers. Are other formulations possible? I'm sure there are. But this one is simple and powerful.
Your formulation is also very template specific. If a designer wanted to add some new kind of data to a page, you would have to change the Haskell code to accommodate that. With Heist's approach no Haskell code change would be necessary. This gives designers a lot of power to change things in a very decoupled manner.