How to add a javascript library to your Django HTML template ๐Ÿ‘”

Published: August 1, 2023

You want to add a javascript library to your Django HTML template for the first time. Good news: it's very easy.

We'll use a CDN (Content Delivery Network) to serve the javascript library from an external source. This is the simplest and fastest approach in most cases.

We'll add a simulation of how matter moves to our Django template. We'll do this by adding the physics.js javascript library to our django template to show a pendulum simulation.

This is a good example because, as of writing, the physics.js

library doesn't show a CDN link in their setup instructions.

But, because the javascript library uses npm (the standard register of javascript libraries, which almost all javascript libraries use), there will be a CDN link.

What our final template will look like

Let's start! We'll assume that you've already setup a django project and are showing a template successfully.

Search for your javascript library on the CDN (

https://www.jsdelivr.com/)

  • Click on the library to find the CDN HTML link. The CDN HTML link looks like this:

Find your CDN link html (https://www.jsdelivr.com/)

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Pendulum</title>
    <script src="https://cdn.jsdelivr.net/npm/matter-js@0.19.0/build/matter.min.js"></script>
  </head>

  <body></body>
</html>

3. Add javascript to your Django template that uses the library

  • Add the javascript in a <script> tag that controls the pendulum
  • Add a little CSS to center the pendulum.
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <title>Pendulum</title>
    <script src="https://cdn.jsdelivr.net/npm/matter-js@0.19.0/build/matter.min.js"></script>

</head>

<body>

    <div>
        Here is our interactive pendulum ๐Ÿ’ซ
    </div>
    <div id="pendulum-wrapper" style={{ display: 'flex', justifyContent: 'center', alignItems: 'center' }}></div>

    <script>
        var Example = Example || {};

        Example.newtonsCradle = function() {
            var Engine = Matter.Engine,
                Render = Matter.Render,
                Runner = Matter.Runner,
                Body = Matter.Body,
                Composites = Matter.Composites,
                MouseConstraint = Matter.MouseConstraint,
                Mouse = Matter.Mouse,
                Composite = Matter.Composite;

            // create engine
            var engine = Engine.create(),
                world = engine.world;

            // create renderer
            var render = Render.create({
                element: document.querySelector('#pendulum-wrapper'),
                engine: engine,
                options: {
                    width: 800,
                    height: 600,
                    showVelocity: true
                }
            });

            Render.run(render);

            // create runner
            var runner = Runner.create();
            Runner.run(runner, engine);

            // see newtonsCradle function defined later in this file
            var cradle = Example.newtonsCradle.newtonsCradle(280, 100, 5, 30, 200);
            Composite.add(world, cradle);
            Body.translate(cradle.bodies[0], {
                x: -180,
                y: -100
            });

            cradle = Example.newtonsCradle.newtonsCradle(280, 380, 7, 20, 140);
            Composite.add(world, cradle);
            Body.translate(cradle.bodies[0], {
                x: -140,
                y: -100
            });

            // add mouse control
            var mouse = Mouse.create(render.canvas),
                mouseConstraint = MouseConstraint.create(engine, {
                    mouse: mouse,
                    constraint: {
                        stiffness: 0.2,
                        render: {
                            visible: false
                        }
                    }
                });

            Composite.add(world, mouseConstraint);

            // keep the mouse in sync with rendering
            render.mouse = mouse;

            // fit the render viewport to the scene
            Render.lookAt(render, {
                min: {
                    x: 0,
                    y: 50
                },
                max: {
                    x: 800,
                    y: 600
                }
            });

            // context for MatterTools.Demo
            return {
                engine: engine,
                runner: runner,
                render: render,
                canvas: render.canvas,
                stop: function() {
                    Matter.Render.stop(render);
                    Matter.Runner.stop(runner);
                }
            };
        };

        Example.newtonsCradle.title = 'Newton\'s Cradle';
        Example.newtonsCradle.for = '>=0.14.2';

        /**
         * Creates a composite with a Newton's Cradle setup of bodies and constraints.     * @method newtonsCradle     * @param {number} xx
         * @param {number} yy
         * @param {number} number
         * @param {number} size
         * @param {number} length
         * @return {composite} A new composite newtonsCradle body
         */
        Example.newtonsCradle.newtonsCradle = function(xx, yy, number, size, length) {
            var Composite = Matter.Composite,
                Constraint = Matter.Constraint,
                Bodies = Matter.Bodies;

            var newtonsCradle = Composite.create({
                label: 'Newtons Cradle'
            });

            for (var i = 0; i < number; i++) {
                var separation = 1.9,
                    circle = Bodies.circle(xx + i * (size * separation), yy + length, size, {
                        inertia: Infinity,
                        restitution: 1,
                        friction: 0,
                        frictionAir: 0,
                        slop: size * 0.02
                    }),
                    constraint = Constraint.create({
                        pointA: {
                            x: xx + i * (size * separation),
                            y: yy
                        },
                        bodyB: circle
                    });

                Composite.addBody(newtonsCradle, circle);
                Composite.addConstraint(newtonsCradle, constraint);
            }

            return newtonsCradle;
        };

        window.Example = Example.newtonsCradle();
    </script>

</body>

</html>

4. View your result

Our result

Bonus: Good Django practice -> Tidy up your templates by moving your javascript

A. Move to a neater structure

  • Create a folder in your app folder (My app is called 'sim') and call the folder static

  • Create a javascript folder called js in your static folder

  • Create a javascript file called pendulum.js in your js folder

Your newly created directory structure
  • Move the javascript that we added to your template into the pendulum.js file. pendulum.js should look like:
var Example = Example || {}

Example.newtonsCradle = function () {
  var Engine = Matter.Engine,
    Render = Matter.Render,
    Runner = Matter.Runner,
    Body = Matter.Body,
    Composites = Matter.Composites,
    MouseConstraint = Matter.MouseConstraint,
    Mouse = Matter.Mouse,
    Composite = Matter.Composite

  // create engine
  var engine = Engine.create(),
    world = engine.world

  // create renderer
  var render = Render.create({
    element: document.querySelector('#pendulum-wrapper'),
    engine: engine,
    options: {
      width: 800,
      height: 600,
      showVelocity: true,
    },
  })

  Render.run(render)

  // create runner
  var runner = Runner.create()
  Runner.run(runner, engine)

  // see newtonsCradle function defined later in this file
  var cradle = Example.newtonsCradle.newtonsCradle(280, 100, 5, 30, 200)
  Composite.add(world, cradle)
  Body.translate(cradle.bodies[0], {
    x: -180,
    y: -100,
  })

  cradle = Example.newtonsCradle.newtonsCradle(280, 380, 7, 20, 140)
  Composite.add(world, cradle)
  Body.translate(cradle.bodies[0], {
    x: -140,
    y: -100,
  })

  // add mouse control
  var mouse = Mouse.create(render.canvas),
    mouseConstraint = MouseConstraint.create(engine, {
      mouse: mouse,
      constraint: {
        stiffness: 0.2,
        render: {
          visible: false,
        },
      },
    })

  Composite.add(world, mouseConstraint)

  // keep the mouse in sync with rendering
  render.mouse = mouse

  // fit the render viewport to the scene
  Render.lookAt(render, {
    min: {
      x: 0,
      y: 50,
    },
    max: {
      x: 800,
      y: 600,
    },
  })

  // context for MatterTools.Demo
  return {
    engine: engine,
    runner: runner,
    render: render,
    canvas: render.canvas,
    stop: function () {
      Matter.Render.stop(render)
      Matter.Runner.stop(runner)
    },
  }
}

Example.newtonsCradle.title = "Newton's Cradle"
Example.newtonsCradle.for = '>=0.14.2'

/**
 * Creates a composite with a Newton's Cradle setup of bodies and constraints.     * @method newtonsCradle     * @param {number} xx
 * @param {number} yy
 * @param {number} number
 * @param {number} size
 * @param {number} length
 * @return {composite} A new composite newtonsCradle body
 */
Example.newtonsCradle.newtonsCradle = function (xx, yy, number, size, length) {
  var Composite = Matter.Composite,
    Constraint = Matter.Constraint,
    Bodies = Matter.Bodies

  var newtonsCradle = Composite.create({
    label: 'Newtons Cradle',
  })

  for (var i = 0; i < number; i++) {
    var separation = 1.9,
      circle = Bodies.circle(xx + i * (size * separation), yy + length, size, {
        inertia: Infinity,
        restitution: 1,
        friction: 0,
        frictionAir: 0,
        slop: size * 0.02,
      }),
      constraint = Constraint.create({
        pointA: {
          x: xx + i * (size * separation),
          y: yy,
        },
        bodyB: circle,
      })

    Composite.addBody(newtonsCradle, circle)
    Composite.addConstraint(newtonsCradle, constraint)
  }

  return newtonsCradle
}

window.Example = Example.newtonsCradle()

B. Update your Django settings.py file to tell Django the path (from your BASE_DIR) to look for your static files.

  • Add the below code to anywhere in your settings.py file. Change 'sim' to the name of your Django app.
STATIC_URL = '/static/'
STATICFILES_DIRS = [BASE_DIR / 'sim/static']

C. Update your template

  • Add the {% load static %} Django template tag
  • Add a link to your moved javascript below your target div (the div with the id="pendulum-wrapper"

Your final template should look like the below:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <title>Pendulum</title>
    <script src="https://cdn.jsdelivr.net/npm/matter-js@0.19.0/build/matter.min.js"></script>
    {% load static %}
  </head>

  <body>
    <div>Here is our interactive pendulum ๐Ÿ’ซ</div>
    <div id="pendulum-wrapper"></div>
    <script src="{% static 'js/pendulum.js' %}"></script>
  </body>
</html>
The output looks the same, but you have much neater code.

Subscribe to my free newsletter

Get updates on AI, software, and business.