diff --git a/heist.cabal b/heist.cabal
--- a/heist.cabal
+++ b/heist.cabal
@@ -1,5 +1,5 @@
 name:           heist
-version:        0.10.2.1
+version:        0.11.0
 synopsis:       An Haskell template system supporting both HTML5 and XML.
 description:
     Heist is a powerful template system that supports both HTML5 and XML.
@@ -149,7 +149,7 @@
     dlist                      >= 0.5     && < 0.6,
     errors                     >= 1.3     && < 1.4,
     filepath                   >= 1.3     && < 1.4,
-    hashable                   >= 1.1     && < 1.2,
+    hashable                   >= 1.1     && < 1.3,
     mtl                        >= 2.0     && < 2.2,
     process                    >= 1.1     && < 1.2,
     random                     >= 1.0.1.0 && < 1.1,
diff --git a/src/Heist.hs b/src/Heist.hs
--- a/src/Heist.hs
+++ b/src/Heist.hs
@@ -37,6 +37,7 @@
   , compiledTemplateNames
   , hasTemplate
   , spliceNames
+  , compiledSpliceNames
   , HeistT
   , evalHeistT
   , getParamNode
diff --git a/src/Heist/Common.hs b/src/Heist/Common.hs
--- a/src/Heist/Common.hs
+++ b/src/Heist/Common.hs
@@ -280,3 +280,12 @@
     enc X.UTF16LE = "utf-16"
 
 
+------------------------------------------------------------------------------
+-- | Binds a set of new splice declarations within a 'HeistState'.
+bindAttributeSplices :: [(T.Text, AttrSplice n)] -- ^ splices to bind
+                     -> HeistState n             -- ^ start state
+                     -> HeistState n
+bindAttributeSplices ss hs =
+    hs { _attrSpliceMap = Map.union (Map.fromList ss) (_attrSpliceMap hs) }
+
+
diff --git a/src/Heist/Compiled.hs b/src/Heist/Compiled.hs
--- a/src/Heist/Compiled.hs
+++ b/src/Heist/Compiled.hs
@@ -17,6 +17,26 @@
   -- * High level compiled splice API
     Splice
   , renderTemplate
+  , codeGen
+  , runChildren
+
+  -- * Functions for manipulating lists of compiled splices
+  , mapSnd
+  , applySnd
+  , textSplices
+  , nodeSplices
+  , pureSplices
+  , textSplice
+  , nodeSplice
+  , pureSplice
+  , mapInputPromise
+  , defer
+  , deferMany
+  , withSplices
+  , manyWithSplices
+  , withPureSplices
+
+  -- * Old compiled splice API
   , mapPromises
   , promiseChildren
   , promiseChildrenWith
@@ -33,23 +53,20 @@
   , yieldRuntimeText
   , yieldLater
   , addSplices
+  , withLocalSplices
 
   -- * Lower level promise functions
   , Promise
   , newEmptyPromise
-
-  -- * RuntimeSplice functions
   , getPromise
   , putPromise
   , adjustPromise
-  , codeGen
 
   -- * Running nodes and splices
   , runNodeList
   , runNode
-  , compileNode
   , runAttributes
-  , runSplice
+  , callTemplate
 
   ) where
 
diff --git a/src/Heist/Compiled/Internal.hs b/src/Heist/Compiled/Internal.hs
--- a/src/Heist/Compiled/Internal.hs
+++ b/src/Heist/Compiled/Internal.hs
@@ -8,8 +8,11 @@
 
 module Heist.Compiled.Internal where
 
+
+------------------------------------------------------------------------------
 import           Blaze.ByteString.Builder
 import           Control.Arrow
+import           Control.Monad
 import           Control.Monad.RWS.Strict
 import           Control.Monad.State.Strict
 import qualified Data.Attoparsec.Text            as AP
@@ -25,10 +28,12 @@
 import qualified Data.Vector                     as V
 import           Prelude                         hiding (catch)
 import qualified Text.XmlHtml                    as X
-
+------------------------------------------------------------------------------
 import           Heist.Common
 import           Heist.Types
+------------------------------------------------------------------------------
 
+
 ------------------------------------------------------------------------------
 -- | A compiled Splice is a HeistT computation that returns a @DList
 -- (Chunk m)@.
@@ -44,6 +49,16 @@
 
 
 ------------------------------------------------------------------------------
+-- | Runs the parameter node's children and returns the resulting compiled
+-- chunks.  By itself this function is a simple passthrough splice that makes
+-- the spliced node disappear.  In combination with locally bound splices,
+-- this function makes it easier to pass the desired view into your splices.
+runChildren :: Monad n => Splice n
+runChildren = runNodeList . X.childNodes =<< getParamNode
+{-# INLINE runChildren #-}
+
+
+------------------------------------------------------------------------------
 -- | Takes a promise function and a runtime action returning a list of items
 -- that fit in the promise and returns a Splice that executes the promise
 -- function for each item and concatenates the results.
@@ -55,14 +70,14 @@
             => (Promise a -> HeistT n IO (RuntimeSplice n Builder))
             -- ^ Use 'promiseChildrenWith' or a variant to create this
             -- function.
-            -> n [a]
+            -> RuntimeSplice n [a]
             -- ^ Runtime computation returning a list of items
             -> Splice n
 mapPromises f getList = do
     singlePromise <- newEmptyPromise
     runSingle <- f singlePromise
     return $ yieldRuntime $ do
-        list <- lift getList
+        list <- getList
         htmls <- forM list $ \item ->
             putPromise singlePromise item >> runSingle
         return $ mconcat htmls
@@ -71,9 +86,7 @@
 ------------------------------------------------------------------------------
 -- | Returns a runtime computation that simply renders the node's children.
 promiseChildren :: Monad m => HeistT m IO (RuntimeSplice m Builder)
-promiseChildren = do
-    res <- runNodeList . X.childNodes =<< getParamNode
-    return $! codeGen $! consolidate res
+promiseChildren = liftM codeGen runChildren
 {-# INLINE promiseChildren #-}
 
 
@@ -293,8 +306,9 @@
 -- | Given a list of output chunks, consolidate turns consecutive runs of
 -- @Pure Html@ values into maximally-efficient pre-rendered strict
 -- 'ByteString' chunks.
-codeGen :: Monad m => [Chunk m] -> RuntimeSplice m Builder
-codeGen l = V.foldr mappend mempty $! V.map toAct $! V.fromList l
+codeGen :: Monad m => DList (Chunk m) -> RuntimeSplice m Builder
+codeGen l = V.foldr mappend mempty $!
+            V.map toAct $! V.fromList $! consolidate l
   where
     toAct !(RuntimeHtml !m)   = m
     toAct !(Pure !h)          = return $! fromByteString h
@@ -310,8 +324,8 @@
 
 ------------------------------------------------------------------------------
 -- | Runs a single node.  If there is no splice referenced anywhere in the
--- subtree, then it is rendered as a pure chunk, otherwise it is compiled to
--- a runtime computation.
+-- subtree, then it is rendered as a pure chunk, otherwise it calls
+-- compileNode to generate the appropriate runtime computation.
 runNode :: Monad n => X.Node -> Splice n
 runNode node = localParamNode (const node) $ do
     isStatic <- subtreeIsStatic node
@@ -393,14 +407,14 @@
         return $ attrToChunk k value
 
     -- Handles attribute splices
-    doAttrSplice splice = DL.singleton $ RuntimeHtml $ lift $ do
+    doAttrSplice splice = DL.singleton $ RuntimeHtml $ do
         res <- splice v
         return $ mconcat $ map attrToBuilder res
 
     
 ------------------------------------------------------------------------------
 -- | Given a 'X.Node' in the DOM tree, produces a \"runtime splice\" that will
--- generate html at runtime. Leaves the writer monad state untouched.
+-- generate html at runtime.
 compileNode :: Monad n => X.Node -> Splice n
 compileNode (X.Element nm attrs ch) =
     -- Is this node a splice, or does it merely contain splices?
@@ -594,9 +608,21 @@
 -- during load-time splice processing.
 addSplices :: Monad m => [(Text, Splice n)] -> HeistT n m ()
 addSplices ss = modifyHS (bindSplices ss)
+{-# DEPRECATED addSplices "addSplices will be removed in the next release!  Use withLocalSplices instead."#-}
 
 
 ------------------------------------------------------------------------------
+-- | Adds a list of compiled splices to the splice map.  This function is
+-- useful because it allows compiled splices to bind other compiled splices
+-- during load-time splice processing.
+withLocalSplices :: [(Text, Splice n)]
+                 -> [(Text, AttrSplice n)]
+                 -> HeistT n IO a
+                 -> HeistT n IO a
+withLocalSplices ss as = localHS (bindSplices ss . bindAttributeSplices as)
+
+
+------------------------------------------------------------------------------
 -- | Looks up a compiled template and returns a runtime monad computation that
 -- constructs a builder.
 renderTemplate :: Monad n
@@ -604,9 +630,152 @@
                -> ByteString
                -> Maybe (n Builder, MIMEType)
 renderTemplate hs nm =
-    fmap (first interpret . fst) $! lookupTemplate nm hs _compiledTemplateMap
+    fmap (first (interpret . DL.fromList) . fst) $!
+      lookupTemplate nm hs _compiledTemplateMap
 
-interpret :: Monad m => [Chunk m] -> m Builder
+
+------------------------------------------------------------------------------
+-- | Looks up a compiled template and returns a compiled splice.
+callTemplate :: Monad n
+             => ByteString
+             -> HeistT n IO (DList (Chunk n))
+callTemplate nm = do
+    hs <- getHS
+    return $ maybe DL.empty (DL.fromList . fst . fst) $
+      lookupTemplate nm hs _compiledTemplateMap
+
+
+interpret :: Monad m => DList (Chunk m) -> m Builder
 interpret = flip evalStateT HE.empty . unRT . codeGen
+
+
+------------------------------------------------------------------------------
+-- Functions for manipulating lists of compiled splices
+------------------------------------------------------------------------------
+
+
+mapSnd :: (b -> c) -> [(d, b)] -> [(d, c)]
+mapSnd = map . second
+
+applySnd :: a -> [(d, a -> b)] -> [(d, b)]
+applySnd a = mapSnd ($a)
+
+textSplices :: [(Text, a -> Text)] -> [(Text, a -> Builder)]
+textSplices = mapSnd textSplice
+
+textSplice :: (a -> Text) -> a -> Builder
+textSplice f = fromByteString . T.encodeUtf8 . f
+
+nodeSplices :: [(Text, a -> [X.Node])] -> [(Text, a -> Builder)]
+nodeSplices = mapSnd nodeSplice
+
+nodeSplice :: (a -> [X.Node]) -> a -> Builder
+nodeSplice f = X.renderHtmlFragment X.UTF8 . f
+
+pureSplices :: Monad m => [(d, a -> Builder)] -> [(d, Promise a -> Splice m)]
+pureSplices = mapSnd pureSplice
+
+pureSplice :: Monad m => (a -> Builder) -> Promise a -> Splice m
+pureSplice f p = do
+    return $ yieldRuntime $ do
+        a <- getPromise p
+        return $ f a
+
+mapInputPromise :: Monad m
+                => (a -> b)
+                -> (Promise b -> Splice m)
+                -> Promise a -> Splice m
+mapInputPromise f g p1 = do
+    p2 <- newEmptyPromise
+    let action = yieldRuntimeEffect $ do
+        a <- getPromise p1
+        putPromise p2 (f a)
+    res <- g p2
+    return $ action `mappend` res
+
+
+------------------------------------------------------------------------------
+-- | Allows you to use deferred Promises in a compiled splice.  It takes care
+-- of the boilerplate of creating and storing data in a promise to be used at
+-- load time when compiled splices are processed.  This function is similar to
+-- mapPromises but runs on a single value instead of a list.
+defer :: Monad n
+      => (Promise a -> Splice n)
+      -> RuntimeSplice n a
+      -> Splice n
+defer f getItem = do
+    promise <- newEmptyPromise
+    chunks <- f promise
+    return $ yieldRuntime $ do
+        item <- getItem
+        putPromise promise item
+        codeGen chunks
+
+
+------------------------------------------------------------------------------
+-- | Takes a promise function and a runtime action returning a list of items
+-- that fit in the promise and returns a Splice that executes the promise
+-- function for each item and concatenates the results.
+deferMany :: Monad n
+          => (Promise a -> Splice n)
+          -> RuntimeSplice n [a]
+          -> Splice n
+deferMany f getItems = do
+    promise <- newEmptyPromise
+    chunks <- f promise
+    return $ yieldRuntime $ do
+        items <- getItems
+        res <- forM items $ \item -> do
+            putPromise promise item
+            codeGen chunks
+        return $ mconcat res
+
+
+withSplices :: Monad n
+            => Splice n
+            -> [(Text, Promise a -> Splice n)]
+            -> n a
+            -> Splice n
+withSplices splice splices runtimeAction = do
+    p <- newEmptyPromise
+    let splices' = mapSnd ($p) splices
+    chunks <- withLocalSplices splices' [] splice
+    let fillPromise = yieldRuntimeEffect $ putPromise p =<< lift runtimeAction
+    return $ fillPromise `mappend` chunks
+
+
+------------------------------------------------------------------------------
+-- | Gets a list of items at runtime, then for each item it runs the splice
+-- with the list of splices bound.  There is no pure variant of this function
+-- because the desired behavior can only be achieved as a function of a
+-- Promise.
+manyWithSplices :: Monad n
+                => Splice n
+                -- ^ Splice to run for each of the items in the runtime list.
+                -- You'll frequently use 'runChildren' here.
+                -> [(Text, Promise a -> Splice n)]
+                -- ^ List of splices to bind
+                -> n [a]
+                -- ^ Runtime action returning a list of items to render.
+                -> Splice n
+manyWithSplices splice splices runtimeAction = do
+    p <- newEmptyPromise
+    let splices' = mapSnd ($p) splices
+    chunks <- withLocalSplices splices' [] splice
+    return $ yieldRuntime $ do
+        items <- lift runtimeAction
+        res <- forM items $ \item -> putPromise p item >> codeGen chunks
+        return $ mconcat res
+
+
+withPureSplices :: Monad n
+                => Splice n
+                -> [(Text, a -> Builder)]
+                -> n a
+                -> Splice n
+withPureSplices splice splices action = do
+    let fieldSplice g = return $ yieldRuntime $ liftM g $ lift action
+    let splices' = map (second fieldSplice) splices
+    withLocalSplices splices' [] splice
 
 
diff --git a/src/Heist/Interpreted.hs b/src/Heist/Interpreted.hs
--- a/src/Heist/Interpreted.hs
+++ b/src/Heist/Interpreted.hs
@@ -78,5 +78,5 @@
   ) where
 
 import Heist.Interpreted.Internal
-import Heist.Common (mapSplices)
+import Heist.Common (mapSplices, bindAttributeSplices)
 
diff --git a/src/Heist/Interpreted/Internal.hs b/src/Heist/Interpreted/Internal.hs
--- a/src/Heist/Interpreted/Internal.hs
+++ b/src/Heist/Interpreted/Internal.hs
@@ -10,11 +10,12 @@
 import           Blaze.ByteString.Builder
 import           Control.Arrow hiding (loop)
 import           Control.Monad
-import           Control.Monad.Trans
+import           Control.Monad.State.Strict
 import qualified Data.Attoparsec.Text as AP
 import           Data.ByteString (ByteString)
 import           Data.List
 import qualified Data.HashMap.Strict as Map
+import qualified Data.HeterogeneousEnvironment   as HE
 import           Data.Maybe
 import           Data.Monoid
 import qualified Data.Text as T
@@ -62,17 +63,8 @@
 
 
 ------------------------------------------------------------------------------
--- | Binds a set of new splice declarations within a 'HeistState'.
-bindAttributeSplices :: [(Text, AttrSplice n)] -- ^ splices to bind
-                     -> HeistState n           -- ^ start state
-                     -> HeistState n
-bindAttributeSplices ss hs =
-    hs { _attrSpliceMap = Map.union (Map.fromList ss) (_attrSpliceMap hs) }
-
-
-------------------------------------------------------------------------------
 -- | Converts 'Text' to a splice returning a single 'TextNode'.
-textSplice :: Monad n => Text -> Splice n
+textSplice :: Monad m => Text -> HeistT n m Template
 textSplice t = return [X.TextNode t]
 
 
@@ -211,7 +203,8 @@
 runAttrSplice :: (Monad n) => (Text, Text) -> HeistT n n [(Text, Text)]
 runAttrSplice a@(k,v) = do
     splice <- getsHS (Map.lookup k . _attrSpliceMap)
-    maybe (liftM (:[]) $ attSubst a) (lift . ($v)) splice
+    maybe (liftM (:[]) $ attSubst a)
+          (lift . flip evalStateT HE.empty . unRT . ($v)) splice
 
 
 ------------------------------------------------------------------------------
diff --git a/src/Heist/Splices.hs b/src/Heist/Splices.hs
--- a/src/Heist/Splices.hs
+++ b/src/Heist/Splices.hs
@@ -1,5 +1,7 @@
 module Heist.Splices
-  ( module Heist.Splices.Apply
+  ( ifISplice
+  , ifCSplice
+  , module Heist.Splices.Apply
   , module Heist.Splices.Bind
   , module Heist.Splices.Cache
   , module Heist.Splices.Html
@@ -7,10 +9,40 @@
   , module Heist.Splices.Markdown
   ) where
 
-import Heist.Splices.Apply
-import Heist.Splices.Bind
-import Heist.Splices.Cache
-import Heist.Splices.Html
-import Heist.Splices.Ignore
-import Heist.Splices.Markdown
+import           Data.Monoid
+import qualified Heist.Compiled as C
+import qualified Heist.Interpreted as I
+import           Heist.Splices.Apply
+import           Heist.Splices.Bind
+import           Heist.Splices.Cache
+import           Heist.Splices.Html
+import           Heist.Splices.Ignore
+import           Heist.Splices.Markdown
+
+------------------------------------------------------------------------------
+-- | Run the splice contents if given condition is True, make splice disappear
+-- if not.
+ifISplice :: Monad m => Bool -> I.Splice m
+ifISplice cond =
+    case cond of
+      False -> return []
+      True -> I.runChildren
+
+
+------------------------------------------------------------------------------
+-- | Function for constructing if splices that use a runtime predicate
+-- function to determine whether the node's children should be rendered.
+ifCSplice :: Monad m
+          => (t -> Bool)
+          -> C.Promise t
+          -> C.Splice m
+ifCSplice predicate prom = do
+    chunks <- C.runChildren
+    return $ C.yieldRuntime $ do
+        a <- C.getPromise prom
+        if predicate a
+          then
+            C.codeGen chunks
+          else
+            return mempty
 
diff --git a/src/Heist/Splices/Cache.hs b/src/Heist/Splices/Cache.hs
--- a/src/Heist/Splices/Cache.hs
+++ b/src/Heist/Splices/Cache.hs
@@ -136,7 +136,7 @@
     ref <- liftIO $ newIORef Nothing
     liftIO $ addCompiledRef ref cts
     let reload curTime = do
-            builder <- C.codeGen $! C.consolidate compiled
+            builder <- C.codeGen compiled
             let out = fromByteString $! toByteString $! builder
             liftIO $ writeIORef ref (Just (curTime, out))
             return $! out
diff --git a/src/Heist/Types.hs b/src/Heist/Types.hs
--- a/src/Heist/Types.hs
+++ b/src/Heist/Types.hs
@@ -124,7 +124,7 @@
 -- | Type alias for attribute splices.  The function parameter is the value of
 -- the bound attribute splice.  The return value is a list of attribute
 -- key/value pairs that get substituted in the place of the bound attribute.
-type AttrSplice m = Text -> m [(Text, Text)]
+type AttrSplice m = Text -> RuntimeSplice m [(Text, Text)]
 
 
 ------------------------------------------------------------------------------
@@ -212,9 +212,15 @@
 
 
 ------------------------------------------------------------------------------
--- | Gets the names of all the splices defined in a HeistState.
+-- | Gets the names of all the interpreted splices defined in a HeistState.
 spliceNames :: HeistState m -> [Text]
 spliceNames ts = H.keys $ _spliceMap ts
+
+
+------------------------------------------------------------------------------
+-- | Gets the names of all the compiled splices defined in a HeistState.
+compiledSpliceNames :: HeistState m -> [Text]
+compiledSpliceNames ts = H.keys $ _compiledSpliceMap ts
 
 
 ------------------------------------------------------------------------------
diff --git a/test/suite/Heist/Tests.hs b/test/suite/Heist/Tests.hs
--- a/test/suite/Heist/Tests.hs
+++ b/test/suite/Heist/Tests.hs
@@ -58,7 +58,7 @@
 
 attrSpliceTest :: IO ()
 attrSpliceTest = do
-    ehs <- loadT "templates" [] [] [] [("autocheck", autocheckedSplice)]
+    ehs <- loadT "templates" [] [] [] [("autocheck", lift . autocheckedSplice)]
     let hs = either (error . show) id ehs
         runtime = fromJust $ C.renderTemplate hs "attr_splice"
 
diff --git a/test/suite/Heist/Tutorial/CompiledSplices.lhs b/test/suite/Heist/Tutorial/CompiledSplices.lhs
--- a/test/suite/Heist/Tutorial/CompiledSplices.lhs
+++ b/test/suite/Heist/Tutorial/CompiledSplices.lhs
@@ -149,12 +149,12 @@
 >     ]
 > 
 > peopleSplice :: (Monad n)
->              => n [Person]
+>              => RuntimeSplice n [Person]
 >              -> C.Splice n
 > peopleSplice getPeople = C.mapPromises personSplice getPeople
 > 
 > allPeopleSplice :: C.Splice (StateT [Person] IO)
-> allPeopleSplice = peopleSplice get
+> allPeopleSplice = peopleSplice (lift get)
 > 
 > personListTest :: FilePath
 >                -> IO ByteString
