Imagine being able to add a field to the config form with just one line! It can be done if you use code generation.
Use ConfigFormGenerator in your ConfigSchema.elm to make a Config.elm file (it can be excluded from your src/ directory if you want, since it won't be compiled directly with your other elm files):
-- ConfigSchema.elm
import ConfigFormGenerator exposing (Kind(..))
import Html exposing (Html)
myConfigFields : List ( String, Kind )
myConfigFields =
[ ( "Header Font Size", IntKind "headerFontSize" )
, ( "Body Font Size", IntKind "bodyFontSize" )
, ( "Background Color", ColorKind "bgColor" )
]
main : Html msg
main =
let
generatedElmCode =
ConfigFormGenerator.toFile myConfigFields
_ =
Debug.log generatedElmCode ""
in
Html.text ""When compiled, it makes an elm app whose sole purpose is to console.log the elm code needed for a Config.elm file. To generate it, run something like this:
# Compile schema file to tmp js:
elm make ConfigSchema.elm --output=~/tmp/tmp.js > /dev/null
# Run compiled js with node, which logs out generated elm code, and save to Config.elm:
node ~/tmp/tmp.js > Config.elm 2>/dev/null#!/bin/bash
CONFIG_SCHEMA_ELMFILE=ConfigSchema.elm
CONFIG_ELMFILE=Config.elm
TMP_JS=~/tmp/gen-config.js
MAIN_ELMFILE=Main.elm
SERVER_DIR=public/
MAIN_JS_OUTPUT=public/js/main.js
GENERATE_ARGS="$CONFIG_SCHEMA_ELMFILE $TMP_JS $CONFIG_ELMFILE"
# Command for generating Config.elm from ConfigSchema.elm
generate_config () {
CONFIG_SCHEMA_ELMFILE=$1
TMP_JS=$2
CONFIG_ELMFILE=$3
# Use `elm make` to make an elm app that console.logs the generated Config.elm code
elm make $CONFIG_SCHEMA_ELMFILE --output=$TMP_JS > /dev/null && \
# Run it with `node` to print the output and write to Config.elm
node $TMP_JS > $CONFIG_ELMFILE 2>/dev/null
}
export -f generate_config
# Generate the config initially, just in case it doesn't exist
generate_config $GENERATE_ARGS
# Watch for config changes
chokidar $CONFIG_SCHEMA_ELMFILE --command "generate_config $GENERATE_ARGS" &
# Watch for elm changes
elm-live $MAIN_ELMFILE --dir=$SERVER_DIR -- --output=$MAIN_JS_OUTPUT &
waitThis will watch for changes to ConfigSchema.elm and generate a Config.elm file. Make sure you have the following installed, too:
# (use --save-dev instead of --global if you only need it locally for one project)
npm install --global elm elm-live@next chokidir
Use these to define what kind of value your field is. For all values except
SectionKind, theStringis the field's camelCase variable name for both yourConfigrecord and its JSON representation, such as "headerFontSize".SectionKindis just for visually organizing your fields.