Permalink
Browse files

Add generic render and serve functions for the heist snaplet

  • Loading branch information...
1 parent bbd3572 commit 20f0a7738c2f2062e27a8cbce370ea5532aee2cb @mightybyte mightybyte committed Mar 4, 2013
Showing with 274 additions and 80 deletions.
  1. +3 −1 snap.cabal
  2. +103 −38 src/Snap/Snaplet/Heist.hs
  3. +37 −0 src/Snap/Snaplet/Heist/Generic.hs
  4. +29 −0 src/Snap/Snaplet/Heist/Internal.hs
  5. +102 −41 src/Snap/Snaplet/HeistNoClass.hs
View
@@ -1,5 +1,5 @@
name: snap
-version: 0.11.2
+version: 0.11.3
synopsis: Top-level package for the Snap Web Framework
description:
This is the top-level package for the official Snap Framework libraries.
@@ -111,6 +111,7 @@ Library
Snap.Snaplet.Heist
Snap.Snaplet.HeistNoClass
Snap.Snaplet.Heist.Compiled
+ Snap.Snaplet.Heist.Generic
Snap.Snaplet.Heist.Interpreted
Snap.Snaplet.Auth
Snap.Snaplet.Auth.Backends.JsonFile
@@ -133,6 +134,7 @@ Library
Snap.Snaplet.Auth.Types
Snap.Snaplet.Auth.Handlers
Snap.Snaplet.Auth.SpliceHelpers
+ Snap.Snaplet.Heist.Internal
Snap.Snaplet.Internal.Initializer
Snap.Snaplet.Internal.LensT
Snap.Snaplet.Internal.Lensed
@@ -13,6 +13,7 @@ module Snap.Snaplet.Heist
-- $initializerSection
, heistInit
, heistInit'
+ , Unclassed.setInterpreted
, addTemplates
, addTemplatesAt
, Unclassed.addConfig
@@ -22,6 +23,12 @@ module Snap.Snaplet.Heist
-- * Handler Functions
-- $handlerSection
+ , gRender
+ , gRenderAs
+ , gHeistServe
+ , gHeistServeSingle
+ , chooseMode
+
, cRender
, cRenderAs
, cHeistServe
@@ -46,14 +53,15 @@ module Snap.Snaplet.Heist
------------------------------------------------------------------------------
import Prelude hiding (id, (.))
+import Control.Monad.State
import Data.ByteString (ByteString)
import Data.Text (Text)
import Heist
------------------------------------------------------------------------------
import Snap.Snaplet
+import Snap.Snaplet.Heist.Internal
import qualified Snap.Snaplet.HeistNoClass as Unclassed
-import Snap.Snaplet.HeistNoClass ( Heist
- , heistInit
+import Snap.Snaplet.HeistNoClass ( heistInit
, heistInit'
, clearHeistCache
)
@@ -148,32 +156,67 @@ withHeistState = Unclassed.withHeistState' heistLens
-- $handlerSection
-- This section contains functions in the 'Handler' monad that you'll use in
--- processing requests. Functions beginning with a 'c' prefix use compiled
--- template rendering. The other functions use the older interpreted
--- rendering. Splices added with addSplices will only work if you use
--- interpreted rendering.
+-- processing requests. Functions beginning with a 'g' prefix use generic
+-- rendering that checks the preferred rendering mode and chooses
+-- appropriately. Functions beginning with a 'c' prefix use compiled template
+-- rendering. The other functions use the older interpreted rendering.
+-- Splices added with addSplices will only work if you use interpreted
+-- rendering.
+--
+-- The generic functions are useful if you are writing general snaplets that
+-- use heist, but need to work for applications that use either interpreted
+-- or compiled mode.
------------------------------------------------------------------------------
--- | Renders a template as text\/html. If the given template is not found,
--- this returns 'empty'.
-render :: HasHeist b
- => ByteString
- -- ^ Template name
- -> Handler b v ()
-render t = withTop' heistLens (Unclassed.render t)
+-- | Generic version of 'render'/'cRender'.
+gRender :: HasHeist b
+ => ByteString
+ -- ^ Template name
+ -> Handler b v ()
+gRender t = withTop' heistLens (Unclassed.gRender t)
------------------------------------------------------------------------------
--- | Renders a template as the given content type. If the given template
--- is not found, this returns 'empty'.
-renderAs :: HasHeist b
- => ByteString
- -- ^ Content type to render with
- -> ByteString
- -- ^ Template name
- -> Handler b v ()
-renderAs ct t = withTop' heistLens (Unclassed.renderAs ct t)
+-- | Generic version of 'renderAs'/'cRenderAs'.
+gRenderAs :: HasHeist b
+ => ByteString
+ -- ^ Content type to render with
+ -> ByteString
+ -- ^ Template name
+ -> Handler b v ()
+gRenderAs ct t = withTop' heistLens (Unclassed.gRenderAs ct t)
+
+
+------------------------------------------------------------------------------
+-- | Generic version of 'heistServe'/'cHeistServe'.
+gHeistServe :: HasHeist b => Handler b v ()
+gHeistServe = withTop' heistLens Unclassed.gHeistServe
+
+
+------------------------------------------------------------------------------
+-- | Generic version of 'heistServeSingle'/'cHeistServeSingle'.
+gHeistServeSingle :: HasHeist b
+ => ByteString
+ -- ^ Template name
+ -> Handler b v ()
+gHeistServeSingle t = withTop' heistLens (Unclassed.gHeistServeSingle t)
+
+
+------------------------------------------------------------------------------
+-- | Chooses between a compiled action and an interpreted action based on the
+-- configured default.
+chooseMode :: HasHeist b
+ => Handler b v a
+ -- ^ A compiled action
+ -> Handler b v a
+ -- ^ An interpreted action
+ -> Handler b v a
+chooseMode cAction iAction = do
+ mode <- withTop' heistLens $ gets _defMode
+ case mode of
+ Unclassed.Compiled -> cAction
+ Unclassed.Interpreted -> iAction
------------------------------------------------------------------------------
@@ -199,6 +242,44 @@ cRenderAs ct t = withTop' heistLens (Unclassed.cRenderAs ct t)
------------------------------------------------------------------------------
+-- | A compiled version of 'heistServe'.
+cHeistServe :: HasHeist b => Handler b v ()
+cHeistServe = withTop' heistLens Unclassed.cHeistServe
+
+
+------------------------------------------------------------------------------
+-- | Analogous to 'fileServeSingle'. If the given template is not found,
+-- this throws an error.
+cHeistServeSingle :: HasHeist b
+ => ByteString
+ -- ^ Template name
+ -> Handler b v ()
+cHeistServeSingle t = withTop' heistLens (Unclassed.cHeistServeSingle t)
+
+
+------------------------------------------------------------------------------
+-- | Renders a template as text\/html. If the given template is not found,
+-- this returns 'empty'.
+render :: HasHeist b
+ => ByteString
+ -- ^ Template name
+ -> Handler b v ()
+render t = withTop' heistLens (Unclassed.render t)
+
+
+------------------------------------------------------------------------------
+-- | Renders a template as the given content type. If the given template
+-- is not found, this returns 'empty'.
+renderAs :: HasHeist b
+ => ByteString
+ -- ^ Content type to render with
+ -> ByteString
+ -- ^ Template name
+ -> Handler b v ()
+renderAs ct t = withTop' heistLens (Unclassed.renderAs ct t)
+
+
+------------------------------------------------------------------------------
-- | A handler that serves all the templates (similar to 'serveDirectory').
-- If the template specified in the request path is not found, it returns
-- 'empty'. Also, this function does not serve any templates beginning with
@@ -222,22 +303,6 @@ heistServeSingle t = withTop' heistLens (Unclassed.heistServeSingle t)
------------------------------------------------------------------------------
--- | A compiled version of 'heistServe'.
-cHeistServe :: HasHeist b => Handler b v ()
-cHeistServe = withTop' heistLens Unclassed.cHeistServe
-
-
-------------------------------------------------------------------------------
--- | Analogous to 'fileServeSingle'. If the given template is not found,
--- this throws an error.
-cHeistServeSingle :: HasHeist b
- => ByteString
- -- ^ Template name
- -> Handler b v ()
-cHeistServeSingle t = withTop' heistLens (Unclassed.cHeistServeSingle t)
-
-
-------------------------------------------------------------------------------
-- | Renders a template with a given set of splices. This is syntax sugar for
-- a common combination of heistLocal, bindSplices, and render.
renderWithSplices :: HasHeist b
@@ -0,0 +1,37 @@
+{-|
+
+A module exporting only generic functions that choose between compiled and
+interpreted mode based on the setting specified in the initializer. This
+module is most useful for writitng general snaplets that use Heist and are
+meant to be used in applications that might use either interpreted or compiled
+templates.
+
+-}
+module Snap.Snaplet.Heist.Generic
+ ( Heist
+ , HasHeist(..)
+ , SnapletHeist
+ , SnapletCSplice
+
+ -- * Initializer Functions
+ -- $initializerSection
+ , heistInit
+ , heistInit'
+ , addTemplates
+ , addTemplatesAt
+ , addConfig
+ , modifyHeistState
+ , withHeistState
+
+ -- * Handler Functions
+ -- $handlerSection
+ , gRender
+ , gRenderAs
+ , gHeistServe
+ , gHeistServeSingle
+ , chooseMode
+
+ , clearHeistCache
+ ) where
+
+import Snap.Snaplet.Heist
@@ -0,0 +1,29 @@
+module Snap.Snaplet.Heist.Internal where
+
+import Prelude hiding ((.), id)
+import Data.IORef
+import Heist
+import Heist.Splices.Cache
+
+import Snap.Snaplet
+
+
+data DefaultMode = Compiled | Interpreted
+
+
+------------------------------------------------------------------------------
+-- | The state for the Heist snaplet. To use the Heist snaplet in your app
+-- include this in your application state and use 'heistInit' to initialize
+-- it. The type parameter b will typically be the base state type for your
+-- application.
+data Heist b = Configuring
+ { _heistConfig :: IORef (HeistConfig (Handler b b), DefaultMode)
+ }
+ | Running
+ { _heistState :: HeistState (Handler b b)
+ , _heistCTS :: CacheTagState
+ , _defMode :: DefaultMode
+ }
+
+
+
Oops, something went wrong.

0 comments on commit 20f0a77

Please sign in to comment.