"Layout" module
Every layout file imports a Layout
module. This module provides the Layout
type and the Layout.new
. This section documents all the functions exposed, and what they are used for.
Layout
This type represents a layout, and contains four parameters.
type Layout parentProps model msg contentMsg
Here's a breakdown of each parameter:
parentProps
– When working with Nested layouts, this parameter is the parent layout's settings. For top-level layouts that aren't nested, this value is always()
.model
– Represents the state of the layoutmsg
– Represents the messages the layout can sendcontentMsg
– Because layouts can embed other HTML, this common variable allows us to combine that HTML together. We describe this in more detail in the "Understanding layouts" section above!
Layout.new
Create a new layout, providing functions to describe how to initialize, update, and view your page.
Layout.new :
{ init : () -> ( Model, Effect Msg )
, update : Msg -> Model -> ( Model, Effect Msg )
, view :
{ model : Model
, toContentMsg : Msg -> contentMsg
, content : View contentMsg
}
-> View contentMsg
, subscriptions : Model -> Sub Msg
}
-> Layout () Model Msg contentMsg
Layout.withParentProps
This is required for nested layouts, which are embedded within other parent layouts. Use this function to provide settings that are required by the parent layout.
Type definition
Layout.withParentProps :
parentProps
-> Layout () Model Msg contentMsg
-> Layout parentProps Model Msg contentMsg
Usage example
module Layouts.Sidebar.Header exposing (..)
-- ...
layout :
Props
-> Shared.Model
-> Route ()
-> Layout Layouts.Sidebar.Props Model Msg contentMsg
layout props shared route =
Layout.new { ... }
|> Layout.withParentProps
{ user = settings.user
}
Layout.withOnUrlChanged
The Layout.withOnUrlChanged
function allows a layout to respond to any changes in the URL that don't involve navigating to another layout.
For example, let's imagine we have the following 3 pages in our application:
Page | Layout |
---|---|
Pages.Dashboard | Layouts.Sidebar |
Pages.Settings | Layouts.Sidebar |
Pages.SignIn | None |
If we navigated from /dashboard
to /settings
, then our UrlChanged
message would be sent to our Layouts.Sidebar
module.
If we navigated from /dashboard
to /dashboard?code=123
, we would also receive a message. However, if we navigated to the /sign-in
route, we would not receive a message, because the "Sign in" page doesn't use this layout.
Use the Layout.withOnUrlChanged
whenever you want to know if the current page, query parameters, or hash has changed within a layout.
Type definition
Layout.withOnUrlChanged :
({ from : Route (), to : Route () } -> Msg)
-> Layout () Model Msg
-> Layout () Model Msg
Usage example
module Layouts.Sidebar exposing (Props, Model, Msg, layout)
import Layout exposing (Layout)
-- ...
layout : Props -> Shared.Model -> Route () -> Layout () Model Msg
layout props shared route =
Layout.new
{ init = init
, update = update
, view = view
, subscriptions = subscriptions
}
|> Layout.withOnUrlChanged UrlChanged
-- ...
type Msg
= ...
| UrlChanged { from : Route (), to : Route () }
update : Msg -> Model -> ( Model, Effect Msg )
update msg model =
case msg of
UrlChanged { from, to } ->
( model, Effect.none )
...
Note: In the Route section, you'll learn about the Route
type and how it stores URL information.