diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,9 @@
 # Mustache library changelog
 
+## v2.2.2
+
+- Added a function to catch a substitution result
+
 ## v2.2.1
 
 - Quickfix for an issue with resolving in context
diff --git a/mustache.cabal b/mustache.cabal
--- a/mustache.cabal
+++ b/mustache.cabal
@@ -1,5 +1,5 @@
 name:                mustache
-version:             2.2.1
+version:             2.2.2
 synopsis:            A mustache template parser library.
 description:
   Allows parsing and rendering template files with mustache markup. See the
diff --git a/src/Text/Mustache/Render.hs b/src/Text/Mustache/Render.hs
--- a/src/Text/Mustache/Render.hs
+++ b/src/Text/Mustache/Render.hs
@@ -19,7 +19,7 @@
   -- * Checked substitution
   , checkedSubstitute, checkedSubstituteValue, SubstitutionError(..)
   -- * Working with Context
-  , Context(..), search, innerSearch, SubM, substituteNode, substituteAST
+  , Context(..), search, innerSearch, SubM, substituteNode, substituteAST, catchSubstitute
   -- * Util
   , toString
   ) where
@@ -100,6 +100,10 @@
 checkedSubstituteValue :: Template -> Value -> ([SubstitutionError], Text)
 checkedSubstituteValue template dataStruct =
   second T.concat $ runSubM (substituteAST (ast template)) (Context mempty dataStruct) (partials template)
+
+-- | Catch the results of running the inner substitution.
+catchSubstitute :: SubM a -> SubM (a, Text)
+catchSubstitute = fmap (second (T.concat . snd)) . SubM . listen . runSubM'
 
 -- | Substitute an entire 'STree' rather than just a single 'Node'
 substituteAST :: STree -> SubM ()
