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

Photo of Tom Dekan
by Tom Dekan

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 style="text-align: center; padding: 1rem;">
    Here is our interactive pendulum 💫
</div>
<div id="pendulum-wrapper" style="display: flex; justify-content: center; align-items: 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 style="text-align: center; padding: 1rem;">
    Here is our interactive pendulum 💫
</div>
<div id="pendulum-wrapper" style="display: flex; justify-content: center; align-items: center"></div>
<script src="{% static 'js/pendulum.js' %}"></script>
</body>
</html>
The output looks the same, but you have much neater code.

Build your Django templates faster with Photon Designer

Congrats! Now you can to add almost any javascript library to your Django template. You'll now be able to produce much richer and valuable web frontend using Django.

If you'd like to accelerate your web development much further, I built Photon Designer to release new Django products much faster - so that you can start making money, and giving value to users, dramatically faster than before.

Let's get visual.

Do you want to create beautiful frontends effortlessly?
Click below to book your spot on our early access mailing list (as well as early adopter prices).
Copied link to clipboard 📋

Made with care by Tom Dekan

© 2024 Photon Designer