diff --git a/heist.cabal b/heist.cabal
--- a/heist.cabal
+++ b/heist.cabal
@@ -1,5 +1,5 @@
 name:           heist
-version:        0.2.1
+version:        0.2.2
 synopsis:       An xhtml templating system
 license:        BSD3
 license-file:   LICENSE
@@ -79,7 +79,8 @@
     Text.Templating.Heist.Splices.Bind,
     Text.Templating.Heist.Splices.Ignore,
     Text.Templating.Heist.Splices.Markdown,
-    Text.Templating.Heist.Splices.Static
+    Text.Templating.Heist.Splices.Static,
+    Text.Templating.Heist.TemplateDirectory
 
   other-modules:
     Text.Templating.Heist.Internal,
diff --git a/src/Text/Templating/Heist.hs b/src/Text/Templating/Heist.hs
--- a/src/Text/Templating/Heist.hs
+++ b/src/Text/Templating/Heist.hs
@@ -73,9 +73,11 @@
   , addTemplate
   , emptyTemplateState
   , bindSplice
+  , bindSplices
   , lookupSplice
   , setTemplates
   , loadTemplates
+  , hasTemplate
 
     -- * Hook functions
     -- $hookDoc
@@ -88,6 +90,13 @@
   , getParamNode
   , runNodeList
   , getContext
+
+  , localParamNode
+  , getsTS
+  , getTS
+  , putTS
+  , modifyTS
+  , restoreTS
 
     -- * Functions for running splices and templates
   , evalTemplate
diff --git a/src/Text/Templating/Heist/Internal.hs b/src/Text/Templating/Heist/Internal.hs
--- a/src/Text/Templating/Heist/Internal.hs
+++ b/src/Text/Templating/Heist/Internal.hs
@@ -31,21 +31,6 @@
 
 
 ------------------------------------------------------------------------------
--- | Restores the components of TemplateState that can get modified in
--- template calls.  You should use this function instead of @putTS@ to restore
--- an old state.  Thas was needed because doctypes needs to be in a "global
--- scope" as opposed to the template call "local scope" of state items such
--- as recursionDepth, curContext, and spliceMap.
-restoreState :: Monad m => TemplateState m -> TemplateMonad m ()
-restoreState ts1 = 
-    modifyTS (\ts2 -> ts2
-        { _recursionDepth = _recursionDepth ts1
-        , _curContext = _curContext ts1
-        , _spliceMap = _spliceMap ts1
-        })
-
-
-------------------------------------------------------------------------------
 -- | Mappends a doctype to the state.
 addDoctype :: Monad m => [ByteString] -> TemplateMonad m ()
 addDoctype dt = do
@@ -85,7 +70,7 @@
 
 
 ------------------------------------------------------------------------------
--- | Bind a new splice declaration to a tag name within a 'TemplateState'.
+-- | Binds a new splice declaration to a tag name within a 'TemplateState'.
 bindSplice :: Monad m =>
               ByteString        -- ^ tag name
            -> Splice m          -- ^ splice action
@@ -95,6 +80,17 @@
 
 
 ------------------------------------------------------------------------------
+-- | Binds a set of new splice declarations within a 'TemplateState'.
+bindSplices :: Monad m =>
+               [(ByteString, Splice m)] -- ^ splices to bind
+            -> TemplateState m   -- ^ start state
+            -> TemplateState m
+bindSplices ss ts = foldl' (flip id) ts acts 
+  where
+    acts = map (uncurry bindSplice) ss
+
+
+------------------------------------------------------------------------------
 -- | Convenience function for looking up a splice.
 lookupSplice :: Monad m =>
                 ByteString
@@ -150,6 +146,15 @@
 
 
 ------------------------------------------------------------------------------
+-- | Returns 'True' if the given template can be found in the template state.
+hasTemplate :: Monad m =>
+               ByteString
+            -> TemplateState m
+            -> Bool
+hasTemplate nameStr ts = isJust $ lookupTemplate nameStr ts
+
+
+------------------------------------------------------------------------------
 -- | Convenience function for looking up a template.
 lookupTemplate :: Monad m =>
                   ByteString
@@ -333,7 +338,7 @@
     if _recurse ts' && _recursionDepth ts' < mAX_RECURSION_DEPTH
         then do modRecursionDepth (+1)
                 res <- runNodeList result
-                restoreState ts'
+                restoreTS ts'
                 return res
         else return result
   where
@@ -364,7 +369,7 @@
         ts <- getTS
         putTS (ts {_curContext = ctx})
         res <- runNodeList $ _itNodes t
-        restoreState ts
+        restoreTS ts
         return $ Just res)
 
 
@@ -381,7 +386,7 @@
         nodes <- lift $ _preRunHook ts $ _itNodes t
         putTS (ts {_curContext = ctx})
         res <- runNodeList nodes
-        restoreState ts
+        restoreTS ts
         return . Just =<< lift (_postRunHook ts res))
 
 
diff --git a/src/Text/Templating/Heist/Splices/Apply.hs b/src/Text/Templating/Heist/Splices/Apply.hs
--- a/src/Text/Templating/Heist/Splices/Apply.hs
+++ b/src/Text/Templating/Heist/Splices/Apply.hs
@@ -41,7 +41,7 @@
                       modifyTS (bindSplice "content" $ return processedChildren)
                       setContext ctx
                       result <- runNodeList $ _itNodes t
-                      restoreState st
+                      restoreTS st
                       return result)
                   (lookupTemplate attr (st {_curContext = nextCtx attr st}))
   where nextCtx name st
diff --git a/src/Text/Templating/Heist/TemplateDirectory.hs b/src/Text/Templating/Heist/TemplateDirectory.hs
new file mode 100644
--- /dev/null
+++ b/src/Text/Templating/Heist/TemplateDirectory.hs
@@ -0,0 +1,85 @@
+{-|
+
+This module defines a TemplateDirectory data structure for convenient
+interaction with templates within web apps.
+
+-}
+
+module Text.Templating.Heist.TemplateDirectory
+    ( TemplateDirectory
+    , newTemplateDirectory
+    , newTemplateDirectory'
+
+    , getDirectoryTS
+    , reloadTemplateDirectory
+    ) where
+
+------------------------------------------------------------------------------
+import           Control.Concurrent
+import           Control.Monad
+import           Control.Monad.Trans
+import           Data.ByteString.Char8 (ByteString)
+import           Text.Templating.Heist
+import           Text.Templating.Heist.Splices.Static
+
+
+------------------------------------------------------------------------------
+-- | Structure representing a template directory.
+data TemplateDirectory m
+    = TemplateDirectory
+        FilePath
+        (TemplateState m)
+        (MVar (TemplateState m))
+        StaticTagState
+
+
+------------------------------------------------------------------------------
+-- | Creates and returns a new 'TemplateDirectory' wrapped in an Either for
+-- error handling.
+newTemplateDirectory :: (MonadIO m, MonadIO n)
+                     => FilePath
+                     -> TemplateState m
+                     -> n (Either String (TemplateDirectory m))
+newTemplateDirectory dir templateState = liftIO $ do
+    (origTs,sts) <- bindStaticTag templateState
+    ets <- loadTemplates dir origTs
+    leftPass ets $ \ts -> do
+        tsMVar <- newMVar $ ts
+        return $ TemplateDirectory dir origTs tsMVar sts
+
+
+------------------------------------------------------------------------------
+-- | Creates and returns a new 'TemplateDirectory', using the monad's fail
+-- function on error.
+newTemplateDirectory' :: (MonadIO m, MonadIO n)
+                      => FilePath
+                      -> TemplateState m
+                      -> n (TemplateDirectory m)
+newTemplateDirectory' = ((either fail return =<<) .) . newTemplateDirectory
+
+
+------------------------------------------------------------------------------
+-- | Gets the 'TemplateState' from a TemplateDirectory.
+getDirectoryTS :: (Monad m, MonadIO n)
+               => TemplateDirectory m
+               -> n (TemplateState m)
+getDirectoryTS (TemplateDirectory _ _ tsMVar _) = liftIO $ readMVar $ tsMVar
+
+
+------------------------------------------------------------------------------
+-- | Clears cached content and reloads templates from disk.
+reloadTemplateDirectory :: (MonadIO m, MonadIO n)
+                        => TemplateDirectory m
+                        -> n (Either String ())
+reloadTemplateDirectory (TemplateDirectory p origTs tsMVar sts) = liftIO $ do
+    clearStaticTagCache sts
+    ets <- loadTemplates p origTs
+    leftPass ets $ \ts -> modifyMVar_ tsMVar (const $ return ts)
+
+
+------------------------------------------------------------------------------
+-- | Prepends an error onto a Left.
+leftPass :: Monad m => Either String b -> (b -> m c) -> m (Either String c)
+leftPass e m = either (return . Left . loadError) (liftM Right . m) e
+  where
+    loadError = (++) "Error loading templates: "
diff --git a/src/Text/Templating/Heist/Types.hs b/src/Text/Templating/Heist/Types.hs
--- a/src/Text/Templating/Heist/Types.hs
+++ b/src/Text/Templating/Heist/Types.hs
@@ -320,7 +320,7 @@
 
 
 ------------------------------------------------------------------------------
--- | TemplateMonad's local
+-- | TemplateMonad's 'local'.
 localParamNode :: Monad m
                => (Node -> Node)
                -> TemplateMonad m a
@@ -329,28 +329,41 @@
 
 
 ------------------------------------------------------------------------------
--- | TemplateMonad's gets
+-- | TemplateMonad's 'gets'.
 getsTS :: Monad m => (TemplateState m -> r) -> TemplateMonad m r
 getsTS f = TemplateMonad $ \_ s -> return (f s, s)
 
 
 ------------------------------------------------------------------------------
--- | TemplateMonad's get
+-- | TemplateMonad's 'get'.
 getTS :: Monad m => TemplateMonad m (TemplateState m)
 getTS = TemplateMonad $ \_ s -> return (s, s)
 
 
 ------------------------------------------------------------------------------
--- | TemplateMonad's put
+-- | TemplateMonad's 'put'.
 putTS :: Monad m => TemplateState m -> TemplateMonad m ()
 putTS s = TemplateMonad $ \_ _ -> return ((), s)
 
 
 ------------------------------------------------------------------------------
--- | TemplateMonad's modify
+-- | TemplateMonad's 'modify'.
 modifyTS :: Monad m
                     => (TemplateState m -> TemplateState m)
                     -> TemplateMonad m ()
 modifyTS f = TemplateMonad $ \_ s -> return ((), f s)
 
 
+------------------------------------------------------------------------------
+-- | Restores the components of TemplateState that can get modified in
+-- template calls.  You should use this function instead of @putTS@ to restore
+-- an old state.  Thas was needed because doctypes needs to be in a "global
+-- scope" as opposed to the template call "local scope" of state items such
+-- as recursionDepth, curContext, and spliceMap.
+restoreTS :: Monad m => TemplateState m -> TemplateMonad m ()
+restoreTS ts1 = 
+    modifyTS (\ts2 -> ts2
+        { _recursionDepth = _recursionDepth ts1
+        , _curContext = _curContext ts1
+        , _spliceMap = _spliceMap ts1
+        })
