This module contains the core definitions for the Heist template system.
The Heist template system is based on XML/xhtml. It allows you to build
custom XML-based markup languages. With Heist you can define your own
domain-specific XML tags implemented with Haskell and use them in your
The most important concept in Heist is the Splice. Splices can be thought
of as functions that transform a node into a list of nodes. Heist then
substitutes the resulting list of nodes into your template in place of the
input node. Splice is implemented as a type synonym type Splice m =
TemplateMonad m [Node], and TemplateMonad has a function getParamNode
that lets you get the input node.
Suppose you have a place on your page where you want to display a link with
the text "Logout username" if the user is currently logged in or a link to
the login page if no user is logged in. Assume you have a function
getUser :: MyAppMonad (Maybe ByteString) that gets the current user.
You can implement this functionality with a Splice as follows:
link :: ByteString -> ByteString -> Node
link target text = X.Element "a" [("href", target)] [X.Text text]
loginLink :: Node
loginLink = link "/login" "Login"
logoutLink :: ByteString -> Node
logoutLink user = link "/logout" (B.append "Logout " user)
loginLogoutSplice :: Splice MyAppMonad
loginLogoutSplice = do
user <- lift getUser
return $ [maybe loginLink logoutLink user]
Next, you need to bind that splice to an XML tag. Heist stores information
about splices and templates in the TemplateState data structure. The
following code demonstrates how this splice would be used.
mySplices = [ ("loginLogout", loginLogoutSplice) ]
main = do
ets <- loadTemplates "templates" $
foldr (uncurry bindSplice) emptyTemplateState mySplices
let ts = either error id ets
t <- runMyAppMonad $ renderTemplate ts "index"
print $ maybe "Page not found" id t
Here we build up our TemplateState by starting with emptyTemplateState and
applying bindSplice for all the splices we want to add. Then we pass this
to loadTemplates our final TemplateState wrapped in an Either to handle
errors. Then we use this TemplateState to render our templates.
|Heist templates are XML documents. The hexpat library is polymorphic over
the type of strings, so here we define a Node alias to fix the string
types of the tag names and tag bodies to ByteString.
|A Splice is a TemplateMonad computation that returns [Node].
|A Template is a forest of XML nodes.
Holds all the state information needed for template processing:
- a collection of named templates. If you use the <apply
template="foo"> tag to include another template by name, "foo"
is looked up in here.
- the mapping from tag names to Splices.
- a flag to control whether we will recurse during splice processing.
We'll illustrate the recursion flag with a small example template:
Assume that "foo" is bound to a splice procedure. Running the foo
splice will result in a list of nodes L; if the recursion flag is on we
will recursively scan L for splices, otherwise L will be included in the
|Functions and declarations on TemplateState values
|Adds a template to the template state.
|An empty template state, with Heist's default splices (<bind> and
|Convenience function for looking up a splice.
|Sets the templateMap in a TemplateState.
|Traverses the specified directory structure and builds a
TemplateState by loading all the files with a .tpl extension.
Heist hooks allow you to modify templates when they are loaded and before
and after they are run. Every time you call one of the addAbcHook
functions the hook is added to onto the processing pipeline. The hooks
processes the template in the order that they were added to the
The pre-run and post-run hooks are run before and after every template is
run/rendered. You should be careful what code you put in these hooks
because it can significantly affect the performance of your site.
|Adds an on-load hook to a TemplateState.
|Adds a pre-run hook to a TemplateState.
|Adds a post-run hook to a TemplateState.
|Stops the recursive processing of splices.
|Gets the node currently being processed.
|Performs splice processing on a list of nodes.
|Gets the current context
|Functions for running splices and templates
|Looks up a template name in the supplied TemplateState and runs
it in the underlying monad.
|Looks up a template name evaluates it. Same as runTemplate except it
runs in TemplateMonad instead of m.
|Renders a template from the specified TemplateState.
|Binds a list of constant string splices
|:: Monad m|
|=> TemplateState m||The initial template state
|-> Node||The splice's input node
|-> Splice m||The splice
|-> m [Node]|
|Runs a splice in the underlying monad. Splices require two
parameters, the template state, and an input node.
|Runs a template in the underlying monad. Similar to runSplice
except that templates don't require a Node as a parameter.
|Reads an XML document from disk.
|Modifies a TemplateState to include a static tag.
|Produced by Haddock version 2.6.1|