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
divs, they sit one above the other - style them as
float: leftand they sit side by side - but if we want flexbox styling, we can’t style
bodyas aflexparent. So, for example, everyone usingelm-uiends 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 ![]()