| Copyright | (c) digitally induced GmbH 2020 |
|---|---|
| Safe Haskell | None |
| Language | GHC2021 |
IHP.Controller.Context
Contents
Description
Re-exports from ihp-context and adds IHP-specific HasField instances for accessing the WAI Request and FrameworkConfig.
Synopsis
- data ControllerContext
- = ControllerContext {
- customFieldsRef :: IORef TMap
- | FrozenControllerContext {
- customFields :: TMap
- = ControllerContext {
- newControllerContext :: (?request :: Request) => IO ControllerContext
- freeze :: ControllerContext -> IO ControllerContext
- unfreeze :: ControllerContext -> IO ControllerContext
- putContext :: (?context :: ControllerContext, Typeable value) => value -> IO ()
- fromContext :: (?context :: ControllerContext, Typeable value) => IO value
- maybeFromContext :: (?context :: ControllerContext, Typeable value) => IO (Maybe value)
- fromFrozenContext :: (?context :: ControllerContext, Typeable value) => value
- maybeFromFrozenContext :: (?context :: ControllerContext, Typeable value) => Maybe value
- newtype ActionType = ActionType TypeRep
Documentation
data ControllerContext Source #
A container storing useful data along the request lifecycle, such as the request, the current user, set current view layout, flash messages, ...
The controller context is usually accessed via the ?context variable. It's available inside the action and the view. Think of it as a key-value-map where the key is the type of the value.
You can store information inside the context using putContext:
>>>newtype CurrentLayout = CurrentLayout Html>>>>>>?context <- newControllerContext>>>putContext (CurrentLayout layout)
Inside an action you can access the values using fromContext:
>>>(CurrentLayout layout) <- fromContext
You can freeze the context and then access values without being inside an IO context (like inside views which are pure):
Call freeze inside an IO part:
>>>?context <- freeze ?context
(freeze is automatically called by IHP before rendering a view, so usually you don't need to call it manually)
Then use the frozen context from your pure code like this:
>>>let (CurrentLayout layout) = fromFrozenContext in ...
The context is initially created before a action is going to be executed. Its life cycle looks like this:
newControllerContext: The new controller context is created- The
runActionWithNewContextfills in a few default values: The current?applicationand also the Flash Messages to be rendered in the to-be-generated response. initContext: The initContext function of theInitControllerContext WebApplication(inside your FrontController.hs) is called. There application-specific context can be provided. Usually this is the current user and the default layout.beforeAction: Here the context could also be modified. E.g. the layout could be overriden here for the whole controller.action ..: The action itself.- Freezing: Before rendering the response, the container is frozen. Frozen means that all previously mutable fields become immutable.
- View Rendering: The frozen container is now used inside the view and layout to display information such as the current user or flash messages
Constructors
| ControllerContext | |
Fields
| |
| FrozenControllerContext | |
Fields
| |
Instances
| HasField "frameworkConfig" ControllerContext FrameworkConfig Source # | Access frameworkConfig via the request vault |
Defined in IHP.Controller.Context Methods | |
| HasField "logger" ControllerContext Logger Source # | Access logger from the request vault |
Defined in IHP.Controller.Context Methods getField :: ControllerContext -> Logger # | |
| HasField "request" ControllerContext Request Source # | Access request from the TMap This allows |
Defined in IHP.Controller.Context Methods getField :: ControllerContext -> Request # | |
newControllerContext :: (?request :: Request) => IO ControllerContext Source #
Creates a new controller context with the WAI Request stored in the TMap
This version stores the Request in the TMap so it can be retrieved via the HasField instance.
freeze :: ControllerContext -> IO ControllerContext Source #
After freezing a container you can access its values from pure non-IO code by using fromFrozenContext
Calls to putContext will throw an exception after it's frozen.
unfreeze :: ControllerContext -> IO ControllerContext Source #
Returns an unfrozen version of the controller context that can be modified again
This is used together with freeze by e.g. AutoRefresh to make an immutable copy of the current controller context state
putContext :: (?context :: ControllerContext, Typeable value) => value -> IO () Source #
Puts a value into the context
Throws an exception if the context is already frozen.
fromContext :: (?context :: ControllerContext, Typeable value) => IO value Source #
Returns a value from the current controller context
Throws an exception if there is no value with the type inside the context
Example: Read the current user from the context
>>>user <- fromContext @User
maybeFromContext :: (?context :: ControllerContext, Typeable value) => IO (Maybe value) Source #
Returns a value from the current controller context, or Nothing if not found
fromFrozenContext :: (?context :: ControllerContext, Typeable value) => value Source #
Returns a value from the current controller context. Requires the context to be frozen.
Example: Read the current user from the context
>>>let user = fromFrozenContext @User
maybeFromFrozenContext :: (?context :: ControllerContext, Typeable value) => Maybe value Source #
Returns a value from a frozen controller context, or Nothing if not found
newtype ActionType Source #
Used to track the current action type
Constructors
| ActionType TypeRep |
Instances
| HasField "actionType" Request ActionType Source # | |
Defined in IHP.ActionType Methods getField :: Request -> ActionType # | |
Orphan instances
| HasField "frameworkConfig" ControllerContext FrameworkConfig Source # | Access frameworkConfig via the request vault |
Methods | |
| HasField "logger" ControllerContext Logger Source # | Access logger from the request vault |
Methods getField :: ControllerContext -> Logger # | |
| HasField "request" ControllerContext Request Source # | Access request from the TMap This allows |
Methods getField :: ControllerContext -> Request # | |