This library helps with routing in elm applications.
type alias Config msg route routeMsg =
{ parser : Parser (route -> route) route
, update : routeMsg -> ( route, Cmd routeMsg )
, view : route -> List (Html routeMsg)
, message : Msg routeMsg -> msg
, subscriptions : route -> Sub routeMsg
, notFound : Url -> List (Html msg)
, routeTitle : route -> Maybe String
, onUrlChanged : Maybe (Url -> msg)
}Two static pages with no model and one with a model, message, and subscription:
type Route
= Home
| About
| Contact Contact.Model
type Msg
= ContactMsg Contact.Model Contact.MsgYou will need to provide the parser like:
parser : Parser (Route -> a) a
parser =
Parser.oneOf
[ Router.mapRoute Parser.top Home
, Router.mapRoute (Parser.s "about") About
, Router.mapRoute (Parser.s "contact") <| Contact <| Contact.init "" ""
]An update function like:
update : Msg -> ( Route, Cmd Msg )
update message =
case message of
ContactMsg model msg ->
Contact.update msg model
|> Router.mapUpdate Contact ContactMsgA view function like:
view : Route -> List (Html Msg)
view route =
case route of
Home ->
Home.view
About ->
About.view
Contact mdl ->
Contact.view mdl
|> Router.mapMsg (ContactMsg mdl)A subscriptions function like:
subscriptions : Route -> Sub Msg
subscriptions route =
case route of
Home ->
Sub.none
About ->
Sub.none
Contact mdl ->
Contact.subscriptions mdl
|> Sub.map (ContactMsg mdl)A title function like:
title : Route -> Maybe String
title route =
case route of
Home ->
Nothing
About ->
Just "About"
Contact _ ->
Just "Contact"And a notFound function like:
where
import Html as H exposing (Html)
import Url exposing (Url)
notFound : Url -> List (Html msg)
notFound url =
[ H.h1 [] [ H.text "Page not found!" ]
, H.h3 [] [ H.text <| Url.toString url ]
]build a Config like:
config : Config App.Msg Route Route.Msg
config =
{ parser = Route.parser
, update = Route.update
, view = Route.view
, message = App.Router
, subscriptions = Route.subscriptions
, notFound = Route.notFound
, routeTitle = Route.title
, onUrlChanged = Nothing
}where:
App.Msg is your application MsgApp.Router is the message in your application Msg created for the RouterAnd use the config created in your application like:
Assuming:
import Route exposing (Route)
import Router
type alias Model =
{ router : Router Route }
type Msg
= Router (Router.Msg Route.Msg)then :
init : () -> Url -> Key -> ( Model, Cmd Msg )
init _ url key =
let
(router, cmd) =
Router.init config url key
in
( Model router, cmd )
update : Msg -> Model -> ( Model, Cmd Msg )
update message ({ router } as model) =
case message of
Router msg ->
let
( newRouter, cmd ) =
Router.update config msg router
in
( { model | router = newRouter }, cmd )
view : Model -> Document Msg
view { router } =
{ title = Router.title router "My app"
, body =
[ H.nav []
[ H.a [ A.href "/" ] [ H.text "Home" ]
, H.a [ A.href "/about" ] [ H.text "About" ]
, H.a [ A.href "/contact" ] [ H.text "Contact" ]
, H.a [ A.href "/something_not_routed" ] [ H.text "404" ]
]
, H.main_ [] (Router.view config router)
]
}
subscriptions : Model -> Sub Msg
subscriptions { router } =
Router.subscriptions config router
main : Program () Model Msg
main =
Browser.application
{ init = init
, update = update
, view = view
, subscriptions = subscriptions
, onUrlChange = Router.onUrlChange config
, onUrlRequest = Router.onUrlRequest config
}