How to add a javascript library to your Django HTML template 👔

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.

Want to ship better features with AI?
Join my free weekly newsletter.

No spam guaranteed Unsubscribe whenever