happstack-heist 7.0.2 → 7.1.0
raw patch · 2 files changed
+118/−44 lines, 2 filesdep +eitherdep +textdep ~happstack-serverdep ~heistPVP ok
version bump matches the API change (PVP)
Dependencies added: either, text
Dependency ranges changed: happstack-server, heist
API changes (from Hackage documentation)
- Happstack.Server.Heist: render :: (MonadPlus m, MonadIO m) => TemplateDirectory m -> ByteString -> m Response
- Happstack.Server.Heist: templateReloader :: (MonadIO m, MonadIO n) => TemplateDirectory m -> n Response
- Happstack.Server.Heist: templateServe :: (ServerMonad m, MonadPlus m, MonadIO m) => TemplateDirectory m -> m Response
+ Happstack.Server.Heist: heistServe :: Happstack m => HeistState m -> m Response
+ Happstack.Server.Heist: initHeistCompiled :: (MonadIO m, Monad n) => [(Text, Splice n)] -> [(Text, AttrSplice n)] -> FilePath -> m (Either [String] (HeistState n))
Files
- Happstack/Server/Heist.hs +112/−40
- happstack-heist.cabal +6/−4
Happstack/Server/Heist.hs view
@@ -1,53 +1,125 @@--- | functions for using Heist with Happstack+-- | This module provides support for serving compiled Heist templates using Happstack. ----- See the Heist Section of the Happstack Crash Course for detailed documentation:+-- The primary function provided by this module is: ----- <http://happstack.com/docs/crashcourse/Templates.html#helloheist>+-- heistServe :: (Happstack m) => HeistState m -> m Response+--+-- It also provides the 'initHeistCompiled' helper function for+-- creating a 'HeistState'. Though you are free to use other functions+-- from the Heist library instead.+--+-- Here is a simple example:+--+-- > module Main where+-- >+-- > import Control.Applicative ((<$>))+-- > import Control.Monad (msum)+-- > import qualified Data.Text as T+-- > import Happstack.Server (dir, nullConf, nullDir, simpleHTTP, seeOther, toResponse)+-- > import Happstack.Server.Heist (heistServe, initHeistCompiled)+-- > import Heist (getParamNode)+-- > import Heist.Compiled (Splice, yieldRuntimeText)+-- > import qualified Text.XmlHtml as X+-- >+-- > -- | factorial splice+-- > factSplice :: (Monad m) => Splice m+-- > factSplice =+-- > do intStr <- T.unpack . X.nodeText <$> getParamNode+-- > let res = yieldRuntimeText $+-- > do case reads intStr of+-- > [(n,[])] ->+-- > return (T.pack $ show $ product [1..(n :: Integer)])+-- > _ ->+-- > return (T.pack $ "Unable to parse " ++ intStr ++ " as an Integer.")+-- > return $ res+-- >+-- > main :: IO ()+-- > main =+-- > do heistState <- do+-- > r <- initHeistCompiled [(T.pack "fact", factSplice)] [] "."+-- > case r of+-- > (Left e) -> error $ unlines e+-- > (Right heistState) -> return $ heistState+-- > simpleHTTP nullConf $ msum+-- > [ dir "heist" $ heistServe heistState+-- > , nullDir >> seeOther "/heist/factorial" (toResponse "/heist/factorial")+-- > ]+--+-- It uses the following template file (@factorial.tpl@):+--+-- @+-- \<html\>+-- \<head\>+-- \<title\>Factorial Page\<\/title\>+-- \<\/head\>+-- \<body\>+-- \<h1\>Factorial Page\<\/h1\>+-- \<p\>The factorial of 6 is \<fact\>6\<\/fact\>\<\/p\>+-- \<\/body\>+-- \<\/html\>+-- @+--+-- For more information on using Compiled Heist Templates see:+--+-- <http://snapframework.com/docs/tutorials/compiled-splices>+--+-- And also see the Heist Section of the Happstack Crash Course:+--+-- <http://happstack.com/docs/crashcourse/>+-- module Happstack.Server.Heist- ( templateReloader- , templateServe- , render- ) where+ ( initHeistCompiled+ , heistServe+ )+ where import Blaze.ByteString.Builder (toLazyByteString)-import Control.Monad (MonadPlus(mzero), msum, liftM)+import Control.Monad (MonadPlus(mzero), msum) import Control.Monad.Trans (MonadIO(liftIO))+import Control.Monad.Trans.Either (EitherT(runEitherT))+import Data.Monoid (mempty) import Data.ByteString.Char8 (ByteString) import qualified Data.ByteString.Char8 as B-import qualified Data.ByteString.Lazy as L-import Happstack.Server (Response, ServerMonad, askRq, nullDir, rqPaths, toResponseBS)+import Data.Text (Text)+import Happstack.Server (Happstack, Response, ServerMonad, askRq, nullDir, rqPaths, toResponseBS)+import Happstack.Server.FileServe.BuildingBlocks (combineSafe)+import Heist (AttrSplice, HeistConfig(..), HeistState, defaultLoadTimeSplices, initHeist, loadTemplates)+import Heist.Compiled (Splice, renderTemplate) import System.FilePath (joinPath)-import Heist.Compiled (renderTemplate)-import Heist.TemplateDirectory (TemplateDirectory, getDirectoryHS, reloadTemplateDirectory) --- | serve the heist templates from the 'TemplateDirectory m'-templateServe :: (ServerMonad m, MonadPlus m, MonadIO m) =>- TemplateDirectory m- -> m Response-templateServe td =- msum [ nullDir >> render td (B.pack "index")+initHeistCompiled :: (MonadIO m, Monad n) =>+ [(Text, Splice n)] -- ^ compiled splices+ -> [(Text, AttrSplice n)] -- ^ attribute splices+ -> FilePath -- ^ path to template directory+ -> m (Either [String] (HeistState n))+initHeistCompiled splices attrSplices templateDir =+ liftIO $ runEitherT $+ do templateRepo <- loadTemplates templateDir+ initHeist $ mempty { hcLoadTimeSplices = defaultLoadTimeSplices+ , hcCompiledSplices = splices+ , hcAttributeSplices = attrSplices+ , hcTemplates = templateRepo+ }++heistServe :: (Happstack m) =>+ HeistState m+ -> m Response+heistServe heistState =+ msum [ nullDir >> renderHeistTemplate heistState (B.pack "index") , do rq <- askRq- let safepath = joinPath $ filter (\x->not (null x) && x /= ".." && x /= ".") (rqPaths rq)- render td (B.pack safepath)+ case combineSafe "" (joinPath (rqPaths rq)) of+ Nothing -> mzero+ (Just safepath) ->+ renderHeistTemplate heistState (B.pack safepath) ] --- | force a reload of the templates from disk-templateReloader :: (MonadIO m, MonadIO n) =>- TemplateDirectory m- -> n Response-templateReloader td = do- e <- liftIO $ reloadTemplateDirectory td- return $ toResponseBS (B.pack "text/plain; charset=utf-8") $- L.fromChunks [either B.pack (const $ B.pack "Templates loaded successfully.") e]----- | render the specified template-render:: (MonadPlus m, MonadIO m) =>- TemplateDirectory m -- ^ 'TemplateDirectory' handle- -> ByteString -- ^ template name- -> m Response-render td template = do- ts <- liftIO $ getDirectoryHS td- let t = renderTemplate ts template- flip (maybe mzero) t $ \(builder, mimeType) ->- liftM (toResponseBS mimeType . toLazyByteString) builder+renderHeistTemplate :: (MonadPlus n) =>+ HeistState n+ -> ByteString+ -> n Response+renderHeistTemplate heistState templateName =+ case renderTemplate heistState templateName of+ Nothing -> mzero+ Just (builderM, mimeType) ->+ do builder <- builderM+ return $ toResponseBS mimeType (toLazyByteString builder)
happstack-heist.cabal view
@@ -1,5 +1,5 @@ Name: happstack-heist-Version: 7.0.2+Version: 7.1.0 Synopsis: Support for using Heist templates in Happstack Description: Happstack is a web application framework. Heist is an XML templating solution. This package makes it easy to use Heist templates with Happstack. Homepage: http://www.happstack.com/@@ -22,7 +22,9 @@ Build-depends: base >= 3.0 && < 5.0, blaze-builder >= 0.2 && <0.4, bytestring >= 0.9 && < 0.11,+ either == 3.4.*, filepath,- happstack-server >= 6.0 && < 7.2,- heist >= 0.10 && < 0.12,- mtl == 2.*+ happstack-server >= 7.0 && < 7.2,+ heist >= 0.11 && < 0.12,+ mtl == 2.*,+ text >= 0.10 && < 0.12