Search code examples
haskellheist

Rendering a heist template returns nothing


import Data.String.Conversions
import Data.Maybe (isJust)
import qualified Heist
import qualified Heist.Interpreted as I
import qualified Heist.Compiled as HeistCom
import Heist.Internal.Types
import qualified Text.XmlHtml as X
import Data.List (sortBy)
import Data.Map.Syntax
import Data.ByteString.Builder (toLazyByteString)

renderTemplate :: String -> (HeistState IO -> HeistState IO) -> ActionM ()
renderTemplate fileName hsBinding = do
  let emptyI = return () :: MapSyntax Text (I.Splice IO)
  let emptyC = return () :: MapSyntax Text (HeistCom.Splice IO)
  let emptyA = return () :: MapSyntax Text (AttrSplice IO)
  let spliceConfig = SpliceConfig emptyI emptyI emptyC emptyA [] (\_ -> False):: SpliceConfig IO
  heist <- lift $ Heist.initHeist (HeistConfig spliceConfig "" True)
  case heist of
    Right heist' -> do
      rendered <- lift $ I.renderTemplate (hsBinding heist') $ convertString fileName
      case (rendered) of
        Just (builder, _) -> do
          lift $ print $ toLazyByteString builder
        Nothing -> error "heist error"
    Left a -> error . convertString $ show a

I'm calling the function this way:

renderTemplate "templates/compareForm"  $ I.bindSplice "test" $ I.textSplice "abcxyz"

I'm guessing it's to do with the config. I have not thoroughly thought through the above config.

Unfortunately the above is just generating an error of "heist error" (the second last line). So my question is why? My next step would be to investigate the Heist.Interpreted.renderTemplate function.


Solution

  • Finally figured this out... I needed to specify a template location...

    renderTemplate :: String -> (HeistState IO -> HeistState IO) -> ActionM ()
    renderTemplate fileName hsBinding = do
      let emptyI = return () :: MapSyntax Text (I.Splice IO)
      let emptyC = return () :: MapSyntax Text (HeistCom.Splice IO)
      let emptyA = return () :: MapSyntax Text (AttrSplice IO)
      let templateLocations = [Heist.loadTemplates "templates/"]
      let spliceConfig = SpliceConfig emptyI emptyI emptyC emptyA templateLocations (\_ -> False):: SpliceConfig IO
      heist <- lift $ Heist.initHeist (HeistConfig spliceConfig "" True)
      case heist of
        Right heist' -> do
          rendered <- lift $ I.renderTemplate (hsBinding heist') $ convertString fileName
          case (rendered) of
            Just (builder, _) -> do
              html . convertString $ toLazyByteString builder
            Nothing -> error "heist error"
        Left a -> error . convertString $ show a
    

    And the render path should not have the directory specified:

    renderTemplate "compareForm"  $ I.bindSplice "test" $ I.textSplice "abcxyz"
    

    The above might not work for compiled templates, one would probably need to modify this line (probably the (\_ -> False): let spliceConfig = SpliceConfig emptyI emptyI emptyC emptyA templateLocations (\_ -> False):: SpliceConfig IO

    There are potential performance implications with the above, see https://github.com/snapframework/heist/issues/102