module Rakka.Resource.Render
( fallbackRender
)
where
import Control.Arrow
import Control.Arrow.ArrowIO
import Control.Arrow.ArrowIf
import Data.Char
import Network.HTTP.Lucu
import Network.HTTP.Lucu.Utils
import Rakka.Environment
import Rakka.Page
import Rakka.Resource
import Rakka.Storage
import Rakka.SystemConfig
import Rakka.Wiki.Engine
import System.FilePath
import System.Time
import Text.XML.HXT.Arrow.Namespace
import Text.XML.HXT.Arrow.XmlArrow
import Text.XML.HXT.Arrow.XmlNodeSet
import Text.XML.HXT.DOM.TypeDefs
fallbackRender :: Environment -> [String] -> IO (Maybe ResourceDef)
fallbackRender env path
| null path = return Nothing
| null $ head path = return Nothing
| not $ isUpper $ head $ head path = return Nothing -- /Foo/bar のような形式でない。
| otherwise
= return $ Just $ ResourceDef {
resUsesNativeThread = False
, resIsGreedy = True
, resGet = Just $ handleGet env (toPageName path)
, resHead = Nothing
, resPost = Nothing
, resPut = Nothing
, resDelete = Nothing
}
where
toPageName :: [String] -> PageName
toPageName = decodePageName . dropExtension . joinWith "/"
handleGet :: Environment -> PageName -> Resource ()
handleGet env name
= runIdempotentA $ proc ()
-> do pageM <- getPageA (envStorage env) -< name
case pageM of
Nothing
-> handlePageNotFound env -< name
Just redir@(Redirection _ _ _ _)
-> handleRedirect env -< redir
Just entity@(Entity _ _ _ _ _ _ _ _ _ _ _ _ _ _)
-> handleGetEntity env -< entity
{-
HTTP/1.1 302 Found
Location: http://example.org/Destination?from=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 $ redirName redir) -- FIXME
{-
-- デフォルトでない場合のみ存在
lastModified="2000-01-01T00:00:00">
blah blah...
-- 存在しない場合もある
-- 存在しない場合もある
blah blah...
blah blah...
blah blah...
blah blah...
-}
handleGetEntity :: (ArrowXml a, ArrowChoice a, ArrowIO a) => Environment -> a Page (Resource ())
handleGetEntity env
= proc page
-> do tree <- formatEntirePage (envStorage env) (envSysConf env) (envInterpTable env) -< page
returnA -< do let lastMod = toClockTime $ pageLastMod page
-- text/x-rakka の場合は、内容が動的に生成され
-- てゐる可能性があるので、ETag も
-- Last-Modified も返す事が出來ない。
case pageType page of
MIMEType "text" "x-rakka" _
-> return ()
_ -> case pageRevision page of
0 -> foundTimeStamp lastMod -- 0 はデフォルトページ
rev -> foundEntity (strongETag $ show rev) lastMod
outputXmlPage tree entityToXHTML
entityToXHTML :: ArrowXml a => a XmlTree XmlTree
entityToXHTML
= eelem "/"
+= ( eelem "html"
+= sattr "xmlns" "http://www.w3.org/1999/xhtml"
+= ( getXPathTreesInDoc "/page/@lang"
`guards`
qattr (QN "xml" "lang" "")
( getXPathTreesInDoc "/page/@lang/text()" )
)
+= ( eelem "head"
+= ( eelem "title"
+= getXPathTreesInDoc "/page/@site/text()"
+= txt " - "
+= getXPathTreesInDoc "/page/@name/text()"
)
+= ( eelem "link"
+= sattr "rel" "stylesheet"
+= sattr "type" "text/css"
+= attr "href"
( getXPathTreesInDoc "/page/@styleSheet/text()" )
)
)
+= ( eelem "body"
+= ( eelem "div"
+= sattr "class" "header"
)
+= ( eelem "div"
+= sattr "class" "center"
+= ( eelem "div"
+= sattr "class" "title"
+= getXPathTreesInDoc "/page/pageTitle/*"
)
+= ( eelem "div"
+= sattr "class" "body"
+= getXPathTreesInDoc "/page/body/*"
)
)
+= ( eelem "div"
+= sattr "class" "footer"
)
+= ( eelem "div"
+= sattr "class" "left sideBar"
+= ( eelem "div"
+= sattr "class" "content"
+= getXPathTreesInDoc "/page/sideBar/left/*"
)
)
+= ( eelem "div"
+= sattr "class" "right sideBar"
+= ( eelem "div"
+= sattr "class" "content"
+= getXPathTreesInDoc "/page/sideBar/right/*"
)
)
)
>>>
uniqueNamespacesFromDeclAndQNames
)
{-
blah blah...
blah blah...
blah blah...
-}
handlePageNotFound :: (ArrowXml a, ArrowChoice a, ArrowIO a) => Environment -> a PageName (Resource ())
handlePageNotFound env
= proc name
-> do tree <- formatUnexistentPage (envStorage env) (envSysConf env) (envInterpTable env) -< name
returnA -< do setStatus NotFound
outputXmlPage tree notFoundToXHTML
notFoundToXHTML :: ArrowXml a => a XmlTree XmlTree
notFoundToXHTML
= eelem "/"
+= ( eelem "html"
+= sattr "xmlns" "http://www.w3.org/1999/xhtml"
+= ( eelem "head"
+= ( eelem "title"
+= getXPathTreesInDoc "/pageNotFound/@site/text()"
+= txt " - "
+= getXPathTreesInDoc "/pageNotFound/@name/text()"
)
+= ( eelem "link"
+= sattr "rel" "stylesheet"
+= sattr "type" "text/css"
+= attr "href"
( getXPathTreesInDoc "/pageNotFound/@styleSheet/text()" )
)
)
+= ( eelem "body"
+= ( eelem "div"
+= sattr "class" "header"
)
+= ( eelem "div"
+= sattr "class" "center"
+= ( eelem "div"
+= sattr "class" "title"
+= getXPathTreesInDoc "/pageNotFound/pageTitle/*"
)
+= ( eelem "div"
+= sattr "class" "body"
+= txt "404 Not Found (FIXME)" -- FIXME
)
)
+= ( eelem "div"
+= sattr "class" "footer"
)
+= ( eelem "div"
+= sattr "class" "left sideBar"
+= ( eelem "div"
+= sattr "class" "content"
+= getXPathTreesInDoc "/pageNotFound/sideBar/left/*"
)
)
+= ( eelem "div"
+= sattr "class" "right sideBar"
+= ( eelem "div"
+= sattr "class" "content"
+= getXPathTreesInDoc "/pageNotFound/sideBar/right/*"
)
)
)
>>>
uniqueNamespacesFromDeclAndQNames
)