Note: although we provide a MonadBaseControl instance, lifted-base's
fork function is incompatible with the underlying ResourceT system.
Instead, if you must fork a separate thread, you should use
resourceForkIO.

Using fork usually leads to an exception that says
"Control.Monad.Trans.Resource.register': The mutable state is being accessed
after cleanup. Please contact the maintainers."

Convenience functions

Languages are determined based on the following three (in descending order
of preference):

The _LANG get parameter.

The _LANG cookie.

The _LANG user session variable.

Accept-Language HTTP header.

Yesod will seek the first language from the returned list matched with languages supporting by your application. This language will be used to render i18n templates.
If a matching language is not found the default language will be used.

Streaming

Note that, for ease of use, the underlying monad is a HandlerT. This
implies that you can run any HandlerT action. However, since a streaming
response occurs after the response headers have already been sent, some
actions make no sense here. For example: short-circuit responses, setting
headers, changing status codes, etc.

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.

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.

Send a raw response. This is used for cases such as WebSockets. Requires
WAI 2.1 or later, and a web server which supports raw responses (e.g.,
Warp).

Since 1.2.7

Different representations

HTTP allows content negotation to determine what representation of data
you would like to use. The most common example of this is providing both a
user-facing HTML page and an API facing JSON response from the same URL. The
means of achieving this is the Accept HTTP header, which provides a list of
content types the client will accept, sorted by preference.

By using selectRep and provideRep, you can provide a number of different
representations, e.g.:

Same as provideRep, but instead of determining the content type from the
type of the value itself, you provide the content type separately. This can
be a convenience instead of creating newtype wrappers for uncommonly used
content types.

Another use case for this function is creating a stream of
server-sent events using GHandler actions (see
yesod-eventsource).

Most of the environment from the outer GHandler is preserved
on the inner GHandler, however:

The request body is cleared (otherwise it would be very
difficult to prevent huge memory leaks).

The cache is cleared (see CacheKey).

Changes to the response made inside the inner GHandler are
ignored (e.g., session variables, cookies, response headers).
This allows the inner GHandler to outlive the outer
GHandler (e.g., on the forkIO example above, a response
may be sent to the client without killing the new thread).

i18n

Per-request caching

Use a per-request cache to avoid performing the same action multiple
times. Note that values are stored by their type. Therefore, you should use
newtype wrappers to distinguish logically different types.