]> gitweb @ CieloNegro.org - Rakka.git/blobdiff - Rakka/Resource/PageEntity.hs
implemented page listing
[Rakka.git] / Rakka / Resource / PageEntity.hs
index 1a8eb03c4d07e750760193e12035c9e360ff5f6f..0b5459447419ffab669650e8f08f5bd1c6abe381 100644 (file)
@@ -7,6 +7,7 @@ import           Control.Arrow
 import           Control.Arrow.ArrowIO
 import           Control.Arrow.ArrowIf
 import           Control.Arrow.ArrowList
+import           Control.Monad.Trans
 import           Data.Char
 import           Data.Maybe
 import           Network.HTTP.Lucu
@@ -17,11 +18,16 @@ import           Rakka.Page
 import           Rakka.Resource
 import           Rakka.Storage
 import           Rakka.SystemConfig
+import           Rakka.Utils
 import           Rakka.Wiki.Engine
 import           System.FilePath
+import           Text.XML.HXT.Arrow.Namespace
+import           Text.XML.HXT.Arrow.WriteDocument
 import           Text.XML.HXT.Arrow.XmlArrow
+import           Text.XML.HXT.Arrow.XmlIOStateArrow
 import           Text.XML.HXT.Arrow.XmlNodeSet
 import           Text.XML.HXT.DOM.TypeDefs
+import           Text.XML.HXT.DOM.XmlKeywords
 
 
 fallbackPageEntity :: Environment -> [String] -> IO (Maybe ResourceDef)
@@ -33,11 +39,11 @@ fallbackPageEntity env path
         = return $ Just $ ResourceDef {
             resUsesNativeThread = False
           , resIsGreedy         = True
-          , resGet              = Just $ handleGet env (toPageName path)
+          , resGet              = Just $ handleGet    env (toPageName path)
           , resHead             = Nothing
           , resPost             = Nothing
-          , resPut              = Just $ handlePut env (toPageName path)
-          , resDelete           = Nothing
+          , resPut              = Just $ handlePut    env (toPageName path)
+          , resDelete           = Just $ handleDelete env (toPageName path)
           }
     where
       toPageName :: [String] -> PageName
@@ -50,23 +56,47 @@ handleGet env name
     -> do pageM <- getPageA (envStorage env) -< (name, Nothing)
           case pageM of
             Nothing
-                -> handlePageNotFound env -< name
+                -> do items <- getDirContentsA (envStorage env) -< (name, Nothing)
+                      case items of
+                        [] -> handlePageNotFound   env -< name
+                        _  -> handleGetPageListing env -< (name, items)
+            Just page
+                -> if isEntity page then
+                       handleGetEntity env -< page
+                   else
+                       handleRedirect env -< page
 
-            Just redir@(Redirection _ _ _ _ _)
-                -> handleRedirect env -< redir
-
-            Just entity@(Entity _ _ _ _ _ _ _ _ _ _ _ _ _ _ _)
-                -> handleGetEntity env -< entity
 
 {-
   HTTP/1.1 302 Found
-  Location: http://example.org/Destination#Redirect:Source
+  Location: http://example.org/Destination.html#Redirect:Source
 -}
 handleRedirect :: (ArrowXml a, ArrowIO a) => Environment -> a Page (Resource ())
 handleRedirect env
     = proc redir
-    -> do BaseURI baseURI <- getSysConfA (envSysConf env) -< ()
-          returnA -< redirect Found (mkPageURI baseURI $ redirDest redir) -- FIXME
+    -> returnA -< do mType <- getEntityType
+                     case mType of
+                       MIMEType "application" "xhtml+xml" _
+                           -> do BaseURI baseURI <- getSysConf (envSysConf env)
+                                 let uri = mkPageFragmentURI
+                                           baseURI
+                                           (redirDest redir)
+                                           ("Redirect:" ++ redirName redir)
+                                 redirect Found uri
+
+                       MIMEType "text" "xml" _
+                           -> do setContentType mType
+                                 [resultStr] <- liftIO $ runX ( setErrorMsgHandler False fail
+                                                                >>>
+                                                                constA redir
+                                                                >>>
+                                                                xmlizePage
+                                                                >>>
+                                                                writeDocumentToString [ (a_indent, v_1) ]
+                                                              )
+                                 output resultStr
+
+                       _   -> fail ("internal error: getEntityType returned " ++ show mType)
 
 
 handleGetEntity :: (ArrowXml a, ArrowChoice a, ArrowIO a) => Environment -> a Page (Resource ())
@@ -92,8 +122,10 @@ entityToXHTML env
     -> do SiteName   siteName   <- getSysConfA (envSysConf env) -< ()
           BaseURI    baseURI    <- getSysConfA (envSysConf env) -< ()
           StyleSheet styleSheet <- getSysConfA (envSysConf env) -< ()
+          GlobalLock isGLocked  <- getSysConfA (envSysConf env) -< ()
 
-          name <- (getXPathTreesInDoc "/page/@name/text()" >>> getText) -< page
+          name     <- (getXPathTreesInDoc "/page/@name/text()" >>> getText) -< page
+          isLocked <- (getXPathTreesInDoc "/page/@isLocked/text()" >>> getText >>> parseYesOrNo) -< page
 
           let cssHref   = [uriToString id (mkObjectURI baseURI styleSheet) ""]
               scriptSrc = [uriToString id (baseURI { uriPath = uriPath baseURI </> "js" }) ""]
@@ -130,6 +162,12 @@ entityToXHTML env
                            += sattr "type" "text/javascript"
                            += attr "src" (arr id >>> mkText)
                          )
+                      += ( eelem "script"
+                           += sattr "type" "text/javascript"
+                           += txt ("Rakka.baseURI=\"" ++ uriToString id baseURI "" ++ "\";")
+                           += txt ("Rakka.isLocked=" ++ trueOrFalse isLocked ++ ";")
+                           += txt ("Rakka.isGlobalLocked=" ++ trueOrFalse isGLocked ++ ";")
+                         )
                     )
                  += ( eelem "body"
                       += ( eelem "div"
@@ -164,6 +202,8 @@ entityToXHTML env
                               )
                          )
                     )
+                 >>>
+                 uniqueNamespacesFromDeclAndQNames
                ) ) -<< page
 
 
@@ -178,6 +218,126 @@ readSubPage env
          returnA -< subXHTML
 
 
+{-
+  <pageListing path="Foo">
+    <page name="Foo/Bar" />
+    <page name="Foo/Baz" />
+  </pageListing>
+-}
+handleGetPageListing :: (ArrowXml a, ArrowChoice a, ArrowIO a) => Environment -> a (PageName, [PageName]) (Resource ())
+handleGetPageListing env
+    = proc (dir, items)
+    -> do tree <- ( eelem "/"
+                    += ( eelem "pageListing"
+                         += attr "path" (arr fst >>> mkText)
+                         += ( arrL snd
+                              >>> 
+                              ( eelem "page"
+                                += attr "name" (arr id >>> mkText)
+                              )
+                            )
+                       )
+                  ) -< (dir, items)
+          returnA -< outputXmlPage tree (pageListingToXHTML env)
+
+
+pageListingToXHTML :: (ArrowXml a, ArrowChoice a, ArrowIO a) => Environment -> a XmlTree XmlTree
+pageListingToXHTML env
+    = proc pageListing
+    -> do SiteName   siteName   <- getSysConfA (envSysConf env) -< ()
+          BaseURI    baseURI    <- getSysConfA (envSysConf env) -< ()
+          StyleSheet styleSheet <- getSysConfA (envSysConf env) -< ()
+          GlobalLock isGLocked  <- getSysConfA (envSysConf env) -< ()
+
+          name <- (getXPathTreesInDoc "/pageListing/@path/text()" >>> getText) -< pageListing
+
+          let cssHref   = [uriToString id (mkObjectURI baseURI styleSheet) ""]
+              scriptSrc = [uriToString id (baseURI { uriPath = uriPath baseURI </> "js" }) ""]
+
+          pageTitle    <- listA (readSubPage env) -< (name, Nothing, "PageTitle")
+          leftSideBar  <- listA (readSubPage env) -< (name, Nothing, "SideBar/Left")
+          rightSideBar <- listA (readSubPage env) -< (name, Nothing, "SideBar/Right")
+
+          ( eelem "/"
+            += ( eelem "html"
+                 += sattr "xmlns" "http://www.w3.org/1999/xhtml"
+                 += ( eelem "head"
+                      += ( eelem "title"
+                           += txt siteName
+                           += txt " - "
+                           += getXPathTreesInDoc "/pageListing/@path/text()"
+                         )
+                      += ( constL cssHref
+                           >>>
+                           eelem "link"
+                           += sattr "rel"  "stylesheet"
+                           += sattr "type" "text/css"
+                           += attr "href" (arr id >>> mkText)
+                         )
+                      += ( constL scriptSrc
+                           >>>
+                           eelem "script"
+                           += sattr "type" "text/javascript"
+                           += attr "src" (arr id >>> mkText)
+                         )
+                      += ( eelem "script"
+                           += sattr "type" "text/javascript"
+                           += txt ("Rakka.baseURI = \"" ++ uriToString id baseURI "" ++ "\";")
+                           += txt ("Rakka.isGlobalLocked=" ++ trueOrFalse isGLocked ++ ";")
+                         )
+                    )
+                 += ( eelem "body"
+                      += ( eelem "div"
+                           += sattr "class" "header"
+                         )
+                      += ( eelem "div"
+                           += sattr "class" "center"
+                           += ( eelem "div"
+                                += sattr "class" "title"
+                                += constL pageTitle
+                              )
+                           += ( eelem "div"
+                                += sattr "class" "body"
+                                += ( eelem "ul"
+                                     += ( getXPathTreesInDoc "/pageListing/page/@name/text()"
+                                          >>>
+                                          eelem "li"
+                                          += ( eelem "a"
+                                               += attr "href" ( getText
+                                                                >>>
+                                                                arr (\ x -> uriToString id (mkPageURI baseURI x) "")
+                                                                >>>
+                                                                mkText
+                                                              )
+                                               += this
+                                             )
+                                        )
+                                   )
+                              )
+                         )
+                      += ( eelem "div"
+                           += sattr "class" "footer"
+                         )
+                      += ( eelem "div"
+                           += sattr "class" "left sideBar"
+                           += ( eelem "div"
+                                += sattr "class" "content"
+                                += constL leftSideBar
+                              )
+                         )
+                      += ( eelem "div"
+                           += sattr "class" "right sideBar"
+                           += ( eelem "div"
+                                += sattr "class" "content"
+                                += constL rightSideBar
+                              )
+                         )
+                    )
+                 >>>
+                 uniqueNamespacesFromDeclAndQNames
+               ) ) -<< pageListing
+
+
 {-
   <pageNotFound name="Foo/Bar" />
 -}
@@ -199,6 +359,7 @@ notFoundToXHTML env
     -> do SiteName   siteName   <- getSysConfA (envSysConf env) -< ()
           BaseURI    baseURI    <- getSysConfA (envSysConf env) -< ()
           StyleSheet styleSheet <- getSysConfA (envSysConf env) -< ()
+          GlobalLock isGLocked  <- getSysConfA (envSysConf env) -< ()
 
           name <- (getXPathTreesInDoc "/pageNotFound/@name/text()" >>> getText) -< pageNotFound
 
@@ -231,6 +392,11 @@ notFoundToXHTML env
                            += sattr "type" "text/javascript"
                            += attr "src" (arr id >>> mkText)
                          )
+                      += ( eelem "script"
+                           += sattr "type" "text/javascript"
+                           += txt ("Rakka.baseURI = \"" ++ uriToString id baseURI "" ++ "\";")
+                           += txt ("Rakka.isGlobalLocked=" ++ trueOrFalse isGLocked ++ ";")
+                         )
                     )
                  += ( eelem "body"
                       += ( eelem "div"
@@ -265,12 +431,22 @@ notFoundToXHTML env
                               )
                          )
                     )
+                 >>>
+                 uniqueNamespacesFromDeclAndQNames
                ) ) -<< pageNotFound
 
 
 handlePut :: Environment -> PageName -> Resource ()
 handlePut env name
-    = runXmlA env "rakka-page-1.0.rng" $ proc tree
-    -> do page   <- parseXmlizedPage -< (name, tree)
-          status <- putPageA (envStorage env) -< page
-          returnA  -< setStatus status
+    = do userID <- getUserID env
+         runXmlA env "rakka-page-1.0.rng" $ proc tree
+             -> do page   <- parseXmlizedPage -< (name, tree)
+                   status <- putPageA (envStorage env) -< (userID, page)
+                   returnA  -< setStatus status
+
+
+handleDelete :: Environment -> PageName -> Resource ()
+handleDelete env name
+    = do userID <- getUserID env
+         status <- deletePage (envStorage env) userID name
+         setStatus status