Many thanks for all the interesting replies and explanations, gratefully received.
It looks like elm-spa is the way to go…
[Edit] …I’ve just discovered Elm Land: Ryan’s upgrade of elm-spa…
I’m very interested in this whole branch of the topic
Model = Custom Type
vs Model = Record
.
In a previous question I asked, Is it inefficient to pass the whole model from function to function?
I think a relevant point from this discussion is that a complex structure like the model is passed by reference. So, whether the model is data for each page plus session data inside a record, or a custom type of one page at a time plus session data, there’s no efficiency gain or loss.
Which I think I am typically very likely to need.
Could we somehow use each page’s init
to populate the ‘empty’ values?
Alternatively, might the record entry for each page be a Maybe
?
I’m still finding my way around elm-spa, but it seems to solve this one by combining Carsten’s and Paul’s approaches — a custom type
inside a record
— plus auto-generation:
The underlying model is a record in .elm-spa/defaults/Main.elm
module Main exposing (main)
import Gen.Pages as Pages
type alias Model =
{ url : Url
, key : Key
, shared : Shared.Model
, page : Pages.Model
}
Pages.Model
= Model.Model
:
type Model
= Redirecting_
| Home_ Gen.Params.Home_.Params ()
| NotFound Gen.Params.NotFound.Params
So each time a page is added (elm-spa add
), a new option is added to the Model.Model
.
Minor note on the Document body type
Even when writing raw html, I always use a ‘dummy’ div
because it feels wrong to style the top-level body
. And, in the case of the Document
type, there is no mechanism to style the body
:
- if it has three unstyled child
div
s, they sit one above the other - style them as
float: left
and they sit side by side - but if we want flexbox styling, we can’t style
body
as aflex
parent. So, for example, everyone usingelm-ui
ends up with something likebody = [ myElmUiBody ]
.
It’s like a painting studio that favours the painters of triptychs over those who just use a single canvas: every frame comes with a hinge, whether you need it or not