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.