yesod-routes-1.2.0.1: Efficient routing for Yesod.

Safe Haskell | None

Yesod.Routes.TH

Contents

- Data types
  - Helper functions
- Functions
  - RenderRoute
  - ParseRoute
  - Dispatch
  - Dispatch

Synopsis

- data Resource typ = Resource {
  - resourceName :: String
  - resourcePieces :: [(CheckOverlap, Piece typ)]
  - resourceDispatch :: Dispatch typ
  - resourceAttrs :: [String]
  }
- data ResourceTree typ
  - = ResourceLeaf (Resource typ)
  - | ResourceParent String [(CheckOverlap, Piece typ)] [ResourceTree typ]
- data Piece typ
  - = Static String
  - | Dynamic typ
- data Dispatch typ
  - = Methods {
    - methodsMulti :: Maybe typ
    - methodsMethods :: [String]
    }
  - | Subsite {
    - subsiteType :: typ
    - subsiteFunc :: String
    }
- type CheckOverlap = Bool
- data FlatResource a = FlatResource [(String, [(CheckOverlap, Piece a)])] String [(CheckOverlap, Piece a)] (Dispatch a)
- resourceMulti :: Resource typ -> Maybe typ
- resourceTreePieces :: ResourceTree typ -> [(CheckOverlap, Piece typ)]
- resourceTreeName :: ResourceTree typ -> String
- flatten :: [ResourceTree a] -> [FlatResource a]
- mkRenderRouteInstance :: Type -> [ResourceTree Type] -> Q [Dec]
- mkRenderRouteInstance' :: Cxt -> Type -> [ResourceTree Type] -> Q [Dec]
- mkRouteCons :: [ResourceTree Type] -> ([Con], [Dec])
- mkRenderRouteClauses :: [ResourceTree Type] -> Q [Clause]
- mkParseRouteInstance :: Type -> [ResourceTree a] -> Q Dec
- mkRouteAttrsInstance :: Type -> [ResourceTree a] -> Q Dec
- mkDispatchClause :: MkDispatchSettings -> [ResourceTree a] -> Q Clause
- data MkDispatchSettings = MkDispatchSettings {
  - mdsRunHandler :: Q Exp
  - mdsSubDispatcher :: Q Exp
  - mdsGetPathInfo :: Q Exp
  - mdsSetPathInfo :: Q Exp
  - mdsMethod :: Q Exp
  - mds404 :: Q Exp
  - mds405 :: Q Exp
  - mdsGetHandler :: Maybe String -> String -> Q Exp
  }
- defaultGetHandler :: Maybe String -> String -> Q Exp

# Data types

data Resource typ Source

Constructors

Resource |

Fields

resourceName :: String
resourcePieces :: [(CheckOverlap, Piece typ)]
resourceDispatch :: Dispatch typ
resourceAttrs :: [String]

Instances

Functor Resource |
Show typ => Show (Resource typ) |
Lift t => Lift (Resource t) |

data ResourceTree typ Source

Constructors

ResourceLeaf (Resource typ) |
ResourceParent String [(CheckOverlap, Piece typ)] [ResourceTree typ] |

Instances

Functor ResourceTree |
Lift t => Lift (ResourceTree t) |

data Piece typ Source

Constructors

Static String |
Dynamic typ |

Instances

Functor Piece |
Show typ => Show (Piece typ) |
Lift t => Lift (Piece t) |

data Dispatch typ Source

Constructors

Methods |

Fields

methodsMulti :: Maybe typ

  type of the multi piece at the end

methodsMethods :: [String]

  supported request methods

Subsite |

Fields

subsiteType :: typ
subsiteFunc :: String

Instances

Functor Dispatch |
Show typ => Show (Dispatch typ) |
Lift t => Lift (Dispatch t) |

type CheckOverlap = Bool Source

data FlatResource a Source

Constructors

FlatResource [(String, [(CheckOverlap, Piece a)])] String [(CheckOverlap, Piece a)] (Dispatch a) |

## Helper functions

resourceMulti :: Resource typ -> Maybe typSource

resourceTreePieces :: ResourceTree typ -> [(CheckOverlap, Piece typ)]Source

resourceTreeName :: ResourceTree typ -> String Source

flatten :: [ResourceTree a] -> [FlatResource a]Source

# Functions

## RenderRoute

mkRenderRouteInstance :: Type -> [ResourceTree Type] -> Q [Dec]Source

Generate the `RenderRoute` instance.

This includes both the `Route` associated type and the `renderRoute` method. This function uses both `mkRouteCons` and `mkRenderRouteClasses`.

mkRenderRouteInstance' :: Cxt -> Type -> [ResourceTree Type] -> Q [Dec]Source

A more general version of `mkRenderRouteInstance` which takes an additional context.

mkRouteCons :: [ResourceTree Type] -> ([Con], [Dec])Source

Generate the constructors of a route data type.

mkRenderRouteClauses :: [ResourceTree Type] -> Q [Clause]Source

Clauses for the `renderRoute` method.

## ParseRoute

mkParseRouteInstance :: Type -> [ResourceTree a] -> Q Dec Source

mkRouteAttrsInstance :: Type -> [ResourceTree a] -> Q Dec Source

## Dispatch

mkDispatchClause :: MkDispatchSettings -> [ResourceTree a] -> Q Clause Source

This function will generate a single clause that will address all your routing needs. It takes four arguments. The fourth (a list of `Resource`s) is self-explanatory. We'll discuss the first three. 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. This is the second argument of our function.

Finally, we need a way to decide which of the possible formats should the handler send the data out. Think of each URL holding an abstract object which has multiple representation (JSON, plain HTML etc). Each client might have a preference on which format it wants the abstract object in. For example, a javascript making a request (on behalf of a browser) might prefer a JSON object over a plain HTML file where as a user browsing with javascript disabled would want the page in HTML. The third argument is a function that converts the abstract object to the desired representation depending on the preferences sent by the client.

The typical values for the first three arguments are, ``yesodRunner`` for the first, ``yesodDispatch`` for the second and `fmap `chooseRep``.

data MkDispatchSettings Source

Constructors

MkDispatchSettings |

Fields

mdsRunHandler :: Q Exp
mdsSubDispatcher :: Q Exp
mdsGetPathInfo :: Q Exp
mdsSetPathInfo :: Q Exp
mdsMethod :: Q Exp
mds404 :: Q Exp
mds405 :: Q Exp
mdsGetHandler :: Maybe String -> String -> Q Exp

defaultGetHandler :: Maybe String -> String -> Q Exp Source