diff --git a/glabrous.cabal b/glabrous.cabal
--- a/glabrous.cabal
+++ b/glabrous.cabal
@@ -1,5 +1,5 @@
 name:                glabrous
-version:             0.4.0
+version:             1.0.0
 synopsis:            A template DSL library
 description:         A minimalistic, Mustache-like syntax, truly logic-less,
                      pure Text template DSL library
@@ -45,7 +45,7 @@
                      , directory > 1.2 && < 1.4
                      , either >= 4.4.1 && < 5.1
                      , glabrous
-                     , hspec >= 2.1.10 && < 2.6
+                     , hspec >= 2.1.10 && < 2.7
                      , text >= 1.2.1 && < 1.3
                      , unordered-containers == 0.2.*
   default-language:    Haskell2010
diff --git a/src/Text/Glabrous.hs b/src/Text/Glabrous.hs
--- a/src/Text/Glabrous.hs
+++ b/src/Text/Glabrous.hs
@@ -1,6 +1,7 @@
 {-# LANGUAGE BangPatterns      #-}
 {-# LANGUAGE OverloadedStrings #-}
 {-# LANGUAGE RecordWildCards   #-}
+{-# LANGUAGE TupleSections     #-}
 
 -- | A minimalistic Mustache-like syntax, truly logic-less,
 -- pure 'T.Text' template library
@@ -14,7 +15,6 @@
 
   -- * 'Template'
     Template (..)
-  , Tag
 
   -- ** Get a 'Template'
   , fromText
@@ -29,6 +29,7 @@
   , compress
   , writeTemplateFile
   , insert
+  , insertMany
 
   -- * 'Context'
   , Context (..)
@@ -56,22 +57,22 @@
   , process
   , processWithDefault
   , partialProcess
-  , G.Result (..)
+  , Result (..)
   , partialProcess'
 
   ) where
 
 import           Control.Monad            (guard)
-import           Data.Aeson
+import           Data.Aeson               hiding (Result)
 import           Data.Aeson.Encode.Pretty (encodePretty)
 import qualified Data.ByteString.Lazy     as L
 import qualified Data.HashMap.Strict      as H
-import           Data.List                (uncons)
+import           Data.List                (intersect,uncons)
 import qualified Data.Text                as T
 import qualified Data.Text.IO             as I
 
 import           Text.Glabrous.Internal
-import           Text.Glabrous.Types      as G
+import           Text.Glabrous.Types
 
 -- | Optimize a 'Template' content after (many) 'partialProcess'(') rewriting(s).
 compress :: Template -> Template
@@ -138,11 +139,11 @@
 -- >λ>fromTagsList ["tag","etc."]
 -- >Context {variables = fromList [("etc.",""),("tag","")]}
 fromTagsList :: [T.Text] -> Context
-fromTagsList ts = fromList $ (\t -> (t,T.empty)) <$> ts
+fromTagsList ts = fromList $ (,T.empty) <$> ts
 
 -- | Build an unset ad hoc 'Context' from the given 'Template'.
 fromTemplate :: Template -> Context
-fromTemplate t = setVariables ((\e -> (e,T.empty)) <$> tagsOf t) initContext
+fromTemplate t = setVariables ((\(Tag e) -> (e,T.empty)) <$> tagsOf t) initContext
 
 -- | Get a 'Context' from a JSON file.
 readContextFile :: FilePath -> IO (Maybe Context)
@@ -216,21 +217,45 @@
 writeTemplateFile f t = I.writeFile f (toText t)
 
 -- | get 'Just' a new 'Template' by inserting a 'Template'
--- into another one by replacing the 'Tag' named, or 'Nothing'.
+-- into another one by replacing the 'Tag', or 'Nothing'.
+--
+-- >λ>insert t0 (Tag "template1") t1
 insert :: Template       -- ^ The Template to insert in
-       -> T.Text         -- ^ The Tag name to be replaced
+       -> Token          -- ^ The Tag to be replaced
        -> Template       -- ^ The Template to be inserted
        -> Maybe Template -- ^ Just the new Template, or Nothing
-insert te tn te' = do
-  guard (Tag tn `elem` content te)
+insert _ (Literal _) _ = Nothing
+insert te t te' = do
+  guard (t `elem` content te)
   return Template { content = foldl trans [] (content te) }
   where
-    trans o t@(Tag tn') =
-      if tn' == tn
+    trans o t'@(Tag _) =
+      if t' == t
         then o ++ content te'
-        else o ++ [t]
+        else o ++ [t']
     trans o l = o ++ [l]
 
+-- | get 'Just' a new 'Template' by inserting many 'Template's,
+-- if there is at least one tag correspondence, or 'Nothing'.
+--
+-- >λ>insertMany t0 [(Tag "template1",t1),(Tag "template2",t2)]
+insertMany :: Template -> [(Token,Template)] -> Maybe Template
+insertMany te ttps = do
+  guard (tagsOf te `intersect` (fst <$> ttps) /= mempty)
+  return Template { content = foldl trans [] (content te) }
+  where
+    trans o li@(Literal _) = o ++ [li]
+    trans o ta@(Tag _) =
+      case lookupTemplate ta ttps of
+        Nothing  -> o ++ [ta]
+        Just te' -> o ++ content te'
+    lookupTemplate (Literal _) _ = Nothing
+    lookupTemplate _ []          = Nothing
+    lookupTemplate t (p:ps) =
+      if fst p == t
+        then Just (snd p)
+        else lookupTemplate t ps
+
 -- | Output the content of the given 'Template'
 -- as it is, with its 'Tag's, if they exist.
 toText :: Template -> T.Text
@@ -250,12 +275,8 @@
     trans o (Tag _) = o
 
 -- | Get the list of 'Tag's in the given 'Template'.
-tagsOf :: Template -> [Tag]
-tagsOf Template{..} =
-  (\(Tag k) -> k) <$> filter isTag content
-  where
-    isTag (Tag _) = True
-    isTag _       = False
+tagsOf :: Template -> [Token]
+tagsOf Template{..} = filter isTag content
 
 tagsRename :: [(T.Text,T.Text)] -> Template -> Template
 tagsRename ts Template{..} =
@@ -307,11 +328,11 @@
 --
 -- >λ>partialProcess' template context
 -- >Partial {template = Template {content = [Literal "Some ",Tag "tags",Literal " are unused in this ",Tag "text",Literal "."]}, context = Context {variables = fromList [("text",""),("tags","")]}}
-partialProcess' :: Template -> Context -> G.Result
+partialProcess' :: Template -> Context -> Result
 partialProcess' t c@Context{..} =
-  case foldl trans ([],[]) (content t) of
+  case foldl trans (mempty,mempty) (content t) of
     (f,[]) -> Final (toTextWithContext (const T.empty) c f)
-    (p,p') -> G.Partial Template { content = p } (fromTagsList p')
+    (p,p') -> Partial Template { content = p } (fromTagsList p')
   where
     trans (!c',!ts) t' =
       case t' of
diff --git a/src/Text/Glabrous/Internal.hs b/src/Text/Glabrous/Internal.hs
--- a/src/Text/Glabrous/Internal.hs
+++ b/src/Text/Glabrous/Internal.hs
@@ -9,11 +9,11 @@
 import           Data.Maybe           (fromMaybe)
 import qualified Data.Text            as T
 
-import           Text.Glabrous.Types  as G
+import           Text.Glabrous.Types
 
 toTextWithContext :: (T.Text -> T.Text) -> Context -> [Token] -> T.Text
 toTextWithContext tagDefault Context{..} ts =
-  T.concat $ trans <$> ts
+  T.concat (trans <$> ts)
   where
     trans (Tag k)     = fromMaybe (tagDefault k) (H.lookup k variables)
     trans (Literal c) = c
@@ -33,13 +33,17 @@
 isLiteral (Literal _) = True
 isLiteral _           = False
 
+isTag :: Token -> Bool
+isTag (Tag _) = True
+isTag _       = False
+
 tokens :: Parser [Token]
 tokens =
   many' token
   where
     token = literal <|> tag <|> leftover
     leftover = do
-      c <- takeWhile1 $ not . content
+      c <- takeWhile1 (not . content)
       return (Literal c)
     literal = do
       c <- takeWhile1 content
diff --git a/src/Text/Glabrous/Types.hs b/src/Text/Glabrous/Types.hs
--- a/src/Text/Glabrous/Types.hs
+++ b/src/Text/Glabrous/Types.hs
@@ -18,16 +18,16 @@
 
 instance Serialize Token
 
-data Template =
+newtype Template =
   Template
-    { content :: ![Token] }
+    { content :: [Token] }
     deriving (Eq, Show, Generic)
 
 instance Serialize Template
 
-data Context =
+newtype Context =
   Context
-    { variables :: !(H.HashMap T.Text T.Text) }
+    { variables :: H.HashMap T.Text T.Text }
     deriving (Eq, Show)
 
 instance ToJSON Context where
@@ -38,8 +38,6 @@
   parseJSON (Object o) = return
     Context { variables = H.fromList ((\(k,String v) -> (k,v)) <$> H.toList o) }
   parseJSON _          = fail "expected an object"
-
-type Tag = T.Text
 
 data Result
   = Final !T.Text
diff --git a/tests/hspec.hs b/tests/hspec.hs
--- a/tests/hspec.hs
+++ b/tests/hspec.hs
@@ -49,7 +49,7 @@
 
     describe "tagsOf" $
         it "returns the list of tags in a template" $
-            tagsOf <$> fromRight' <$> readTemplateFile templateFile `shouldReturn` ["ipsum","tortor","lectus","vehicula","bibendum","condimentum","tellus","faucibus","cursus","commodo","vestibulum","lobortis","fermentum","maximus","venenatis","sagittis","vitae","rhoncus"]
+            tagsOf <$> fromRight' <$> readTemplateFile templateFile `shouldReturn` [Tag "ipsum",Tag "tortor",Tag "lectus",Tag "vehicula",Tag "bibendum",Tag "condimentum",Tag "tellus",Tag "faucibus",Tag "cursus",Tag "commodo",Tag "vestibulum",Tag "lobortis",Tag "fermentum",Tag "maximus",Tag "venenatis",Tag "sagittis",Tag "vitae",Tag "rhoncus"]
 
     describe "toText" $
         it "returns the template as it is" $
