UrlDisp-0.1.7: Network/UrlDisp.hs
-----------------------------------------------------------------------
-- |
-- Module: Network.UrlDisp
-- Copyright: (c) Artyom Shalkhakov 2009, Sterling Clover 2008
-- License: BSD 3 Clause
-- Maintainer: artyom.shalkhakov@gmail.com
-- Stability: experimental
-- Portability: portable
--
-- URL dispatching (routing) library, based on Sterling Clover's HVAC.
-----------------------------------------------------------------------
module Network.UrlDisp (
-- * Types
UrlDisp,
UrlS,
-- * Controller combinators
h, (|/), (|//), (|?), (|\), (|\\), (|.),
path, meth, param, takePath, readPath, endPath,
-- * Running UrlDisp
runUrlDisp, evalUrlDisp
) where
import Control.Monad.Maybe
import Control.Monad.State.Strict
import Network.CGI
import Network.CGI.Monad
import Network.UrlDisp.Types
import Network.UrlDisp.Controller
-- | Given path and a sequence of actions chained using combinators
-- defined in controller API, run them in the CGI monad.
runUrlDisp :: (MonadCGI m)
=> String -- ^ path (hierarchical part of the URL)
-> UrlDisp m a
-> m (Maybe a)
runUrlDisp p (UrlDisp hn) = runMaybeT $ evalStateT hn (UrlS {pPath = pinfo})
where pinfo = (filter (not . null) . splitPath) p
splitPath :: String -> [String]
splitPath xs = let (zs, ys) = break (=='/') xs
in zs : case ys of
[] -> []
_:ws -> splitPath ws
-- | The same as runUrlDisp, but yields CGIResult. If URL dispatching
-- failed, then a 404 not found error is returned.
evalUrlDisp :: (MonadCGI m, MonadIO m) => UrlDisp m CGIResult -> m CGIResult
evalUrlDisp handler = pathInfo >>= \s -> runUrlDisp s handler >>=
maybe (outputNotFound s) return