Updated yesod-routes docs

This commit is contained in:
Michael Snoyman 2012-01-03 13:41:41 +02:00
parent 09750605a8
commit fa4fd5690f
2 changed files with 49 additions and 2 deletions

View File

@ -17,6 +17,53 @@ import Web.PathPieces (PathPiece (..), PathMultiPiece (..))
import Control.Applicative ((<$>)) import Control.Applicative ((<$>))
import Data.List (foldl') import Data.List (foldl')
-- |
--
-- This function will generate a single clause that will address all your
-- routing needs. It takes three arguments. The third (a list of 'Resource's)
-- is self-explanatory. We\'ll discuss the first two. But first, let\'s cover
-- the terminology.
--
-- Dispatching involves a master type and a sub type. When you dispatch to the
-- top level type, master and sub are the same. Each time to dispatch to
-- another subsite, the sub changes. This requires two changes:
--
-- * Getting the new sub value. This is handled via 'subsiteFunc'.
--
-- * Figure out a way to convert sub routes to the original master route. To
-- address this, we keep a toMaster function, and each time we dispatch to a
-- new subsite, we compose it with the constructor for that subsite.
--
-- Dispatching acts on two different components: the request method and a list
-- of path pieces. If we cannot match the path pieces, we need to return a 404
-- response. If the path pieces match, but the method is not supported, we need
-- to return a 405 response.
--
-- The final result of dispatch is going to be an application type. A simple
-- example would be the WAI Application type. However, our handler functions
-- will need more input: the master/subsite, the toMaster function, and the
-- type-safe route. Therefore, we need to have another type, the handler type,
-- and a function that turns a handler into an application, i.e.
--
-- > runHandler :: handler sub master -> master -> sub -> Route sub -> (Route sub -> Route master) -> app
--
-- This is the first argument to our function. Note that this will almost
-- certainly need to be a method of a typeclass, since it will want to behave
-- differently based on the subsite.
--
-- Note that the 404 response passed in is an application, while the 405
-- response is a handler, since the former can\'t be passed the type-safe
-- route.
--
-- In the case of a subsite, we don\'t directly deal with a handler function.
-- Instead, we redispatch to the subsite, passing on the updated sub value and
-- toMaster function, as well as any remaining, unparsed path pieces. This
-- function looks like:
--
-- > dispatcher :: master -> sub -> (Route sub -> Route master) -> app -> handler sub master -> Text -> [Text] -> app
--
-- Where the parameters mean master, sub, toMaster, 404 response, 405 response,
-- request method and path pieces.
mkDispatchClause :: Q Exp -- ^ runHandler function mkDispatchClause :: Q Exp -- ^ runHandler function
-> Q Exp -- ^ dispatcher function -> Q Exp -- ^ dispatcher function
-> [Resource] -> [Resource]

View File

@ -14,11 +14,9 @@ import Data.Text (Text, unpack, singleton)
import Yesod.Routes.Dispatch hiding (Static, Dynamic) import Yesod.Routes.Dispatch hiding (Static, Dynamic)
import Yesod.Routes.Class hiding (Route) import Yesod.Routes.Class hiding (Route)
import qualified Yesod.Routes.Class as YRC import qualified Yesod.Routes.Class as YRC
import Web.PathPieces
import qualified Yesod.Routes.Dispatch as D import qualified Yesod.Routes.Dispatch as D
import Yesod.Routes.TH hiding (Dispatch) import Yesod.Routes.TH hiding (Dispatch)
import Language.Haskell.TH.Syntax import Language.Haskell.TH.Syntax
import qualified Data.Map as Map
result :: ([Text] -> Maybe Int) -> Dispatch Int result :: ([Text] -> Maybe Int) -> Dispatch Int
result f ts = f ts result f ts = f ts
@ -138,6 +136,7 @@ instance Dispatcher MySubParam master where
[[c]] -> ("subparam " ++ show i ++ ' ' : [c], Just $ toMaster $ ParamRoute c) [[c]] -> ("subparam " ++ show i ++ ' ' : [c], Just $ toMaster $ ParamRoute c)
_ -> app404 _ -> app404
{-
thDispatchAlias thDispatchAlias
:: (master ~ MyApp, sub ~ MyApp, handler ~ String, app ~ (String, Maybe (YRC.Route MyApp))) :: (master ~ MyApp, sub ~ MyApp, handler ~ String, app ~ (String, Maybe (YRC.Route MyApp)))
=> master => master
@ -200,6 +199,7 @@ thDispatchAlias master sub toMaster app404 handler405 method0 pieces0 =
] ]
methodsRootR = Map.fromList [("GET", getRootR)] methodsRootR = Map.fromList [("GET", getRootR)]
methodsBlogPostR = Map.fromList [("GET", getBlogPostR), ("POST", postBlogPostR)] methodsBlogPostR = Map.fromList [("GET", getBlogPostR), ("POST", postBlogPostR)]
-}
main :: IO () main :: IO ()
main = hspecX $ do main = hspecX $ do