Philosophy
Philosophy
As a general rule,
elm-pages
strives to be unopinionated about how you organize
your files (both code and content).
.
├── content/
├── elm.json
├── images/
├── static/
├── index.js
├── package.json
└── src/
└── Template/
├── Bio.elm # user-defined template modules
└── Catalog.elm
└── Main.elm
content folder
content
folder
Each file in the
content
folder will result in a new route for your static site. You can define how to render the types of document in the
content
folder based on the extension any way you like.
helloDocument : Pages.Document.DocumentParser Metadata (List (Html Msg))
helloDocument =
Pages.Document.parser
{ extension = "txt"
, metadata =
-- pages will use the layout for Docs if they have
-- `type: doc` in their markdown frontmatter
Json.Decode.map2
(\title maybeType ->
case maybeType of
Just "doc" ->
Metadata.Doc { title = title }
_ ->
Metadata.Page { title = title }
)
(Json.Decode.field "title" Json.Decode.string)
(Json.Decode.field "type" Json.Decode.string
|> Json.Decode.maybe
)
, body = MarkdownRenderer.view
}
markdownDocument : Pages.Document.DocumentParser Metadata (List (Element Msg))
markdownDocument =
Pages.Document.parser
{ extension = "md"
, metadata =
Json.Decode.map2
(\title maybeType ->
case maybeType of
Just "doc" ->
Metadata.Doc { title = title }
_ ->
Metadata.Page { title = title }
)
(Json.Decode.field "title" Json.Decode.string)
(Json.Decode.field "type" Json.Decode.string
|> Json.Decode.maybe
)
, body = MarkdownRenderer.view
}
Modules
Modules
Templates
Templates
src/Template/*.elm
A template represents a type of page. For example, a BlogPost template could live in
src/Template/BlogPost.elm
. Any files in your
content/
folder with frontmatter that you decode into type
TemplateType.BlogPost
will be rendered using your
BlogPost
template.
Think of each template as having its own mini
elm-pages architecture
lifecycle.
Imagine you have a site called thegreatcomposers.com that lists the greatest works of Classical composers.
Let's say you have a file called
content/catalog/sibelius.md
with these contents:
---
template: catalog
composer: Sibelius
---
## Symphony 2, Op. 47
### Notable Recordings
Bernstein Vienna Philharmonic
You have a metadata decoder like this:
module Metadata exposing (Metadata, decoder)
type Metadata = Catalog Composer | Bio Composer
type Composer = Sibelius | Mozart
decoder =
Decode.string
|> Decode.field "template"
|> Decode.andThen (\template ->
case template of
"catalog" -> Decode.map Catalog decodeComposer
"bio" -> Decode.map Bio decodeComposer
)
Now say you navigate to
/catalog/sibelius
. Let's look at the
elm-pages architecture
lifecycle steps that kick in.
Build
Build
•
staticData
- When you build your site (using
elm-pages build
for prod or
elm-pages develop
in dev mode), the
staticData
will be fetched for this page. Your
staticData
request has access to the page's
Metadata
. So if you wanted to request
api.composers.com/portrait-images/
to get the list of images for each composer's catalog page, you could. Behind the scenes,
elm-pages
will make sure this data is loaded for you in the browser so you have access to this data, even though the API is only hit during the initial build and then stored as a JSON asset for your site.
Page Load
Page Load
•
init
- the page for Sibelius' catalog has its own state. Let's display a Carousel that shows photos of the composer.
init
is called when you navigate to this page. If you navigate to another composer's catalog page, like Mozart, it will call the same
init
function to get a fresh Model for the new page, passing in the metadata for the Mozart page (from the frontmatter in
content/catalog/mozart
.
•
view
given the page's state, metadata, and StaticHttp data, you can render the catalog for Sibelius.
Page Interaction
Page Interaction
•
update
- if you click the Carousel, the page's state gets updated.
Shared
Shared
src/Shared.elm
•
staticData
(loaded per-app, not per-page)
•
View
- the data type that pages render to in your app
•
view
- the top-level view function for your app
Build
Build
src/Build.elm
•
staticData
(build-only)
•
manifest
•
generateFiles
Global Metadata
Global Metadata
src/TemplateType.elm
This module must define a variant for each template module.