This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "heist".

The branch, master has been updated
       via  f8b93a404136e7678e3d420897d0515c194ac277 (commit)
       via  05cb43fdd4c5c614f97331aed194e594a01d62b5 (commit)
       via  fa50ec658cb338ffdacbdc287ff7093ee99134c1 (commit)
       via  f9453bd4ae6812bff033dca2bd5d840b54700918 (commit)
       via  d40e4e66b27acf7b20d3e6f620bf187767f8d319 (commit)
       via  3295bedc34345485a5007cdadc1093e27bf0be13 (commit)
       via  a2c92a7540f3c3c026d52af945ba07aef4664797 (commit)
       via  f6891e492f76640685976202d143817586c88cba (commit)
       via  a81f153aba6ed5e74224e47884d990e42bb84011 (commit)
       via  9bf32d7fbd14f9deae0b9166b26ca2f82d86dc0a (commit)
      from  78f7b5039b12a73ef30f0aa15e3ac9b8be0052db (commit)


Summary of changes:
 heist.cabal                                   |   10 +-
 src/Text/Templating/Heist.hs                  |   31 ++--
 src/Text/Templating/Heist/Constants.hs        |  268 ----------------------
 src/Text/Templating/Heist/Internal.hs         |  299 ++++++++++++-------------
 src/Text/Templating/Heist/Splices/Apply.hs    |   24 +-
 src/Text/Templating/Heist/Splices/Bind.hs     |   12 +-
 src/Text/Templating/Heist/Splices/Ignore.hs   |    4 +-
 src/Text/Templating/Heist/Splices/Markdown.hs |   34 ++--
 src/Text/Templating/Heist/Splices/Static.hs   |   24 +-
 src/Text/Templating/Heist/Types.hs            |   38 +--
 test/heist-testsuite.cabal                    |    5 +-
 test/suite/Text/Templating/Heist/Tests.hs     |  147 +++++++------
 12 files changed, 315 insertions(+), 581 deletions(-)
 delete mode 100644 src/Text/Templating/Heist/Constants.hs

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit f8b93a404136e7678e3d420897d0515c194ac277
Author: Chris Smith <[email protected]>
Date:   Tue Jan 11 09:38:06 2011 -0700

    Update documentation on MIME types

diff --git a/src/Text/Templating/Heist/Internal.hs 
b/src/Text/Templating/Heist/Internal.hs
index c570109..c3a59f0 100644
--- a/src/Text/Templating/Heist/Internal.hs
+++ b/src/Text/Templating/Heist/Internal.hs
@@ -473,7 +473,11 @@ mimeType d = case d of
 
 
 ------------------------------------------------------------------------------
--- | Renders a template from the specified TemplateState to a 'Builder'.
+-- | Renders a template from the specified TemplateState to a 'Builder'.  The
+-- MIME type returned is based on the detected character encoding, and whether
+-- the root template was an HTML or XML format template.  It will always be
+-- @text/html@ or @text/xml@.  If a more specific MIME type is needed for a
+-- particular XML application, it must be provided by the application.
 renderTemplate :: Monad m
                => TemplateState m
                -> ByteString
commit 05cb43fdd4c5c614f97331aed194e594a01d62b5
Author: Chris Smith <[email protected]>
Date:   Tue Jan 11 09:25:48 2011 -0700

    Export type I forgot

diff --git a/src/Text/Templating/Heist.hs b/src/Text/Templating/Heist.hs
index 6cd74fc..bfaf0f3 100644
--- a/src/Text/Templating/Heist.hs
+++ b/src/Text/Templating/Heist.hs
@@ -69,6 +69,7 @@ module Text.Templating.Heist
   (
     -- * Types
     Template
+  , MIMEType
   , Splice
   , TemplateMonad
   , TemplateState
commit fa50ec658cb338ffdacbdc287ff7093ee99134c1
Author: Chris Smith <[email protected]>
Date:   Tue Jan 11 09:23:57 2011 -0700

    Include MIME type in template results

diff --git a/src/Text/Templating/Heist/Internal.hs 
b/src/Text/Templating/Heist/Internal.hs
index d434093..c570109 100644
--- a/src/Text/Templating/Heist/Internal.hs
+++ b/src/Text/Templating/Heist/Internal.hs
@@ -459,15 +459,30 @@ callTemplate name params = do
 
 
 ------------------------------------------------------------------------------
+-- Gives the MIME type for a 'X.Document'
+mimeType :: X.Document -> ByteString
+mimeType d = case d of
+    (X.HtmlDocument e _ _) -> "text/html;charset=" `BC.append` enc e
+    (X.XmlDocument  e _ _) -> "text/xml;charset="  `BC.append` enc e
+  where
+    enc X.UTF8    = "utf-8"
+    -- Should not include byte order designation for UTF-16 since
+    -- rendering will include a byte order mark. (RFC 2781, Sec. 3.3)
+    enc X.UTF16BE = "utf-16"
+    enc X.UTF16LE = "utf-16"
+
+
+------------------------------------------------------------------------------
 -- | Renders a template from the specified TemplateState to a 'Builder'.
 renderTemplate :: Monad m
                => TemplateState m
                -> ByteString
-               -> m (Maybe Builder)
+               -> m (Maybe (Builder, MIMEType))
 renderTemplate ts name = evalTemplateMonad tpl (X.TextNode "") ts
   where tpl = do mt <- evalWithHooksInternal name
-                 case mt of Nothing  -> return Nothing
-                            Just doc -> return $ Just $ X.render doc
+                 case mt of
+                    Nothing  -> return Nothing
+                    Just doc -> return $ Just $ (X.render doc, mimeType doc)
 
 
 ------------------------------------------------------------------------------
@@ -479,7 +494,7 @@ renderWithArgs :: Monad m
                    => [(Text, Text)]
                    -> TemplateState m
                    -> ByteString
-                   -> m (Maybe Builder)
+                   -> m (Maybe (Builder, MIMEType))
 renderWithArgs args ts = renderTemplate (bindStrings args ts)
 
 
diff --git a/src/Text/Templating/Heist/Types.hs 
b/src/Text/Templating/Heist/Types.hs
index db5cc35..b847bbb 100644
--- a/src/Text/Templating/Heist/Types.hs
+++ b/src/Text/Templating/Heist/Types.hs
@@ -45,6 +45,11 @@ type Template = [X.Node]
 
 
 ------------------------------------------------------------------------------
+-- | MIME Type.  The type alias is here to make the API clearer.
+type MIMEType = ByteString
+
+
+------------------------------------------------------------------------------
 -- | Reversed list of directories.  This holds the path to the template
 -- currently being processed.
 type TPath = [ByteString]
diff --git a/test/suite/Text/Templating/Heist/Tests.hs 
b/test/suite/Text/Templating/Heist/Tests.hs
index 5ab54d0..9618f59 100644
--- a/test/suite/Text/Templating/Heist/Tests.hs
+++ b/test/suite/Text/Templating/Heist/Tests.hs
@@ -167,12 +167,12 @@ doctypeTest :: H.Assertion
 doctypeTest = do
     ets <- loadT "templates"
     let ts = either (error "Error loading templates") id ets
-    index <- renderTemplate ts "index"
+    Just (indexDoc, indexMIME) <- renderTemplate ts "index"
     H.assertBool "doctype test index" $ isJust $ X.docType $
-        fromRight $ (X.parseHTML "index") $ toByteString $ fromJust index
-    ioc <- renderTemplate ts "ioc"
+        fromRight $ (X.parseHTML "index") $ toByteString $ indexDoc
+    Just (iocDoc, iocMIME) <- renderTemplate ts "ioc"
     H.assertBool "doctype test ioc" $ isJust $ X.docType $
-        fromRight $ (X.parseHTML "index") $ toByteString $ fromJust ioc
+        fromRight $ (X.parseHTML "index") $ toByteString $ iocDoc
   where fromRight (Right x) = x
         fromRight (Left  s) = error s
 
@@ -187,11 +187,11 @@ attrSubstTest = do
   where
     setTs val = bindSplice "foo" (return [X.TextNode val])
     check ts str = do
-        res <- renderTemplate ts "attrs"
+        Just (resDoc, resMIME) <- renderTemplate ts "attrs"
         H.assertBool ("attr subst " ++ (show str)) $ not $ B.null $
-            snd $ B.breakSubstring str $ toByteString $ fromJust res
+            snd $ B.breakSubstring str $ toByteString $ resDoc
         H.assertBool ("attr subst foo") $ not $ B.null $
-            snd $ B.breakSubstring "$(foo)" $ toByteString $ fromJust res
+            snd $ B.breakSubstring "$(foo)" $ toByteString $ resDoc
 
 
 ------------------------------------------------------------------------------
@@ -203,11 +203,11 @@ bindAttrTest = do
 
   where
     check ts str = do
-        res <- renderTemplate ts "bind-attrs"
+        Just (resDoc, resMIME) <- renderTemplate ts "bind-attrs"
         H.assertBool ("attr subst " ++ (show str)) $ not $ B.null $
-            snd $ B.breakSubstring str $ toByteString $ fromJust res
+            snd $ B.breakSubstring str $ toByteString $ resDoc
         H.assertBool ("attr subst bar") $ B.null $
-            snd $ B.breakSubstring "$(bar)" $ toByteString $ fromJust res
+            snd $ B.breakSubstring "$(bar)" $ toByteString $ resDoc
 
 
 ------------------------------------------------------------------------------
@@ -226,9 +226,9 @@ markdownTest = do
 
   where
     check ts str = do
-        result <- liftM (fmap $ B.filter (/= '\n')) $
-                  liftM (fmap toByteString) $ renderTemplate ts "markdown"
-        H.assertEqual ("Should match " ++ (show str)) str (fromJust result)
+        Just (doc, mime) <- renderTemplate ts "markdown"
+        let result = B.filter (/= '\n') (toByteString doc)
+        H.assertEqual ("Should match " ++ (show str)) str result
 
 
 ------------------------------------------------------------------------------
@@ -359,8 +359,9 @@ processNode elems loc =
 -- template.  (Old convenience code.)
 quickRender :: FilePath -> ByteString -> IO (Maybe ByteString)
 quickRender baseDir name = do
-    ts <- loadTS baseDir
-    fmap (fmap toByteString) (renderTemplate ts name)
+    ts  <- loadTS baseDir
+    res <- renderTemplate ts name
+    return (fmap (toByteString . fst) res)
 
 
 ------------------------------------------------------------------------------
commit f9453bd4ae6812bff033dca2bd5d840b54700918
Author: Chris Smith <[email protected]>
Date:   Tue Jan 11 01:34:45 2011 -0700

    Remove old ByteString functions, and give Builder versions the better names.

diff --git a/src/Text/Templating/Heist.hs b/src/Text/Templating/Heist.hs
index f9f181a..6cd74fc 100644
--- a/src/Text/Templating/Heist.hs
+++ b/src/Text/Templating/Heist.hs
@@ -107,9 +107,7 @@ module Text.Templating.Heist
   , evalTemplate
   , callTemplate
   , renderTemplate
-  , renderTemplateBuilder
   , renderWithArgs
-  , renderWithArgsBuilder
   , bindStrings
   , bindString
 
diff --git a/src/Text/Templating/Heist/Internal.hs 
b/src/Text/Templating/Heist/Internal.hs
index dbc4762..d434093 100644
--- a/src/Text/Templating/Heist/Internal.hs
+++ b/src/Text/Templating/Heist/Internal.hs
@@ -460,24 +460,14 @@ callTemplate name params = do
 
 ------------------------------------------------------------------------------
 -- | Renders a template from the specified TemplateState to a 'Builder'.
-renderTemplateBuilder :: Monad m
-                      => TemplateState m
-                      -> ByteString
-                      -> m (Maybe Builder)
-renderTemplateBuilder ts name = evalTemplateMonad tpl (X.TextNode "") ts
-  where tpl = do mt <- evalWithHooksInternal name
-                 case mt of Nothing  -> return Nothing
-                            Just doc -> return $ Just $ X.render doc
-
-
-------------------------------------------------------------------------------
--- | Renders a template from the specified TemplateState to a 'ByteString'.
 renderTemplate :: Monad m
                => TemplateState m
                -> ByteString
-               -> m (Maybe ByteString)
-renderTemplate ts name =
-    liftM (liftM toByteString) (renderTemplateBuilder ts name)
+               -> m (Maybe Builder)
+renderTemplate ts name = evalTemplateMonad tpl (X.TextNode "") ts
+  where tpl = do mt <- evalWithHooksInternal name
+                 case mt of Nothing  -> return Nothing
+                            Just doc -> return $ Just $ X.render doc
 
 
 ------------------------------------------------------------------------------
@@ -489,24 +479,11 @@ renderWithArgs :: Monad m
                    => [(Text, Text)]
                    -> TemplateState m
                    -> ByteString
-                   -> m (Maybe ByteString)
+                   -> m (Maybe Builder)
 renderWithArgs args ts = renderTemplate (bindStrings args ts)
 
 
 ------------------------------------------------------------------------------
--- | Renders a template with the specified arguments passed to it, and output
--- as a 'Builder'.  This is a convenience function for the common pattern of
--- calling renderTemplateBuilder after using bindString, bindStrings, or
--- bindSplice to set up the arguments to the template.
-renderWithArgsBuilder :: Monad m
-                      => [(Text, Text)]
-                      -> TemplateState m
-                      -> ByteString
-                      -> m (Maybe Builder)
-renderWithArgsBuilder args ts = renderTemplateBuilder (bindStrings args ts)
-
-
-------------------------------------------------------------------------------
 -- Template loading
 ------------------------------------------------------------------------------
 
diff --git a/test/suite/Text/Templating/Heist/Tests.hs 
b/test/suite/Text/Templating/Heist/Tests.hs
index 8a1dace..5ab54d0 100644
--- a/test/suite/Text/Templating/Heist/Tests.hs
+++ b/test/suite/Text/Templating/Heist/Tests.hs
@@ -158,7 +158,7 @@ renderNoNameTest = do
     ets <- loadT "templates"
     either (error "Error loading templates")
            (\ts -> do t <- renderTemplate ts ""
-                      H.assertBool "renderNoName" $ t == Nothing
+                      H.assertBool "renderNoName" $ isNothing t
            ) ets
 
 
@@ -168,11 +168,11 @@ doctypeTest = do
     ets <- loadT "templates"
     let ts = either (error "Error loading templates") id ets
     index <- renderTemplate ts "index"
-    H.assertBool "doctype test index" $ isJust $
-        X.docType $ fromRight $ (X.parseHTML "index") $ fromJust index
+    H.assertBool "doctype test index" $ isJust $ X.docType $
+        fromRight $ (X.parseHTML "index") $ toByteString $ fromJust index
     ioc <- renderTemplate ts "ioc"
-    H.assertBool "doctype test ioc" $ isJust $
-        X.docType $ fromRight $ (X.parseHTML "index") $ fromJust ioc
+    H.assertBool "doctype test ioc" $ isJust $ X.docType $
+        fromRight $ (X.parseHTML "index") $ toByteString $ fromJust ioc
   where fromRight (Right x) = x
         fromRight (Left  s) = error s
 
@@ -188,10 +188,10 @@ attrSubstTest = do
     setTs val = bindSplice "foo" (return [X.TextNode val])
     check ts str = do
         res <- renderTemplate ts "attrs"
-        H.assertBool ("attr subst " ++ (show str)) $
-            not $ B.null $ snd $ B.breakSubstring str $ fromJust res
-        H.assertBool ("attr subst foo") $
-            not $ B.null $ snd $ B.breakSubstring "$(foo)" $ fromJust res
+        H.assertBool ("attr subst " ++ (show str)) $ not $ B.null $
+            snd $ B.breakSubstring str $ toByteString $ fromJust res
+        H.assertBool ("attr subst foo") $ not $ B.null $
+            snd $ B.breakSubstring "$(foo)" $ toByteString $ fromJust res
 
 
 ------------------------------------------------------------------------------
@@ -204,10 +204,10 @@ bindAttrTest = do
   where
     check ts str = do
         res <- renderTemplate ts "bind-attrs"
-        H.assertBool ("attr subst " ++ (show str)) $
-            not $ B.null $ snd $ B.breakSubstring str $ fromJust res
-        H.assertBool ("attr subst bar") $
-            B.null $ snd $ B.breakSubstring "$(bar)" $ fromJust res
+        H.assertBool ("attr subst " ++ (show str)) $ not $ B.null $
+            snd $ B.breakSubstring str $ toByteString $ fromJust res
+        H.assertBool ("attr subst bar") $ B.null $
+            snd $ B.breakSubstring "$(bar)" $ toByteString $ fromJust res
 
 
 ------------------------------------------------------------------------------
@@ -227,7 +227,7 @@ markdownTest = do
   where
     check ts str = do
         result <- liftM (fmap $ B.filter (/= '\n')) $
-                  renderTemplate ts "markdown"
+                  liftM (fmap toByteString) $ renderTemplate ts "markdown"
         H.assertEqual ("Should match " ++ (show str)) str (fromJust result)
 
 
@@ -360,7 +360,7 @@ processNode elems loc =
 quickRender :: FilePath -> ByteString -> IO (Maybe ByteString)
 quickRender baseDir name = do
     ts <- loadTS baseDir
-    renderTemplate ts name
+    fmap (fmap toByteString) (renderTemplate ts name)
 
 
 ------------------------------------------------------------------------------
commit d40e4e66b27acf7b20d3e6f620bf187767f8d319
Author: Chris Smith <[email protected]>
Date:   Tue Jan 11 01:02:51 2011 -0700

    Expose Builder versions of rendering functions.
    Also fix rendering to choose the format/encoding of the root document.

diff --git a/src/Text/Templating/Heist.hs b/src/Text/Templating/Heist.hs
index 6cd74fc..f9f181a 100644
--- a/src/Text/Templating/Heist.hs
+++ b/src/Text/Templating/Heist.hs
@@ -107,7 +107,9 @@ module Text.Templating.Heist
   , evalTemplate
   , callTemplate
   , renderTemplate
+  , renderTemplateBuilder
   , renderWithArgs
+  , renderWithArgsBuilder
   , bindStrings
   , bindString
 
diff --git a/src/Text/Templating/Heist/Internal.hs 
b/src/Text/Templating/Heist/Internal.hs
index 55739e6..dbc4762 100644
--- a/src/Text/Templating/Heist/Internal.hs
+++ b/src/Text/Templating/Heist/Internal.hs
@@ -210,7 +210,7 @@ addXMLTemplate :: Monad m =>
                -> TemplateState m
                -> TemplateState m
 addXMLTemplate n t st = insertTemplate (splitTemplatePath n)
-                                    (X.XmlDocument X.UTF8 Nothing t) st
+                                       (X.XmlDocument X.UTF8 Nothing t) st
 
 
 ------------------------------------------------------------------------------
@@ -389,20 +389,40 @@ evalTemplate name = lookupAndRun name
 
 
 ------------------------------------------------------------------------------
+-- | Sets the document type of a 'X.Document' based on the 'TemplateMonad'
+-- value.
+fixDocType :: Monad m => X.Document -> TemplateMonad m X.Document
+fixDocType d = do
+    dts <- getsTS _doctypes
+    return $ d { X.docType = listToMaybe dts }
+
+
+------------------------------------------------------------------------------
+-- | Same as evalWithHooks, but returns the entire 'X.Document' rather than
+-- just the nodes.  This is the right thing to do if we are starting at the
+-- top level.
+evalWithHooksInternal :: Monad m
+                      => ByteString
+                      -> TemplateMonad m (Maybe X.Document)
+evalWithHooksInternal name = lookupAndRun name $ \(t,ctx) -> do
+    addDoctype $ maybeToList $ X.docType t
+    ts <- getTS
+    nodes <- lift $ _preRunHook ts $ X.docContent t
+    putTS (ts {_curContext = ctx})
+    res <- runNodeList nodes
+    restoreTS ts
+    newNodes <- lift (_postRunHook ts res)
+    newDoc   <- fixDocType $ t { X.docContent = newNodes }
+    return (Just newDoc)
+
+
+------------------------------------------------------------------------------
 -- | Looks up a template name evaluates it by calling runNodeList.  This also
 -- executes pre- and post-run hooks and adds the doctype.
 evalWithHooks :: Monad m
             => ByteString
             -> TemplateMonad m (Maybe Template)
-evalWithHooks name = lookupAndRun name
-    (\(t,ctx) -> do
-        addDoctype $ maybeToList $ X.docType t
-        ts <- getTS
-        nodes <- lift $ _preRunHook ts $ X.docContent t
-        putTS (ts {_curContext = ctx})
-        res <- runNodeList nodes
-        restoreTS ts
-        return . Just =<< lift (_postRunHook ts res))
+evalWithHooks name = liftM (liftM X.docContent) (evalWithHooksInternal name)
 
 
 ------------------------------------------------------------------------------
@@ -439,33 +459,25 @@ callTemplate name params = do
 
 
 ------------------------------------------------------------------------------
--- | Converts a Template to a X.Document.  This can only be done inside
--- TemplateMonad where the doctype is available.
-toDocument :: Monad m => Template -> TemplateMonad m X.Document
-toDocument t = do
-    dts <- getsTS _doctypes
-    return $ X.HtmlDocument X.UTF8 (listToMaybe dts) t
+-- | Renders a template from the specified TemplateState to a 'Builder'.
+renderTemplateBuilder :: Monad m
+                      => TemplateState m
+                      -> ByteString
+                      -> m (Maybe Builder)
+renderTemplateBuilder ts name = evalTemplateMonad tpl (X.TextNode "") ts
+  where tpl = do mt <- evalWithHooksInternal name
+                 case mt of Nothing  -> return Nothing
+                            Just doc -> return $ Just $ X.render doc
 
 
 ------------------------------------------------------------------------------
--- | Renders a document by prepending the appropriate doctype.
-renderDocument :: Monad m => X.Document -> TemplateMonad m ByteString
-renderDocument d = return (toByteString (X.render d))
-
-
-------------------------------------------------------------------------------
--- | Renders a template from the specified TemplateState.
+-- | Renders a template from the specified TemplateState to a 'ByteString'.
 renderTemplate :: Monad m
                => TemplateState m
                -> ByteString
                -> m (Maybe ByteString)
-renderTemplate ts name = do
-    evalTemplateMonad
-        (do mt <- evalWithHooks name
-            maybe (return Nothing)
-                (\t -> liftM Just $ renderDocument =<< toDocument t)
-                mt
-        ) (X.TextNode "") ts
+renderTemplate ts name =
+    liftM (liftM toByteString) (renderTemplateBuilder ts name)
 
 
 ------------------------------------------------------------------------------
@@ -482,6 +494,19 @@ renderWithArgs args ts = renderTemplate (bindStrings args 
ts)
 
 
 ------------------------------------------------------------------------------
+-- | Renders a template with the specified arguments passed to it, and output
+-- as a 'Builder'.  This is a convenience function for the common pattern of
+-- calling renderTemplateBuilder after using bindString, bindStrings, or
+-- bindSplice to set up the arguments to the template.
+renderWithArgsBuilder :: Monad m
+                      => [(Text, Text)]
+                      -> TemplateState m
+                      -> ByteString
+                      -> m (Maybe Builder)
+renderWithArgsBuilder args ts = renderTemplateBuilder (bindStrings args ts)
+
+
+------------------------------------------------------------------------------
 -- Template loading
 ------------------------------------------------------------------------------
 
commit 3295bedc34345485a5007cdadc1093e27bf0be13
Author: Chris Smith <[email protected]>
Date:   Sun Jan 9 10:37:19 2011 -0700

    * Fix some documentation that still called Heist an XML-based system.
    * Export XML versions of some functions (getXMLDoc and addXMLTemplate)
    * Identify .xtpl files as XML format templates and load them.

diff --git a/src/Text/Templating/Heist.hs b/src/Text/Templating/Heist.hs
index d2866d1..6cd74fc 100644
--- a/src/Text/Templating/Heist.hs
+++ b/src/Text/Templating/Heist.hs
@@ -4,10 +4,10 @@
 
   This module contains the core definitions for the Heist template system.
 
-  The Heist template system is based on XML\/xhtml.  It allows you to build
-  custom XML-based markup languages.  With Heist you can define your own
-  domain-specific XML tags implemented with Haskell and use them in your
-  templates.  
+  The Heist template system is based on HTML and XML.  It allows you to build
+  custom HTML and XML based markup languages.  With Heist you can define your
+  own domain-specific HTML and XML tags implemented with Haskell and use them
+  in your templates.
 
   The most important concept in Heist is the 'Splice'.  Splices can be thought
   of as functions that transform a node into a list of nodes.  Heist then
@@ -19,23 +19,25 @@
   Suppose you have a place on your page where you want to display a link with
   the text \"Logout username\" if the user is currently logged in or a link to
   the login page if no user is logged in.  Assume you have a function
-  @getUser :: MyAppMonad (Maybe ByteString)@ that gets the current user.
+  @getUser :: MyAppMonad (Maybe Text)@ that gets the current user.
   You can implement this functionality with a 'Splice' as follows:
 
   > import             Data.ByteString.Char8 (ByteString)
   > import qualified   Data.ByteString.Char8 as B
-  > import qualified   Text.XML.Expat.Tree as X
+  > import             Data.Text (Text)
+  > import qualified   Data.Text as T
+  > import qualified   Text.XmlHtml as X
   > 
   > import             Text.Templating.Heist
   >
-  > link :: ByteString -> ByteString -> Node
-  > link target text = X.Element "a" [("href", target)] [X.Text text]
+  > link :: Text -> Text -> Node
+  > link target text = X.Element "a" [("href", target)] [X.TextNode text]
   > 
   > loginLink :: Node
   > loginLink = link "/login" "Login"
   > 
-  > logoutLink :: ByteString -> Node
-  > logoutLink user = link "/logout" (B.append "Logout " user)
+  > logoutLink :: Text -> Node
+  > logoutLink user = link "/logout" (T.append "Logout " user)
   > 
   > loginLogoutSplice :: Splice MyAppMonad
   > loginLogoutSplice = do
@@ -43,7 +45,7 @@
   >     return $ [maybe loginLink logoutLink user]
   >
 
-  Next, you need to bind that splice to an XML tag.  Heist stores information
+  Next, you need to bind that splice to a tag.  Heist stores information
   about splices and templates in the 'TemplateState' data structure.  The
   following code demonstrates how this splice would be used.
 
@@ -73,6 +75,7 @@ module Text.Templating.Heist
 
     -- * Functions and declarations on TemplateState values
   , addTemplate
+  , addXMLTemplate
   , emptyTemplateState
   , bindSplice
   , bindSplices
@@ -110,6 +113,7 @@ module Text.Templating.Heist
 
     -- * Misc functions
   , getDoc
+  , getXMLDoc
   , bindStaticTag
 
   ) where
diff --git a/src/Text/Templating/Heist/Internal.hs 
b/src/Text/Templating/Heist/Internal.hs
index 66f7a4e..55739e6 100644
--- a/src/Text/Templating/Heist/Internal.hs
+++ b/src/Text/Templating/Heist/Internal.hs
@@ -192,7 +192,7 @@ insertTemplate p t st =
 
 
 ------------------------------------------------------------------------------
--- | Adds a template to the template state.
+-- | Adds an HTML format template to the template state.
 addTemplate :: Monad m =>
                ByteString
             -> Template
@@ -485,17 +485,36 @@ renderWithArgs args ts = renderTemplate (bindStrings args 
ts)
 -- Template loading
 ------------------------------------------------------------------------------
 
--- | Reads an HTML template from disk.
-getDoc :: String -> IO (Either String X.Document)
-getDoc f = do
+
+------------------------------------------------------------------------------
+-- | Type synonym for parsers.
+type ParserFun = String -> ByteString -> Either String X.Document
+
+
+------------------------------------------------------------------------------
+-- | Reads an HTML or XML template from disk.
+getDocWith :: ParserFun -> String -> IO (Either String X.Document)
+getDocWith parser f = do
     bs <- catch (liftM Right $ B.readFile f)
                 (\(e::SomeException) -> return $ Left $ show e)
 
-    let d = either Left (X.parseHTML f) bs
+    let d = either Left (parser f) bs
     return $ mapLeft (\s -> f ++ " " ++ s) d
 
 
 ------------------------------------------------------------------------------
+-- | Reads an HTML template from disk.
+getDoc :: String -> IO (Either String X.Document)
+getDoc = getDocWith X.parseHTML
+
+
+------------------------------------------------------------------------------
+-- | Reads an XML template from disk.
+getXMLDoc :: String -> IO (Either String X.Document)
+getXMLDoc = getDocWith X.parseHTML
+
+
+------------------------------------------------------------------------------
 mapLeft :: (a -> b) -> Either a c -> Either b c
 mapLeft g = either (Left . g) Right
 mapRight :: (b -> c) -> Either a b -> Either a c
@@ -504,25 +523,31 @@ mapRight g = either Left (Right . g)
 
 ------------------------------------------------------------------------------
 -- | Loads a template with the specified path and filename.  The
--- template is only loaded if it has a ".tpl" extension.
+-- template is only loaded if it has a ".tpl" or ".xtpl" extension.
 loadTemplate :: String -- ^ path of the template root
              -> String -- ^ full file path (includes the template root)
              -> IO [Either String (TPath, X.Document)] --TemplateMap
 loadTemplate templateRoot fname
-    | ".tpl" `isSuffixOf` fname = do
+    | isHTMLTemplate = do
         c <- getDoc fname
         return [fmap (\t -> (splitLocalPath $ BC.pack tName, t)) c]
+    | isXMLTemplate = do
+        c <- getXMLDoc fname
+        return [fmap (\t -> (splitLocalPath $ BC.pack tName, t)) c]
     | otherwise = return []
   where -- tName is path relative to the template root directory
+        isHTMLTemplate = ".tpl"  `isSuffixOf` fname
+        isXMLTemplate  = ".xtpl" `isSuffixOf` fname
         correction = if last templateRoot == '/' then 0 else 1
+        extLen     = if isHTMLTemplate then 4 else 5
         tName = drop ((length templateRoot)+correction) $
                 -- We're only dropping the template root, not the whole path
-                take ((length fname) - 4) fname
+                take ((length fname) - extLen) fname
 
 
 ------------------------------------------------------------------------------
 -- | Traverses the specified directory structure and builds a
--- TemplateState by loading all the files with a ".tpl" extension.
+-- TemplateState by loading all the files with a ".tpl" or ".xtpl" extension.
 loadTemplates :: Monad m => FilePath -> TemplateState m -> IO (Either String 
(TemplateState m))
 loadTemplates dir ts = do
     d <- readDirectoryWith (loadTemplate dir) dir
-----------------------------------------------------------------------


hooks/post-receive
-- 
heist
_______________________________________________
Snap mailing list
[email protected]
http://mailman-mail5.webfaction.com/listinfo/snap

Reply via email to