yesod-core-0.9.4.1: Creation of type-safe, RESTful web applications.

Yesod.Handler

Contents

- Type families
- Handler monad
  - Read information from handler
- Special responses
  - Redirecting
  - Errors
  - Short-circuit responses.
- Setting headers
  - Content caching and expiration
- Session
  - Ultimate destination
  - Messages
- Helpers for specific content
  - Hamlet
  - Misc
- i18n
- Per-request caching
- Internal Yesod

Synopsis

- type family Route a
- class YesodSubRoute s y where
  - fromSubRoute :: s -> y -> Route s -> Route y
- type GHandler sub master = GGHandler sub master (Iteratee ByteString IO)
- type GGHandler sub master = ReaderT (HandlerData sub master)
- getYesod :: Monad m => GGHandler sub master m master
- getYesodSub :: Monad m => GGHandler sub master m sub
- getUrlRender :: Monad m => GGHandler sub master m (Route master -> Text)
- getUrlRenderParams :: Monad m => GGHandler sub master m (Route master -> [(Text, Text)] -> Text)
- getCurrentRoute :: Monad m => GGHandler sub master m (Maybe (Route sub))
- getRouteToMaster :: Monad m => GGHandler sub master m (Route sub -> Route master)
- getRequest :: Monad mo => GGHandler s m mo Request
- waiRequest :: Monad mo => GGHandler sub master mo Request
- runRequestBody :: GHandler s m RequestBodyContents
- data RedirectType
  - = RedirectPermanent
  - | RedirectTemporary
  - | RedirectSeeOther
- redirect :: MonadIO mo => RedirectType -> Route master -> GGHandler sub master mo a
- redirectParams :: MonadIO mo => RedirectType -> Route master -> [(Text, Text)] -> GGHandler sub master mo a
- redirectString :: MonadIO mo => RedirectType -> Text -> GGHandler sub master mo a
- redirectText :: MonadIO mo => RedirectType -> Text -> GGHandler sub master mo a
- redirectToPost :: MonadIO mo => Route master -> GGHandler sub master mo a
- notFound :: Failure ErrorResponse m => m a
- badMethod :: MonadIO mo => GGHandler s m mo a
- permissionDenied :: Failure ErrorResponse m => Text -> m a
- permissionDeniedI :: (RenderMessage y msg, MonadIO mo) => msg -> GGHandler s y mo a
- invalidArgs :: Failure ErrorResponse m => [Text] -> m a
- invalidArgsI :: (RenderMessage y msg, MonadIO mo) => [msg] -> GGHandler s y mo a
- sendFile :: MonadIO mo => ContentType -> FilePath -> GGHandler sub master mo a
- sendFilePart :: MonadIO mo => ContentType -> FilePath -> Integer -> Integer -> GGHandler sub master mo a
- sendResponse :: (MonadIO mo, HasReps c) => c -> GGHandler sub master mo a
- sendResponseStatus :: (MonadIO mo, HasReps c) => Status -> c -> GGHandler s m mo a
- sendResponseCreated :: MonadIO mo => Route m -> GGHandler s m mo a
- sendWaiResponse :: MonadIO mo => Response -> GGHandler s m mo b
- setCookie :: MonadIO mo => Int -> Ascii -> Ascii -> GGHandler sub master mo ()
- deleteCookie :: MonadIO mo => Ascii -> GGHandler sub master mo ()
- setHeader :: MonadIO mo => CI Ascii -> Ascii -> GGHandler sub master mo ()
- setLanguage :: MonadIO mo => Text -> GGHandler sub master mo ()
- cacheSeconds :: MonadIO mo => Int -> GGHandler s m mo ()
- neverExpires :: MonadIO mo => GGHandler s m mo ()
- alreadyExpired :: MonadIO mo => GGHandler s m mo ()
- expiresAt :: MonadIO mo => UTCTime -> GGHandler s m mo ()
- type SessionMap = Map Text Text
- lookupSession :: MonadIO mo => Text -> GGHandler s m mo (Maybe Text)
- getSession :: MonadIO mo => GGHandler s m mo SessionMap
- setSession :: MonadIO mo => Text -> Text -> GGHandler sub master mo ()
- deleteSession :: MonadIO mo => Text -> GGHandler sub master mo ()
- setUltDest :: MonadIO mo => Route master -> GGHandler sub master mo ()
- setUltDestString :: MonadIO mo => Text -> GGHandler sub master mo ()
- setUltDestText :: MonadIO mo => Text -> GGHandler sub master mo ()
- setUltDest' :: MonadIO mo => GGHandler sub master mo ()
- setUltDestReferer :: MonadIO mo => GGHandler sub master mo ()
- redirectUltDest :: MonadIO mo => RedirectType -> Route master -> GGHandler sub master mo a
- clearUltDest :: MonadIO mo => GGHandler sub master mo ()
- setMessage :: MonadIO mo => Html -> GGHandler sub master mo ()
- setMessageI :: (RenderMessage y msg, MonadIO mo) => msg -> GGHandler sub y mo ()
- getMessage :: MonadIO mo => GGHandler sub master mo (Maybe Html)
- hamletToContent :: Monad mo => HtmlUrl (Route master) -> GGHandler sub master mo Content
- hamletToRepHtml :: Monad mo => HtmlUrl (Route master) -> GGHandler sub master mo RepHtml
- newIdent :: MonadIO mo => GGHandler sub master mo String
- liftIOHandler :: MonadIO mo => GGHandler sub master IO a -> GGHandler sub master mo a
- getMessageRender :: (Monad mo, RenderMessage master message) => GGHandler s master mo (message -> Text)
- data CacheKey a
- mkCacheKey :: Q Exp
- cacheLookup :: MonadIO mo => CacheKey a -> GGHandler sub master mo (Maybe a)
- cacheInsert :: MonadIO mo => CacheKey a -> a -> GGHandler sub master mo ()
- cacheDelete :: MonadIO mo => CacheKey a -> GGHandler sub master mo ()
- runHandler :: HasReps c => GHandler sub master c -> (Route master -> [(Text, Text)] -> Text) -> Maybe (Route sub) -> (Route sub -> Route master) -> master -> sub -> YesodApp
- newtype YesodApp = YesodApp {
  - unYesodApp :: (ErrorResponse -> YesodApp) -> Request -> [ContentType] -> SessionMap -> Iteratee ByteString IO YesodAppResult
  }
- runSubsiteGetter :: SubsiteGetter g m s => g -> m s
- toMasterHandler :: (Route sub -> Route master) -> (master -> sub) -> Route sub -> GGHandler sub master mo a -> GGHandler sub' master mo a
- toMasterHandlerDyn :: Monad mo => (Route sub -> Route master) -> GGHandler sub' master mo sub -> Route sub -> GGHandler sub master mo a -> GGHandler sub' master mo a
- toMasterHandlerMaybe :: (Route sub -> Route master) -> (master -> sub) -> Maybe (Route sub) -> GGHandler sub master mo a -> GGHandler sub' master mo a
- localNoCurrent :: Monad mo => GGHandler s m mo a -> GGHandler s m mo a
- data HandlerData sub master
- data ErrorResponse
  - = NotFound
  - | InternalError Text
  - | InvalidArgs [Text]
  - | PermissionDenied Text
  - | BadMethod Method
- data YesodAppResult
  - = YARWai Response
  - | YARPlain Status [Header] ContentType Content SessionMap
- handlerToYAR :: (HasReps a, HasReps b) => m -> s -> (Route s -> Route m) -> (Route m -> [(Text, Text)] -> Text) -> (ErrorResponse -> GHandler s m a) -> Request -> Maybe (Route s) -> SessionMap -> GHandler s m b -> Iteratee ByteString IO YesodAppResult
- yarToResponse :: HeaderRenderer -> YesodAppResult -> Response
- headerToPair :: ByteString -> (Int -> UTCTime) -> Header -> (CI Ascii, Ascii)

# Type families

type family Route a

The type-safe URLs associated with a site argument.

class YesodSubRoute s y where

Methods

fromSubRoute :: s -> y -> Route s -> Route y

# Handler monad

type GHandler sub master = GGHandler sub master (Iteratee ByteString IO)

type GGHandler sub master = ReaderT (HandlerData sub master)

A generic handler monad, which can have a different subsite and master site. This monad is a combination of `ReaderT` for basic arguments, a `WriterT` for headers and session, and an `MEitherT` monad for handling special responses. It is declared as a newtype to make compiler errors more readable.

## Read information from handler

getYesod :: Monad m => GGHandler sub master m master

Get the master site appliation argument.

getYesodSub :: Monad m => GGHandler sub master m sub

Get the sub application argument.

getUrlRender :: Monad m => GGHandler sub master m (Route master -> Text)

Get the URL rendering function.

getUrlRenderParams :: Monad m => GGHandler sub master m (Route master -> [(Text, Text)] -> Text)

The URL rendering function with query-string parameters.

getCurrentRoute :: Monad m => GGHandler sub master m (Maybe (Route sub))

Get the route requested by the user. If this is a 404 response- where the user requested an invalid route- this function will return `Nothing`.

getRouteToMaster :: Monad m => GGHandler sub master m (Route sub -> Route master)

Get the function to promote a route for a subsite to a route for the master site.

getRequest :: Monad mo => GGHandler s m mo Request

waiRequest :: Monad mo => GGHandler sub master mo Request

Get the request's `Request` value.

runRequestBody :: GHandler s m RequestBodyContents

# Special responses

## Redirecting

data RedirectType

Different types of redirects.

Constructors

RedirectPermanent |
RedirectTemporary |
RedirectSeeOther |

Instances

Eq RedirectType |
Show RedirectType |

redirect :: MonadIO mo => RedirectType -> Route master -> GGHandler sub master mo a

Redirect to the given route.

redirectParams :: MonadIO mo => RedirectType -> Route master -> [(Text, Text)] -> GGHandler sub master mo a

Redirects to the given route with the associated query-string parameters.

redirectString :: MonadIO mo => RedirectType -> Text -> GGHandler sub master mo a

redirectText :: MonadIO mo => RedirectType -> Text -> GGHandler sub master mo a

Redirect to the given URL.

redirectToPost :: MonadIO mo => Route master -> GGHandler sub master mo a

Redirect to a POST resource.

This is not technically a redirect; instead, it returns an HTML page with a POST form, and some Javascript to automatically submit the form. This can be useful when you need to post a plain link somewhere that needs to cause changes on the server.

## Errors

notFound :: Failure ErrorResponse m => m a

Return a 404 not found page. Also denotes no handler available.

badMethod :: MonadIO mo => GGHandler s m mo a

Return a 405 method not supported page.

permissionDenied :: Failure ErrorResponse m => Text -> m a

Return a 403 permission denied page.

permissionDeniedI :: (RenderMessage y msg, MonadIO mo) => msg -> GGHandler s y mo a

Return a 403 permission denied page.

invalidArgs :: Failure ErrorResponse m => [Text] -> m a

Return a 400 invalid arguments page.

invalidArgsI :: (RenderMessage y msg, MonadIO mo) => [msg] -> GGHandler s y mo a

Return a 400 invalid arguments page.

## Short-circuit responses.

sendFile :: MonadIO mo => ContentType -> FilePath -> GGHandler sub master mo a

Bypass remaining handler code and output the given file.

For some backends, this is more efficient than reading in the file to memory, since they can optimize file sending via a system call to sendfile.

sendFilePart

Arguments

:: MonadIO mo |
=> ContentType |
-> FilePath |
-> Integer | offset
-> Integer | count
-> GGHandler sub master mo a |

Same as `sendFile`, but only sends part of a file.

sendResponse :: (MonadIO mo, HasReps c) => c -> GGHandler sub master mo a

Bypass remaining handler code and output the given content with a 200 status code.

sendResponseStatus :: (MonadIO mo, HasReps c) => Status -> c -> GGHandler s m mo a

Bypass remaining handler code and output the given content with the given status code.

sendResponseCreated :: MonadIO mo => Route m -> GGHandler s m mo a

Send a 201 Created response with the given route as the Location response header.

sendWaiResponse :: MonadIO mo => Response -> GGHandler s m mo b

Send a `Response`. Please note: this function is rarely necessary, and will disregard any changes to response headers and session that you have already specified. This function short-circuits. It should be considered only for very specific needs. If you are not sure if you need it, you don't.

# Setting headers

setCookie

Arguments

:: MonadIO mo |
=> Int | minutes to timeout
-> Ascii | key
-> Ascii | value
-> GGHandler sub master mo () |

Set the cookie on the client.

deleteCookie :: MonadIO mo => Ascii -> GGHandler sub master mo ()

Unset the cookie on the client.

setHeader :: MonadIO mo => CI Ascii -> Ascii -> GGHandler sub master mo ()

Set an arbitrary response header.

setLanguage :: MonadIO mo => Text -> GGHandler sub master mo ()

Set the language in the user session. Will show up in `languages` on the next request.

## Content caching and expiration

cacheSeconds :: MonadIO mo => Int -> GGHandler s m mo ()

Set the Cache-Control header to indicate this response should be cached for the given number of seconds.

neverExpires :: MonadIO mo => GGHandler s m mo ()

Set the Expires header to some date in 2037. In other words, this content is never (realistically) expired.

alreadyExpired :: MonadIO mo => GGHandler s m mo ()

Set an Expires header in the past, meaning this content should not be cached.

expiresAt :: MonadIO mo => UTCTime -> GGHandler s m mo ()

Set an Expires header to the given date.

# Session

type SessionMap = Map Text Text

lookupSession :: MonadIO mo => Text -> GGHandler s m mo (Maybe Text)

Lookup for session data.

getSession :: MonadIO mo => GGHandler s m mo SessionMap

Get all session variables.

setSession

Arguments

:: MonadIO mo |
=> Text | key
-> Text | value
-> GGHandler sub master mo () |

Set a variable in the user's session.

The session is handled by the clientsession package: it sets an encrypted and hashed cookie on the client. This ensures that all data is secure and not tampered with.

deleteSession :: MonadIO mo => Text -> GGHandler sub master mo ()

Unsets a session variable. See `setSession`.

## Ultimate destination

setUltDest :: MonadIO mo => Route master -> GGHandler sub master mo ()

Sets the ultimate destination variable to the given route.

An ultimate destination is stored in the user session and can be loaded later by `redirectUltDest`.

setUltDestString :: MonadIO mo => Text -> GGHandler sub master mo ()

setUltDestText :: MonadIO mo => Text -> GGHandler sub master mo ()

Same as `setUltDest`, but use the given string.

setUltDest' :: MonadIO mo => GGHandler sub master mo ()

Same as `setUltDest`, but uses the current page.

If this is a 404 handler, there is no current page, and then this call does nothing.

setUltDestReferer :: MonadIO mo => GGHandler sub master mo ()

Sets the ultimate destination to the referer request header, if present.

This function will not overwrite an existing ultdest.

redirectUltDest

Arguments

:: MonadIO mo |
=> RedirectType |
-> Route master | default destination if nothing in session
-> GGHandler sub master mo a |

Redirect to the ultimate destination in the user's session. Clear the value from the session.

The ultimate destination is set with `setUltDest`.

clearUltDest :: MonadIO mo => GGHandler sub master mo ()

Remove a previously set ultimate destination. See `setUltDest`.

## Messages

setMessage :: MonadIO mo => Html -> GGHandler sub master mo ()

Sets a message in the user's session.

See `getMessage`.

setMessageI :: (RenderMessage y msg, MonadIO mo) => msg -> GGHandler sub y mo ()

Sets a message in the user's session.

See `getMessage`.

getMessage :: MonadIO mo => GGHandler sub master mo (Maybe Html)

Gets the message in the user's session, if available, and then clears the variable.

See `setMessage`.

# Helpers for specific content

## Hamlet

hamletToContent :: Monad mo => HtmlUrl (Route master) -> GGHandler sub master mo Content

Converts the given Hamlet template into `Content`, which can be used in a Yesod `Response`.

hamletToRepHtml :: Monad mo => HtmlUrl (Route master) -> GGHandler sub master mo RepHtml

Wraps the `Content` generated by `hamletToContent` in a `RepHtml`.

## Misc

newIdent :: MonadIO mo => GGHandler sub master mo String

Get a unique identifier.

liftIOHandler :: MonadIO mo => GGHandler sub master IO a -> GGHandler sub master mo a

# i18n

getMessageRender :: (Monad mo, RenderMessage master message) => GGHandler s master mo (message -> Text)

# Per-request caching

data CacheKey a

mkCacheKey :: Q Exp

Generate a new `CacheKey`. Be sure to give a full type signature.

cacheLookup :: MonadIO mo => CacheKey a -> GGHandler sub master mo (Maybe a)

cacheInsert :: MonadIO mo => CacheKey a -> a -> GGHandler sub master mo ()

cacheDelete :: MonadIO mo => CacheKey a -> GGHandler sub master mo ()

# Internal Yesod

runHandler :: HasReps c => GHandler sub master c -> (Route master -> [(Text, Text)] -> Text) -> Maybe (Route sub) -> (Route sub -> Route master) -> master -> sub -> YesodApp

Function used internally by Yesod in the process of converting a `GHandler` into an `Application`. Should not be needed by users.

newtype YesodApp

An extension of the basic WAI `Application` datatype to provide extra features needed by Yesod. Users should never need to use this directly, as the `GHandler` monad and template haskell code should hide it away.

Constructors

YesodApp |

Fields

unYesodApp :: (ErrorResponse -> YesodApp) -> Request -> [ContentType] -> SessionMap -> Iteratee ByteString IO YesodAppResult

runSubsiteGetter :: SubsiteGetter g m s => g -> m s

toMasterHandler :: (Route sub -> Route master) -> (master -> sub) -> Route sub -> GGHandler sub master mo a -> GGHandler sub' master mo a

Used internally for promoting subsite handler functions to master site handler functions. Should not be needed by users.

toMasterHandlerDyn :: Monad mo => (Route sub -> Route master) -> GGHandler sub' master mo sub -> Route sub -> GGHandler sub master mo a -> GGHandler sub' master mo a

toMasterHandlerMaybe :: (Route sub -> Route master) -> (master -> sub) -> Maybe (Route sub) -> GGHandler sub master mo a -> GGHandler sub' master mo a

localNoCurrent :: Monad mo => GGHandler s m mo a -> GGHandler s m mo a

data HandlerData sub master

Instances

ToWidget sub master (GWidget sub master ()) |
MonadIO monad => Failure ErrorResponse (GGHandler sub master monad) |
master ~ master' => SubsiteGetter (master -> sub) (GHandler anySub master') sub |
(anySub ~ anySub', master ~ master') => SubsiteGetter (GHandler anySub master sub) (GHandler anySub' master') sub |

data ErrorResponse

Responses to indicate some form of an error occurred. These are different from `SpecialResponse` in that they allow for custom error pages.

Constructors

NotFound |
InternalError Text |
InvalidArgs [Text] |
PermissionDenied Text |
BadMethod Method |

Instances

Eq ErrorResponse |
Show ErrorResponse |
Typeable ErrorResponse |
Exception ErrorResponse |
MonadIO monad => Failure ErrorResponse (GGHandler sub master monad) |

data YesodAppResult

Constructors

YARWai Response |
YARPlain Status [Header] ContentType Content SessionMap |

handlerToYAR

Arguments

:: (HasReps a, HasReps b) |
=> m | master site foundation
-> s | sub site foundation
-> (Route s -> Route m) |
-> (Route m -> [(Text, Text)] -> Text) |
-> (ErrorResponse -> GHandler s m a) |
-> Request |
-> Maybe (Route s) |
-> SessionMap |
-> GHandler s m b |
-> Iteratee ByteString IO YesodAppResult |

yarToResponse :: HeaderRenderer -> YesodAppResult -> Response

headerToPair

Arguments

:: ByteString | cookie path
-> (Int -> UTCTime) | minutes -> expiration time
-> Header |
-> (CI Ascii, Ascii) |

Convert Header to a key/value pair.