Pages are the building blocks of elm-spa.
Instead of importing this module, your project will have a Page
module with a much simpler type:
module Page exposing (Page, ...)
type Page model msg
This makes all the generic route
, effect
, and view
arguments disappear!
static : effect -> { view : view } -> Page shared route effect view () msg
A page that only needs to render a static view.
import Page
page : Page () Never
page =
Page.static
{ view = view
}
-- view : View Never
sandbox : effect -> { init : model, update : msg -> model -> model, view : model -> view } -> Page shared route effect view model msg
A page that can keep track of application state.
( Inspired by Browser.sandbox
)
import Page
page : Page Model Msg
page =
Page.sandbox
{ init = init
, update = update
, view = view
}
-- init : Model
-- update : Msg -> Model -> Model
-- view : Model -> View Msg
element : (Platform.Cmd.Cmd msg -> effect) -> { init : ( model, Platform.Cmd.Cmd msg ), update : msg -> model -> ( model, Platform.Cmd.Cmd msg ), view : model -> view, subscriptions : model -> Platform.Sub.Sub msg } -> Page shared route effect view model msg
A page that can handle effects like HTTP requests or subscriptions.
( Inspired by Browser.element
)
import Page
page : Page Model Msg
page =
Page.element
{ init = init
, update = update
, view = view
, subscriptions = subscriptions
}
-- init : ( Model, Cmd Msg )
-- update : Msg -> Model -> ( Model, Cmd Msg )
-- view : Model -> View Msg
-- subscriptions : Model -> Sub Msg
advanced : { init : ( model, effect ), update : msg -> model -> ( model, effect ), view : model -> view, subscriptions : model -> Platform.Sub.Sub msg } -> Page shared route effect view model msg
A page that can handles custom effects like sending a Shared.Msg
or other general user-defined effects.
import Effect
import Page
page : Page Model Msg
page =
Page.advanced
{ init = init
, update = update
, view = view
, subscriptions = subscriptions
}
-- init : ( Model, Effect Msg )
-- update : Msg -> Model -> ( Model, Effect Msg )
-- view : Model -> View Msg
-- subscriptions : Model -> Sub Msg
Actions to take when a user visits a protected
page
import Gen.Route as Route exposing (Route)
beforeProtectedInit : Shared.Model -> Request () -> Protected User Route
beforeProtectedInit shared _ =
case shared.user of
Just user ->
Provide user
Nothing ->
RedirectTo Route.SignIn
protected : { effectNone : effect, fromCmd : Platform.Cmd.Cmd msg -> effect, beforeInit : shared -> Request route () -> Protected user route } -> { static : (user -> { view : view }) -> Page shared route effect view () msg, sandbox : (user -> { init : model, update : msg -> model -> model, view : model -> view }) -> Page shared route effect view model msg, element : (user -> { init : ( model, Platform.Cmd.Cmd msg ), update : msg -> model -> ( model, Platform.Cmd.Cmd msg ), view : model -> view, subscriptions : model -> Platform.Sub.Sub msg }) -> Page shared route effect view model msg, advanced : (user -> { init : ( model, effect ), update : msg -> model -> ( model, effect ), view : model -> view, subscriptions : model -> Platform.Sub.Sub msg }) -> Page shared route effect view model msg }
Prefixing any of the four functions above with protected
will guarantee that the page has access to a user. Here's an example with sandbox
:
-- before
Page.sandbox
{ init = init
, update = update
, view = view
}
-- after
Page.protected.sandbox
(\user ->
{ init = init
, update = update
, view = view
}
)
-- other functions have same API
init : Model
update : Msg -> Model -> Model
view : Model -> View Msg
{ init : params -> shared -> Url -> Browser.Navigation.Key -> ( pagesModel
, effect )
, update : params -> msg -> model -> shared -> Url -> Browser.Navigation.Key -> ( pagesModel
, effect )
, view : params -> model -> shared -> Url -> Browser.Navigation.Key -> pagesView
, subscriptions : params -> model -> shared -> Url -> Browser.Navigation.Key -> Platform.Sub.Sub pagesMsg
}
A convenient function for use within generated code. Makes it easy to handle init
, update
, view
, and subscriptions
for each page!
bundle : { redirecting : { model : pagesModel, view : pagesView }, toRoute : Url -> route, toUrl : route -> String, fromCmd : Platform.Cmd.Cmd any -> pagesEffect, mapEffect : effect -> pagesEffect, mapView : view -> pagesView, page : shared -> Request route params -> Page shared route effect view model msg, toModel : params -> model -> pagesModel, toMsg : msg -> pagesMsg } -> Bundle params model msg shared pagesEffect pagesModel pagesMsg pagesView
This function is used by the generated code to connect your pages together.
It's big, spooky, and makes writing elm-spa pages really nice!