{-# LANGUAGE NoMonomorphismRestriction #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE TypeSynonymInstances #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE ExistentialQuantification #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE MultiParamTypeClasses #-} module Main where import Prelude hiding ((.)) import Control.Lens import Control.Monad.State import qualified Data.Text as T import Snap.Http.Server.Config import Snap.Core import Snap.Util.FileServe import Snap.Snaplet import Snap.Snaplet.Heist import Heist import Heist.Interpreted -- If we universally quantify FooSnaplet to get rid of the type parameter -- mkLabels throws an error "Can't reify a GADT data constructor" data FooSnaplet = FooSnaplet { _fooHeist :: Snaplet (Heist FooSnaplet) , _fooVal :: Int } makeLenses ''FooSnaplet instance HasHeist FooSnaplet where heistLens = subSnaplet fooHeist fooInit :: SnapletInit FooSnaplet FooSnaplet fooInit = makeSnaplet "foosnaplet" "foo snaplet" Nothing $ do hs <- nestSnaplet "heist" fooHeist $ heistInit "templates" addTemplates hs "foo" rootUrl <- getSnapletRootURL fooLens <- getLens addRoutes [("fooRootUrl", writeBS rootUrl) ,("aoeuhtns", renderWithSplices "foo/foopage" ("asplice" ## fooSplice fooLens)) ,("", heistServe) ] return $ FooSnaplet hs 42 --fooSplice :: (Lens (Snaplet b) (Snaplet (FooSnaplet b))) -- -> SnapletSplice (Handler b b) fooSplice :: (SnapletLens (Snaplet b) FooSnaplet) -> SnapletISplice b fooSplice fooLens = do val <- lift $ with' fooLens $ gets _fooVal textSplice $ T.pack $ "splice value" ++ (show val) ------------------------------------------------------------------------------ data App = App { _foo :: Snaplet (FooSnaplet) } makeLenses ''App app :: SnapletInit App App app = makeSnaplet "app" "nested snaplet application" Nothing $ do fs <- embedSnaplet "foo" foo fooInit addRoutes [ ("/hello", writeText "hello world") , ("/public", serveDirectory "public") ] return $ App fs main :: IO () main = serveSnaplet defaultConfig app