Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Elm Routing: One Approach

Elm Routing: One Approach

Brian Hicks

January 04, 2016
Tweet

More Decks by Brian Hicks

Other Decks in Programming

Transcript

  1. Hello I'm Brian Hicks I do computer stuff [email protected] //

    @brianhicks Brian Hicks, St. Louis Elm Meetup 2
  2. Overview — Two modules: Routing and Mantl — They're complementary,

    and slightly coupled... we'll see why. — This is one way to do this for a smallish app1. It's one of a few possible approaches to routing in Elm. 1 Code is from the mantl-ui-frontend project at ca4145 Brian Hicks, St. Louis Elm Meetup 8
  3. Model Locations in the app are a tagged union: type

    Location = Home | HealthOverview | HealthCheck String Brian Hicks, St. Louis Elm Meetup 10
  4. Utilities: urlFor urlFor : Location -> String urlFor loc =

    let url = case loc of Home -> "/" HealthOverview -> "/health/" HealthCheck app -> "/health/" ++ app ++ "/" in "#" ++ url -- or just `url` if you want path routing Brian Hicks, St. Louis Elm Meetup 11
  5. Utilities: locFor locFor : String -> Maybe Location locFor path

    = let segments = path |> split "/" |> List.filter (\seg -> seg /= "" && seg /= "#") in case segments of [] -> Just Home ["health"] -> Just HealthOverview ["health", app] -> Just (HealthCheck app) _ -> Nothing Brian Hicks, St. Louis Elm Meetup 12
  6. Utilities: parentFor parentFor : Location -> Location parentFor child =

    case child of HealthCheck _ -> HealthOverview _ -> child Brian Hicks, St. Louis Elm Meetup 13
  7. Some startapp bookeeping -- MODEL type alias Model = Maybe

    Location init : Model init = Nothing -- UPDATE type Action = PathChange String update : Action -> Model -> (Model, Effects Action) update action model = case action of PathChange path -> ( (locFor path), Effects.none ) Brian Hicks, St. Louis Elm Meetup 14
  8. View: navItem navItem : Model -> Location -> String ->

    Html navItem model page caption = let active = case model of Nothing -> False Just current -> (parentFor current) == page in li [ classList [ ("nav-item", True) , ("active", active) ] ] [ a [ class "nav-link" , href (urlFor page) ] [ text caption ] ] Brian Hicks, St. Louis Elm Meetup 15
  9. View: notFound notfound : Html notfound = div [ class

    "row" ] [ p [ class "col-sm-12" ] [ text "Not found!" ] ] Brian Hicks, St. Louis Elm Meetup 16
  10. And finally, using it! (pt. 1) view : Signal.Address Action

    -> Model -> Html view address model = let link = Route.navItem model.route body = case model.route of Just (Route.Home) -> Services.view (Signal.forwardTo address ServicesAction) model.services model.health Just (Route.HealthOverview) -> Health.view (Signal.forwardTo address HealthAction) model.health Nothing Just (Route.HealthCheck app) -> Health.view (Signal.forwardTo address HealthAction) model.health (Just app) Nothing -> Route.notfound Brian Hicks, St. Louis Elm Meetup 17
  11. And finally, using it! (pt. 2) -- view : Signal.Address

    Action -> Model -> Html -- view address model = in div [ class "app" ] [ div [ classes [ "navbar", "navbar-inverted" ] ] [ div [ class "container" ] [ a [ class "navbar-brand" , href (Route.urlFor Route.Home) ] [ text "Mantl" ] , ul [ classes [ "nav", "navbar-nav" ] ] [ link Route.Home "Home" , link Route.HealthOverview "Health" ] -- health status elided to save space ] ] ] , div [ classes [ "container", "content" ] ] [ body ] ] Brian Hicks, St. Louis Elm Meetup 18