2019-11-06 02:37:10 +03:00
# elm-spa
2020-03-28 09:46:45 +03:00
[![Build Status ](https://travis-ci.org/ryannhg/elm-spa.svg?branch=master )](https://travis-ci.org/ryannhg/elm-spa)
2020-03-28 10:20:36 +03:00
## single page apps made easy
2020-03-27 07:35:43 +03:00
2020-03-28 10:20:36 +03:00
When you create an app with the [elm/browser ](https://package.elm-lang.org/packages/elm/browser/latest ) package, you can build anything from a static `Html msg` page to a fully-fledged web `Browser.application` .
__elm-spa__ uses that design at the page-level, so you can quickly add new pages to your Elm application!
2020-03-30 04:51:10 +03:00
✅ Automatically generate routes and pages
2020-03-28 10:20:36 +03:00
2020-03-30 04:51:10 +03:00
✅ Read and update global state across pages
## static pages
2020-03-28 10:20:36 +03:00
2020-03-30 04:51:10 +03:00
```elm
2020-03-28 10:20:36 +03:00
-- can render a static page
2020-03-28 22:59:28 +03:00
page : Page Flags Model Msg
2020-03-28 10:20:36 +03:00
page =
2020-03-28 22:59:28 +03:00
Page.static
{ view = view
}
2020-03-28 10:20:36 +03:00
```
2020-03-27 07:35:43 +03:00
2020-03-30 04:51:10 +03:00
## sandbox pages
2020-03-28 10:20:36 +03:00
2020-03-30 04:51:10 +03:00
```elm
2020-03-28 10:20:36 +03:00
-- can keep track of page state
2020-03-28 22:59:28 +03:00
page : Page Flags Model Msg
2020-03-28 10:20:36 +03:00
page =
2020-03-28 22:59:28 +03:00
Page.sandbox
{ init = init
, update = update
, view = view
}
2020-03-28 23:00:02 +03:00
```
2020-03-28 10:20:36 +03:00
2020-03-30 04:51:10 +03:00
## element pages
2020-03-28 10:20:36 +03:00
2020-03-30 04:51:10 +03:00
```elm
2020-03-28 10:20:36 +03:00
-- can perform side effects
2020-03-28 22:59:28 +03:00
page : Page Flags Model Msg
2020-03-28 10:20:36 +03:00
page =
2020-03-28 22:59:28 +03:00
Page.element
{ init = init
, update = update
, subscriptions = subscriptions
, view = view
}
2020-03-27 07:43:08 +03:00
```
2020-03-27 07:35:43 +03:00
2020-03-30 04:51:10 +03:00
## component pages
2019-11-22 08:49:36 +03:00
2020-03-30 04:51:10 +03:00
```elm
2020-03-28 10:20:36 +03:00
-- can read and update global state
2020-03-28 22:59:28 +03:00
page : Page Flags Model Msg
2020-03-28 10:20:36 +03:00
page =
2020-03-28 22:59:28 +03:00
Page.component
{ init = init
, update = update
, subscriptions = subscriptions
, view = view
}
2020-03-27 07:43:08 +03:00
```
2020-03-28 10:20:36 +03:00
2020-03-30 04:51:10 +03:00
## easily put together pages!
The reason we return the same `Page` type is to make it super
easy to write top-level `init` , `update` , `view` , and `susbcriptions` functions.
(And if you're using the [official cli tool ](https://npmjs.org/elm-spa ), this code will be automatically generated for you)
### `init`
2020-03-28 10:20:36 +03:00
```elm
init : Route -> Global.Model -> ( Model, Cmd Msg, Cmd Global.Msg )
init route =
case route of
Route.Home -> pages.home.init ()
Route.About -> pages.about.init ()
Route.Posts slug -> pages.posts.init slug
Route.SignIn -> pages.signIn.init ()
2020-03-27 07:43:08 +03:00
```
2019-11-22 08:49:36 +03:00
2020-03-30 04:51:10 +03:00
### `update`
2020-03-28 10:20:36 +03:00
```elm
update : Msg -> Model -> Global.Model -> ( Model, Cmd Msg, Cmd Global.Msg )
update bigMsg bigModel =
case ( bigMsg, bigModel ) of
( Home_Msg msg, Home_Model model ) ->
pages.home.update msg model
2019-11-22 08:49:36 +03:00
2020-03-28 10:20:36 +03:00
( About_Msg msg, About_Model model ) ->
pages.about.update msg model
( Posts_Msg msg, Posts_Model model ) ->
pages.posts.update msg model
( SignIn_Msg msg, SignIn_Model model ) ->
pages.signIn.update msg model
_ ->
always ( bigModel, Cmd.none, Cmd.none )
2020-03-27 07:43:08 +03:00
```
2020-03-28 10:20:36 +03:00
2020-03-30 04:51:10 +03:00
### `view` + `subscriptions`
2020-03-28 10:20:36 +03:00
```elm
-- handle view and subscriptions in one case expression!
bundle : Model -> Global.Model -> { view : Document Msg, subscriptions : Sub Msg }
bundle bigModel =
case route of
Home_Model model -> pages.home.bundle model
About_Model model -> pages.about.bundle model
Posts_Model model -> pages.posts.bundle model
SignIn_Model model -> pages.signIn.bundle model
2020-03-27 07:46:52 +03:00
```
2020-03-28 10:20:36 +03:00
### install the npm package
2020-03-27 07:46:52 +03:00
2020-03-28 10:20:36 +03:00
The [cli tool ](https://www.npmjs.com/package/elm-spa ) has commands like `elm-spa init` , `elm-spa add` , and `elm-spa build` for
generating your routes and pages for you!
```
npm install -g elm-spa
elm-spa init new-project
```
2020-03-27 07:46:52 +03:00
2020-03-28 10:20:36 +03:00
### install the elm package
2020-03-27 07:46:52 +03:00
2020-03-28 10:20:36 +03:00
If you'd rather define routes and pages by hand,
2020-03-28 22:59:28 +03:00
you can add [the elm package ](https://package.elm-lang.org/packages/ryannhg/elm-spa/latest ) to your project:
2020-03-27 07:46:52 +03:00
2020-03-28 10:20:36 +03:00
```
elm install ryannhg/elm-spa
```
2020-03-27 07:46:52 +03:00
2020-03-28 10:20:36 +03:00
### rather see an example?
2020-03-27 07:46:52 +03:00
2020-03-28 10:20:36 +03:00
This repo comes with an example project that you can
2020-03-30 04:51:10 +03:00
play around with. Add in some pages and see how it works!
#### html example
2020-03-28 10:20:36 +03:00
```
git clone https://github.com/ryannhg/elm-spa
2020-03-30 04:51:10 +03:00
cd elm-spa/examples/html
2020-03-28 10:20:36 +03:00
npm start
```
2020-03-30 04:51:10 +03:00
#### elm-ui example
```
git clone https://github.com/ryannhg/elm-spa
cd elm-spa/examples/elm-ui
npm start
```
The __elm-spa__ will be running at http://localhost:8000