Search code examples
haskellhaskell-snap-frameworkheist

Heist example not working: ‘hcCompiledSplices’ is not a record selector


I'm trying to understand how to use Heist, but none of the examples I find seem to be working and I can't seem to find anyone else that's having the same issue that I am. I found some example code here:

https://www.schoolofhaskell.com/school/to-infinity-and-beyond/older-but-still-interesting/compiled-heist-insight-with-no-snap-in-sight

However, when I try to run the first example, I get the following error:

Main.hs:20:15:
    ‘hcCompiledSplices’ is not a record selector
    In the expression:
    mempty
        {hcCompiledSplices = "foo" ## splice,
        hcTemplateLocations = [loadTemplates "."]}
    In an equation for ‘heistConfig’:
        heistConfig
        = mempty
            {hcCompiledSplices = "foo" ## splice,
            hcTemplateLocations = [loadTemplates "."]}
    In the expression:
    do { let heistConfig = ...;
        heistState <- either (error "oops") id
                        <$> (runEitherT $ initHeist heistConfig);
        builder <- maybe (error "oops") fst
                    $ renderTemplate heistState "simple";
        toByteStringIO B.putStr builder }

Main.hs:22:15:
    ‘hcTemplateLocations’ is not a record selector
    In the expression:
    mempty
        {hcCompiledSplices = "foo" ## splice,
        hcTemplateLocations = [loadTemplates "."]}
    In an equation for ‘heistConfig’:
        heistConfig
        = mempty
            {hcCompiledSplices = "foo" ## splice,
            hcTemplateLocations = [loadTemplates "."]}
    In the expression:
    do { let heistConfig = ...;
        heistState <- either (error "oops") id
                        <$> (runEitherT $ initHeist heistConfig);
        builder <- maybe (error "oops") fst
                    $ renderTemplate heistState "simple";
        toByteStringIO B.putStr builder }

What am I doing wrong?


Solution

  • Using lenses seems to be the way to do things now.

    Also, I change the template simple.tpl to use the tag <h:foo>...</h:foo> instead of just <foo>...</foo>.

    {-# LANGUAGE OverloadedStrings  #-}
    
    module Lib2 where
    
    -- import Data.Monoid
    import qualified Data.Text as T
    import qualified Data.ByteString as B
    import Blaze.ByteString.Builder
    import Control.Monad
    import Control.Monad.IO.Class
    import Control.Applicative
    import Control.Monad.Trans.Either
    import Heist
    import Heist.Compiled as C
    import Control.Lens
    
    runtime :: RuntimeSplice IO T.Text
    runtime = liftIO $ do
        putStrLn "Write something:"
        T.pack <$> getLine
    
    splice :: Splice IO
    splice = return $ C.yieldRuntimeText $ runtime
    
    main = do
        let heistConfig = emptyHeistConfig
              & hcTemplateLocations .~ [ loadTemplates "." ]
              & hcCompiledSplices .~  ( "foo" ## splice )
            reportErrors errs = error ("errors: " ++ unlines errs)
        heistState <- either reportErrors id <$> 
             (runEitherT $ initHeist heistConfig)
        builder <- maybe (error "oops") fst $
             renderTemplate heistState "simple"
        toByteStringIO B.putStr builder