diff options
Diffstat (limited to 'examples/07-routing/README.md')
-rw-r--r-- | examples/07-routing/README.md | 56 |
1 files changed, 53 insertions, 3 deletions
diff --git a/examples/07-routing/README.md b/examples/07-routing/README.md index 5eaf0cd..217b674 100644 --- a/examples/07-routing/README.md +++ b/examples/07-routing/README.md @@ -2,12 +2,62 @@ # 07 Routing -We haven't quite got round to documenting this example yet. You can still check out the [source code](./src/app.gleam) and run it with the following command: +In this example, we demonstrate basic routing using the community library [modem](https://hexdocs.pm/modem/). Modem's quickstart docs should be all you should need to get up to speed, so that's the best place to start. -```sh -gleam run -m lustre/dev start --use-example-styles +Of course, it's not much fun routing without something to route _to_. This example lets users create new pages on the fly - a guest book for your next house party! Hospitality is very important, and guests will be sure to feel welcome when they see their name in the navigation with a special greeting page just for them. + +## Using Modem + +Modem uses [custom side effects](../06-custom-effects/) and external Javascript to translate browser click and navigation events into `update` messages for the Lustre runtime. All we need to use it is a [route change handler function](./src/app.gleam#L59) that we can pass to `modem.init` in our app's `init` function. + +> _Note:_ See [`modem.advanced`](https://hexdocs.pm/modem/modem.html#advanced) to configure more options. + +Inside our `on_route_change` function, we match URI path segment patterns to our routes: + +```gleam + fn on_route_change(uri: Uri) -> Msg { + case uri.path_segments(uri.path) { + ["welcome", guest] -> OnRouteChange(WelcomeGuest(guest)) + _ -> OnRouteChange(Home) + } + } +``` + +In our `update` function, we assign the matched route to `model.current_route`: + +```gleam +fn update(model: Model, msg: Msg) -> #(Model, Effect(Msg)) { + case msg { + OnRouteChange(route) -> #( + Model(..model, current_route: route), + effect.none(), + ) + ... + } ``` +And in our `view` function, we use `model.current_route` to determine what to display to the user: + +```gleam +fn view(model: Model) -> Element(Msg) { + let page = case model.current_route { + Home -> render_home(model) + WelcomeGuest(name) -> render_welcome(model, name) + } + ... +} +``` + +## Views: They're just functions! + +Lustre doesn't provide a traditional HTML or JSX-style templating engine, and this is by design. + +Since the `view` portion of this example is a bit more involved than our previous ones have been, it should start to give you more of a feel for how views in Lustre are _just functions_. The layout is a function. Each page view is a function. The nav is a function, and each individual nav _item_ is a function too. + +This means we can build up our entire UI using Gleam's functional syntax, benefiting from features like exhaustive pattern matching based on our routes. + +Since our views are [pure functions](https://github.com/lustre-labs/lustre/blob/main/pages/hints/pure-functions.md), we know they'll always render reliably. + ## Getting help If you're having trouble with Lustre or are not sure what the right way to do |