François Constant logo

Elm & Django

January 2018

Here is a simple solution to run Elm code within a Django template. This could be used to handle the full frontend or just to embed a “widget” - like a search bar - via Elm.

Quick overview

To make it short: we’ll generate the JS code under the static folder and load it in our template. That way, we can still load CSS and Javascript files via Django. We can also fill up parts of the HTML via Django. To generate the JS code, we’ll use elm-live .

elm-live installation (on MacOS)

To install elm-live , simply run: npm install --global elm elm-live

If elm-live requires a more recent versions of npm (which requires a recent version of node ) you can upgrade these with the following commands (as long as node was installed via brew ). Using the --verbose option is useful as these commands can be extremely long to run. Also, if they crash, having the verbose output is useful for debugging.

npm install npm@latest -g                     
brew update —verbose
brew upgrade node —verbose`

Let’s do it

1.Does Elm compile?

First, make sure that your Elm code can run fine by itself. For example:

cd frontend
elm-reactor

2.Generate elm.js

Then, let’s generate the JS via elm-live . I would recommend to add that command under a bash file to reuse it afterwards. For example:

elm-live --port=3000 --output=../ede/static/ede/elm.js index.elm --pushstate --no-recover

or (to use Elm in debug mode and take advantage of the history feature):

elm-live --port=3000 --output=../ede/static/ede/elm.js index.elm --pushstate --debu

Here ede is the name of my application (that stands for Elm Django Example).

At that stage, please make sure that the generated JS ends up in the right folder. Also, make sure that it’s available in the browser. In the above example, it’s the case at: http://127.0.0.1:8000/static/ede/elm.js .

If it’s in the right folder but not visible in the browser, check your INSTALLED_APPS settings.

3.Load elm.js

The next step is to give a name to our Elm module by adding the following after the imports under index.elm :

module Ede exposing (..)

Now we can use the generated javascript in our Django template:

{% load static %}
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Elm Django Example</title>
</head>
<body>
  <h1>Elm Django Example</h1>
  <div id="elm"></div>
  <script src="{% static 'ede/elm.js' %}"></script>
  <script type="text/javascript">Elm.Ede.embed(document.querySelector("#elm"));</script>
</body>
</html>

Note the use of the module via Elm.Ede .

Et voilà; it’s working. The full working code is available here: github.com/FrancoisConstant/elm-django-example/tree/e44072e5…