> -- | Definitions and functions for building a router
> module Frame.Router (
>   FrameRouter,
>   fileFolder,
>   Router,
>   startRouter
> ) where
> import Data.List
> import Data.Map
> import qualified Data.ByteString.Lazy as L
> import Control.Monad.State (StateT, runStateT)
> import Control.Monad.Reader (ReaderT, runReaderT)
> import Frame.GUI
> import Frame.Data
> import Frame.Config
> import Frame.State
> import Frame.Types
> import Frame.Utilities
> import Frame.Validation
> import Frame.Model
> import Frame.View
> class (FrameConfig m, FrameState m, FrameIO m) => FrameRouter m
> instance (FrameConfig m, FrameState m, FrameIO m) => FrameRouter m
> -- | The 'fileFolder' function maps a URL to a filesystem folder
> fileFolder :: FrameRouter m => String   -- ^ Folder on the file system
>                             -> [String] -- ^ Exploded URL
>                             -> m Data   -- ^ Either an Error404 or the File
> fileFolder r fs = do
>               f <- liftIO $ L.readFile (r ++ implodeUrl fs) `catch` (\_ -> return L.empty) 
>               case L.null f of 
>                  True -> return Error404
>                  False -> return $ File f
> -- | A router maps from a path (list of URL parts) to some 'Data'
> type Router = ([String] -> StateT Vars (ReaderT Config IO) Data)
> {-|
>     Executes a given router and validators against request information from the
>     server
> -}
> startRouter :: Router                -- ^ The router being executed
>             -> Config                -- ^ The configuration
>             -> Validators            -- ^ Validators to check fields against
>             -> [(FieldName, String)] -- ^ Initial fields (from the server)
>             -> String                -- ^ The URL (from the server)
>             -> String                -- ^ The session ID
>             -> Bool                  -- ^ Whether this is an Ajax request
>             -> IO Data               -- ^ The data to be returned
> startRouter r c@Config{database=db} v vs u id a = let fs = fromList' db vs in
>     do 
>         (d, _) <- runReaderT (runStateT (r $ explodeURL u) startState{fields=fs, validators=v, post=size fs /= 0, ajax=a}) c{sessionId=id}
>         return d