diff --git a/HSmarty.cabal b/HSmarty.cabal
--- a/HSmarty.cabal
+++ b/HSmarty.cabal
@@ -1,5 +1,5 @@
 name:                HSmarty
-version:             0.4.0
+version:             0.4.1
 synopsis:            Small template engine
 description:         Haskell implementation of a subset of the PHP-Smarty template language
 Homepage:            https://github.com/agrafix/HSmarty
@@ -13,7 +13,9 @@
 build-type:          Simple
 cabal-version:       >=1.10
 data-dir:            data
-data-files:          test.tpl
+data-files:          test.tpl,
+                     testCapture.tpl,
+                     testCapture.txt
 tested-with:         GHC==8.8.4
 
 Library
@@ -42,7 +44,9 @@
 
 Test-Suite TestHSmarty
   hs-source-dirs:    test
-  other-modules:     Text.HSmarty.Parser.SmartyTest, Paths_HSmarty
+  other-modules:     Text.HSmarty.Parser.SmartyTest, 
+                     Text.HSmarty.Render.EngineTest, 
+                     Paths_HSmarty
   Type:              exitcode-stdio-1.0
   Main-Is:           Tests.hs
   Ghc-Options:       -Wall
diff --git a/data/testCapture.tpl b/data/testCapture.tpl
new file mode 100644
--- /dev/null
+++ b/data/testCapture.tpl
@@ -0,0 +1,1 @@
+{capture name='var' assign=var}Hello{/capture}{$var}/{$smarty.capture.var}
diff --git a/data/testCapture.txt b/data/testCapture.txt
new file mode 100644
--- /dev/null
+++ b/data/testCapture.txt
@@ -0,0 +1,1 @@
+Hello/Hello
diff --git a/src/Text/HSmarty/Parser/Smarty.hs b/src/Text/HSmarty/Parser/Smarty.hs
--- a/src/Text/HSmarty/Parser/Smarty.hs
+++ b/src/Text/HSmarty/Parser/Smarty.hs
@@ -22,7 +22,7 @@
 
 pRoot :: Parser [SmartyStmt]
 pRoot =
-    (stripSpace $ many1 pStmt) <* endOfInput
+    stripSpace (many1 pStmt) <* endOfInput
 
 pStmt :: Parser SmartyStmt
 pStmt =
@@ -34,7 +34,7 @@
     SmartyScope <$> pScope <|>
     SmartyFun <$> pFunDef <|>
     braced (char '{') (char '}') (SmartyPrint <$> pExpr <*> many pPrintDirective) <|>
-    SmartyText <$> (takeWhile1 (/='{'))
+    SmartyText <$> takeWhile1 (/='{')
 
 pPrintDirective :: Parser PrintDirective
 pPrintDirective =
@@ -113,8 +113,9 @@
 pCapture :: Parser Capture
 pCapture =
     Capture
-    <$> ((string "{capture name=" *> space_) *> stringP <* char '}')
-    <*> (many pStmt <* pClose "capture")
+    <$> ((string "{capture name=" *> optSpace_) *> stringP)
+    <*> optional (optSpace_ *> string "assign=" *> pName)
+    <*> (optSpace_ *> char '}' *> many pStmt <* pClose "capture")
 
 pFunDef :: Parser FunctionDef
 pFunDef =
diff --git a/src/Text/HSmarty/Parser/Util.hs b/src/Text/HSmarty/Parser/Util.hs
--- a/src/Text/HSmarty/Parser/Util.hs
+++ b/src/Text/HSmarty/Parser/Util.hs
@@ -16,8 +16,8 @@
 
 boolP :: Parser Bool
 boolP =
-    const True <$> string "true" <|>
-    const False <$> string "false"
+    True <$ string "true" <|>
+    False <$ string "false"
 
 stringP :: Parser T.Text
 stringP = (quotedString '"' <|> quotedString '\'') <?> "stringP"
@@ -51,11 +51,11 @@
     where decode c r = r <$ char c
 
 unicodeSeq :: Parser Char
-unicodeSeq = char 'u' *> (intToChar <$> decodeHexUnsafe <$> count 4 hexDigit)
+unicodeSeq = char 'u' *> (intToChar . decodeHexUnsafe <$> count 4 hexDigit)
     where intToChar = toEnum . fromIntegral
 
 decodeHexUnsafe :: String -> Integer
-decodeHexUnsafe hex = (head $ map fst $ readHex hex)
+decodeHexUnsafe hex = head $ map fst $ readHex hex
 
 hexDigitUpper :: Parser Char
 hexDigitUpper = satisfy (inClass "0-9A-F")
diff --git a/src/Text/HSmarty/Render/Engine.hs b/src/Text/HSmarty/Render/Engine.hs
--- a/src/Text/HSmarty/Render/Engine.hs
+++ b/src/Text/HSmarty/Render/Engine.hs
@@ -66,10 +66,28 @@
     = SmartyError { unSmartyError :: T.Text }
       deriving (Show, Eq)
 
+wrapSmartyCapture :: A.Value -> PropMap -> TemplateVar
+wrapSmartyCapture x = TemplateVar (A.Object $ HM.singleton "capture" x)
+
+updateSmartyCapture :: T.Text -> A.Value -> HM.HashMap T.Text TemplateVar -> HM.HashMap T.Text TemplateVar
+updateSmartyCapture key value hm =
+    let updatedVal =
+            case HM.lookup "smarty" hm of
+                Nothing -> wrapSmartyCapture (A.Object $ HM.singleton key value) mempty
+                Just (TemplateVar existingCtx oldProps) -> 
+                    case existingCtx of
+                        A.Object oldContext -> 
+                            wrapSmartyCapture (A.Object $ HM.insert key value oldContext) oldProps
+                        _ -> error "Smarty capture context is always a map!"
+    in HM.insert "smarty" updatedVal hm
+
+rootMap :: HM.HashMap T.Text TemplateVar
+rootMap = HM.singleton "smarty" (wrapSmartyCapture (A.Object mempty) mempty)
+
 mkEnv :: ParamMap -> SmartyCtx -> Env
 mkEnv pm ctx =
     Env
-    { e_var = HM.map (\init' -> TemplateVar init' HM.empty) pm
+    { e_var = rootMap <> HM.map (\init' -> TemplateVar init' HM.empty) pm
     , e_fun = HM.empty
     , e_ctx = ctx
     }
@@ -167,8 +185,14 @@
        pure (env { e_fun = fun }, T.empty)
 evalStmt env (SmartyCapture cap) =
     do (_, body) <- seqStmts env (c_stmts cap)
-       let eVars =
-               HM.insert (c_name cap) (TemplateVar (A.String body) mempty) (e_var env)
+       let varBody = TemplateVar (A.String body) mempty
+           capture =
+               updateSmartyCapture (c_name cap) (A.String body)
+           assignment = 
+             case c_assign cap of
+                 Nothing -> mempty
+                 Just x -> HM.insert x varBody
+           eVars = capture . assignment $ e_var env
        pure (env { e_var = eVars }, T.empty)
 evalStmt env (SmartyLet l) =
     do r <- evalExpr env (l_expr l)
diff --git a/src/Text/HSmarty/Types.hs b/src/Text/HSmarty/Types.hs
--- a/src/Text/HSmarty/Types.hs
+++ b/src/Text/HSmarty/Types.hs
@@ -78,6 +78,7 @@
 data Capture
     = Capture
     { c_name :: T.Text
+    , c_assign :: Maybe T.Text
     , c_stmts :: [SmartyStmt]
     } deriving (Show, Eq)
 
diff --git a/test/Tests.hs b/test/Tests.hs
--- a/test/Tests.hs
+++ b/test/Tests.hs
@@ -3,6 +3,7 @@
 
 import Test.Framework
 import {-@ HTF_TESTS @-} Text.HSmarty.Parser.SmartyTest
+import {-@ HTF_TESTS @-} Text.HSmarty.Render.EngineTest
 
 main :: IO ()
 main = htfMain htf_importedTests
diff --git a/test/Text/HSmarty/Parser/SmartyTest.hs b/test/Text/HSmarty/Parser/SmartyTest.hs
--- a/test/Text/HSmarty/Parser/SmartyTest.hs
+++ b/test/Text/HSmarty/Parser/SmartyTest.hs
@@ -48,6 +48,14 @@
     do parserTest pVar "$hallo.sub@prop" (Variable "hallo" ["sub"] Nothing (Just "prop"))
        parserTest pVar "$hallo.foo_bar" (Variable "hallo" ["foo_bar"] Nothing Nothing)
 
+test_capture :: IO ()
+test_capture =
+    do parserTest pCapture "{capture name='foo'}Bye{/capture}" expect1
+       parserTest pCapture "{capture name='foo' assign=bar}Bye{/capture}" expect2
+    where
+      expect1 = Capture "foo" Nothing [SmartyText "Bye"]
+      expect2 = Capture "foo" (Just "bar") [SmartyText "Bye"]
+
 test_if :: IO ()
 test_if =
     do parserTest pIf "{if $var@last}Bye{/if}" expect
diff --git a/test/Text/HSmarty/Render/EngineTest.hs b/test/Text/HSmarty/Render/EngineTest.hs
new file mode 100644
--- /dev/null
+++ b/test/Text/HSmarty/Render/EngineTest.hs
@@ -0,0 +1,28 @@
+{-# OPTIONS_GHC -F -pgmF htfpp #-}
+{-# LANGUAGE OverloadedStrings #-}
+{-# LANGUAGE RankNTypes #-}
+module Text.HSmarty.Render.EngineTest where
+
+import Paths_HSmarty
+import Test.Framework
+import Text.HSmarty
+import qualified Data.Text as T
+import qualified Data.Text.IO as T
+
+readDataFile :: String -> IO T.Text
+readDataFile name =
+    do fp <- getDataFileName name
+       T.readFile fp
+
+engineTest :: FilePath -> FilePath -> IO ()
+engineTest inputFile outputFile =
+    do testInputFile <- getDataFileName inputFile
+       expectedOutput <- readDataFile outputFile
+       ctx <- prepareTemplate testInputFile
+       case applyTemplate testInputFile ctx mempty of
+           Left errMsg -> fail (show errMsg)
+           Right ok -> assertEqual ok expectedOutput
+
+test_capture :: IO ()
+test_capture =
+    engineTest "testCapture.tpl" "testCapture.txt"
