Quantcast
Channel: NoRedInk
Viewing all articles
Browse latest Browse all 193

Static site generation in Elm

$
0
0

Experiments in Elm

This post is part of a mini series based on some of the experiments we’ve been doing at NoRedInk. A lot of these ideas are proof of concepts that aren’t intended to go anywhere. The focus is on experimentation and trying new things out! The majority of these posts will be about Elm.

Static site generation

In this post, we’re going to talk about static site generation. Jekyll? I’d rather use Elm! With elm-static-site, doing this is trivial.

Imagine we have a blog. On our blog, we have multiple bloggers, which we have in a list like this -

-- Blog/Bloggers.elm
module Blog.Bloggers where

type alias Blogger =
    { name : String
    , age : Int
    }

noah =
    { name = "Noah"
    , age = 23
    }

dave =
    { name = "Dave"
    , age = 33
    }

bloggers : List Blogger
bloggers =
    [ noah
    , dave
    ]

Great. Now let’s make a statically generated page to list our bloggers.

-- Blog/Index.elm
module Blog.Index where

import Html exposing (..)
import Blog.Bloggers exposing (..)

bloggerView : Blogger -> Html.Html
bloggerView blogger =
    div
        [ id blogger.name]
        [ text "Hello, my name is "
        , text blogger.name
        , text " and I'm "
        , text (toString blogger.age)
        , " years old!"
        ]

view =
    div
        []
        (List.map bloggerView bloggers)

This will generate a page like this

<div>
    <div id="Noah">
        Hello, my name is Noah and I'm 23 years old!
    </div>
    <div id="Dave">
        Hello, my name is Dave and I'm 33 years old!
    </div>
</div>

For every file in the folder you give it, it will take that file, and if it has a view : Html function, it will take that out and turn into it a static page instead. So let’s say we had this structure:

examples/
    Index.elm -- has a view : Html
    Blog/
        Index.elm -- has a view : Html
        Bloggers.elm -- doesn't have a view : Html

the following files will be generated

output/
    index.html
    blog/
        index.html

Notice that Bloggers.elm gets skipped as it doesn’t expose a top-level view function.

The way this script works is pretty simple really. It uses a script to convert the output of the view functions to strings, and then through node, we extract the value from those ports to write to files with the same name as the module. This is why Blog.Index gets turned into blog/index.html.

Some background

Elm’s virtual dom is based on an implementation of a virtual dom simply called virtual-dom. How many times can we say virtual-dom in a sentence and have it still make sense?

This virtual-dom implementation has some cool libraries based around it, including one called vdom-to-html. What this does is render the virtual dom to HTML, either on the client or one the server. It just takes a Node, then returns the HTML version of that Node as a string. In Elm, the type signature for that function just looks like this

toHtml : VirtualDom.Node -> String

Right off the bat, that will work with the majority of Elm views. For example,

view =
    div
        []
        [ text "Hello world!" ]

htmlVersion =
    toHtml view

generates

<div>Hello world!</div>

and that’s it! Now we have static site generation in Elm!

If you want check this out, go to elm-static-site and start using it! There’s plenty of ways to improve it, so if you want to ask just ask me at @eeue56 on twitter or eeue56 on Slack!


Noah Hall
@eeue56
Engineer at NoRedInk


Viewing all articles
Browse latest Browse all 193

Trending Articles