This is a proof-of-concept project with the following technologies:
- Elm
- UIkit
- Phoenix Web Server
It is a really simple simulation of switching pages...
- Home page
- Profile page
Here is how it looks like...
User clicked 'Home' menu
User clicked 'Profile' menu
the Elm files are located here:
assets/elm/src/
├── Main.elm
├── HomePage.elm
├── ProfilePage.elm
├── Common.elm
└── ErrorPage.elm
- Pull the Data from a server
- Add UIKit layout
- Read the Data for the Model from JSON strings
- Configure Phoenix to to return the right Elm page on different browser URL calls
- Create the
Model
withPage
alternatives - Setup Elm compile watcher with esbuild
- Setup Elm
- Setup Phoenix project
Despite it is a Single Page Elm app, different pages are simulated with the contents in the Elm Model
.
The Model holds the Page
and the data that is used for the presentation of the page. E.g. Which menu item is active and what page contents should be displayed.
type alias Model =
{ key : Nav.Key
, page : Page
}
type Page
= HomePage HomeData
| ProfilePage ProfileData
| ErrorPage String
The Page Data is currently read from a JSON String, but can be easily ported to fetch it from a server.
Ref: https://github.com/dwyl/phoenix-elm-starter
$ cd <proect-root>
$ npm install -D esbuild-plugin-elm
$ npm install -D elm
$ mkdir assets/elm
$ cd assets/elm
$ elm init
$ cat > src/Main.elm <<EOF
module Main exposing (..)
import Html exposing (text)
name = "John"
main =
text ("Hello " ++ name ++ "!")
EOF
$ cat > src/index.js <<"EOF"
import { Elm } from './Main.elm';
const $root = document.createElement('div');
document.body.appendChild($root);
Elm.Main.init({
node: $root
});
EOF
$ cat > build.js <<"EOF"
const esbuild = require('esbuild');
const ElmPlugin = require('esbuild-plugin-elm');
esbuild.build({
entryPoints: ['src/index.js'],
outfile: '../vendor/elm.js',
bundle: true,
watch: process.argv.includes('--watch'),
plugins: [
ElmPlugin({
debug: true,
clearOnWatch: true,
}),
],
}).catch(_e => process.exit(1))
EOF
$ cd ..
$ cat >> js/app.js <<EOF
import elm from '../vendor/elm'
EOF
$ cd ..
$ tail config/dev.exs
watchers: [
...
node: ["./build.js", "--watch", cd: Path.expand("../assets/elm", __DIR__)]
]
Start the server with mix phx.server
You should see "Hello John!" ath the bottom of thhe page