Search code examples
haskellheist

Getting heist 0.14.0.1 to work


To be clear, I am only interested in using heist, not snap. I'm reading through ocharles's tutorial (https://ocharles.org.uk/blog/posts/2013-12-11-24-days-of-hackage-heist.html) and trying to adapt his first example. It is a simple bind tag. My code is as follows:

-- main.hs
main :: IO ()
main = billy

billy :: IO ()
billy = do
  heistState <- either (error . concat) id <$>
       (runEitherT $ initHeist myConfig)
  builder <- maybe (error "oops2") fst $
       renderTemplate heistState "billy"
  toByteStringIO BS.putStr builder
  BS.putStr "\n"

myConfig = (set hcNamespace "") $
           (set hcInterpretedSplices defaultInterpretedSplices) $
           (set hcTemplateLocations [loadTemplates "templates"]) $
           emptyHeistConfig

And the template I'm using:

<bind tag="kiddo">Billy</bind>
Merry Christmas, <kiddo/>!

The output I get is this:

<bind tag='kiddo'>Billy</bind>&#10;
Merry Christmas, <kiddo></kiddo>!

I cannot see why the bind tag doesn't work. I've actually updated his code to use the new lens-style heist config, and I know about the namespace trickery that was introduced somewhat recently in heist, but I can't see what else needs to change to get this example working.


Solution

  • Here is what I was able to get to work:

    {-# LANGUAGE OverloadedStrings  #-}
    
    import qualified Data.ByteString as B
    import Blaze.ByteString.Builder (toByteStringIO)
    import Control.Applicative
    import Control.Monad.Trans.Either (runEitherT)
    import Heist
    import Heist.Compiled (renderTemplate)
    import Control.Lens
    
    heistConfig =
      (set hcNamespace "") $
      -- (set hcInterpretedSplices defaultInterpretedSplices) $
      (set hcLoadTimeSplices defaultLoadTimeSplices) $
      (set hcTemplateLocations [loadTemplates "."]) $
      emptyHeistConfig
    
    main = do
        heistState <- either (error "oops") id <$>
             (runEitherT $ initHeist heistConfig)
        builder <- maybe (error "oops") fst $
             renderTemplate heistState "billy"
        toByteStringIO B.putStr builder
    

    Apparently bind is a load time splice, not an interpreted splice.