Esta pagina se ve mejor con JavaScript habilitado

Django Bootstrap mediante WebPack

 ·  🎃 kr0m

Bootstrap es un conocido framework de desarrollo web para frontend, este incluye hojas de estilo CSS y librerías JS que nos facilitarán mucho la programación. En este artículo vamos a explicar como utilizar Bootstrap dentro de un proyecto Django/Webpack.

Antes de comenzar es recomendable leer los artículos anteriores sobre Django ya que son los pasos previos a este artículo:


Instalamos Bootstrap y sus dependencias:

yarn add bootstrap jquery popper.js

Con webpack las variables dentro de nuestro código JS ya no son globales, esto presenta algunos problemas en ciertas librerías obsoletas, para solventar dichos problemas debemos definir algunas variables, el mejor lugar donde hacerlo es en el fichero minimal.js ya que los templates extenderán desde minimal.html

No debemos definir estas variables en varios ficheros ni importar Bootstrap en varios puntos del código ya que ocasionará problemas y comportamientos anómalos, algunas funcionalidades de Bootstrap fallarán sin mostar ningún tipo de error.

Nuestro código quedará del siguiente modo:

vi assets/js/minimal.js

// JQuery stuff
import $ from 'jquery';
global.$ = global.jQuery = $;

import 'bootstrap';
import 'bootstrap/dist/css/bootstrap.min.css';

console.log('Inside minimal. Edit me in assets/js/minimal.js');
vi assets/js/base.js
console.log('Inside base. Edit me in assets/js/base.js');

En el index vamos a poner un poco de debug a través de la consola JS del navegador para comprobar que Bootstrap fué cargado con éxito y mostraremos también la versión de JQuery:

vi assets/js/index.js

import img from '../images/django-logo-positive.png';

// ------ OnLoad checks ------
window.onload = function() {
    // Basic checks
    console.log('----- window.onload -----');
    if (typeof $.fn.popover == 'function') { 
        console.log('BootStrap working correctly');
    } else {
        console.log('BootStrap NOT working correctly');
    }

    if (typeof jQuery != 'undefined') {  
        // jQuery is loaded => print the version
        console.log('JQuery version: ' + jQuery.fn.jquery);
    }
};

console.log('Inside index. Edit me in assets/js/index.js');

Registramos los nuevos entry points:

vi webpack.ENV.config.js

var path = require("path")
var webpack = require('webpack')
var BundleTracker = require('webpack-bundle-tracker')
var ProgressBarPlugin = require('progress-bar-webpack-plugin');
const MiniCssExtractPlugin = require('mini-css-extract-plugin');

module.exports = {
    mode: "development",
    context: __dirname,
    entry: {
        minimal: './assets/js/minimal.js',
        base: './assets/js/base.js',
        index: './assets/js/index.js',
    },

    output: {
        path: path.resolve('./assets/bundles/'),
        publicPath: '/static/',
        filename: "[name]-[fullhash].js",
    },

    plugins: [
        new BundleTracker({filename: '../../webpack-stats.json'}),
        new ProgressBarPlugin(),
        new MiniCssExtractPlugin({
            filename: '[name]-[hash].css',
        }),
    ],

    module:{
        rules:[
            {
                test: /\.css$/i,
                use: [MiniCssExtractPlugin.loader, 'css-loader'],
            },
            {
                test: /\.(png|jpe?g|gif)$/i,
                loader: 'file-loader',
                options: {
                  name: '[name].[ext]',
                },
            },
       ]
    },
}

Modificamos los templates para que hagan uso de algún elemento de Bootstrap como por ejemplo un card:

vi rxWod/templates/rxWod/minimal.html

{% load render_bundle from webpack_loader %}

<!doctype html>
<html lang="en">
    <head>
        <!-- Required meta tags for BootStrap -->
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
        <title>rxWod</title>
        {% render_bundle 'minimal' 'css'%}
        {% block minimal_head %}
        {% endblock %}
    </head>
    <body>
        <p>Minimal Template</p>
        {% render_bundle 'minimal' 'js'%}
        {% block minimal_body %}
        {% endblock %}
    </body>
</html>
vi rxWod/templates/rxWod/base.html
{% extends 'rxWod/minimal.html' %}
{% load render_bundle from webpack_loader %}

{% block minimal_head %}
    {% render_bundle 'base' 'css'%}
    {% block base_head %}
    {% endblock %}
{% endblock %}

{% block minimal_body %}
    <p>Base template</p>
    {% render_bundle 'base' 'js'%}
    {% block base_body %}
    {% endblock %}
{% endblock %}
vi rxWod/templates/rxWod/index.html
{% extends 'rxWod/base.html' %}
{% load render_bundle from webpack_loader %}
{% load webpack_static from webpack_loader %}

{% block base_head %}
    {% render_bundle 'index' 'css'%}
{% endblock %}

{% block base_body %}
        {% if routines %}
            {% for routine in routines %}
                <div class="col-xs-12 col-sm-12 col-md-6 col-lg-3 p-2 mb-2">
                    <div class="card text-center text-white bg-dark border border-primary rounded">
                        <div class="card text-center text-white bg-dark border border-primary rounded">
                            <div class="card-header">
                            <img class="text-center" src="{% webpack_static 'django-logo-positive.png' %}" width="150" height="90" alt="rxWod">
                        </div>
                        <div class="card-body">
                            <h5 class="card-title">{{ routine.date }}</h5>
                        </div>
                    </div>
                </div>
            {% endfor %}
        {% else %}
            <p>No routines available.</p>
        {% endif %}

    {% render_bundle 'index' 'js'%}
{% endblock %}

Recompilamos los bundles:

yarn dev-build

Accedemos a la web y vemos que BootStrap está funcionando:

Además en la consola JS del navegador podemos comprobar que Bootstrap se ha cargado correctamente y consultar la versión de JQuery(podemos ignorar los warnings acerca de los ficheros .map):

Si te ha gustado el artículo puedes invitarme a un RedBull aquí