Desarrollo de Ecommerce con Django (parte 4)
Published: 2024-04-02 23:56:12

Este tutorial cubre los siguientes puntos:

- Layout de la web. 
- Configuración de archivos estáticos.
- Herencia de plantillas.

**1. Reestructurar el layout de la plantilla principal**

Vamos a estructurar el layout para que tenga una zona de header, nav, main y footer.

Usemos el siguiente código que está basado en los ejemplos de bootstrap 5:

```
{% load static %}

<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>EELA Ecommerce</title>
    <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-QWTKZyjpPEjISv5WaRU9OFeRpok6YctnYmDr5pNlyT2bRjXh0JMhjY6hW+ALEwIH" crossorigin="anonymous">
    <link rel="shortcut icon" href="{% static 'img/icon.png' %}" type="image/x-icon">
</head>

</head>
<body>
    <div class="container-fluid">

        <!-- Header -->
        <header class="d-flex flex-wrap align-items-center justify-content-center justify-content-md-between py-3 mb-4 border-bottom">
            <a href="{% url 'home' %}" class="d-flex align-items-center col-md-3 mb-2 mb-md-0 text-dark text-decoration-none">
              <svg class="bi me-2" width="40" height="32" role="img" aria-label="Bootstrap"><use xlink:href="#bootstrap"/></svg>
            </a>
      
            <ul class="nav col-12 col-md-auto mb-2 justify-content-center mb-md-0">
              <li><a href="#" class="nav-link px-2 link-secondary">Home</a></li>
              <li><a href="#" class="nav-link px-2 link-dark">Quiénes somos</a></li>
              <li><a href="#" class="nav-link px-2 link-dark">FAQs</a></li>              
            </ul>
      
            <div class="col-md-3 text-end">
              {% if user.is_authenticated %}
                <a href="#" class="nav-link link-body-emphasis px-2">Bienvenido, {{user.username}}</a>
                <a href="{% url 'logout' %}" class="nav-link link-body-emphasis px-2">Logout</a>                
              {% else %}
                <a href="{% url 'signin' %}" class="btn btn-outline-primary me-2">Login</a>
                <a href="{% url 'signup' %}" class="btn btn-primary">Sign-up</a>
              {% endif %}
            </div>
        </header>

        <!-- Navigation -->
        <nav class="navbar navbar-expand-lg bg-body-tertiary">
            <div class="container-fluid">
              <div class="collapse navbar-collapse" id="navbarSupportedContent">
                <ul class="navbar-nav me-auto mb-2 mb-lg-0">
                    <li class="nav-item dropdown">
                        <a class="nav-link dropdown-toggle" href="#" role="button" data-bs-toggle="dropdown" aria-expanded="false">
                      Categorías
                    </a>
                    <ul class="dropdown-menu">
                      <li><a class="dropdown-item" href="{% url 'home' %}">Todas las categorías</a></li>                      
                    </ul>
                  </li>
                </ul>
                <form class="d-flex" role="search">
                  <input class="form-control me-2" type="search" placeholder="Producto..." aria-label="Search">
                  <button class="btn btn-outline-primary" type="submit">Buscar</button>
                </form>
              </div>
            </div>
        </nav>

        <!-- Main -->
        <main class="container">

            <h1 class="text-center">Catálogo de Productos</h1>
            <div class="my-3 row row-cols-1 row-cols-md-3 g-4">
                {% for producto in productos %}
                <div class="col">
                    <div class="card h-100">
                        <img src="{{producto.imagen.url}}" alt="...">
                        <div class="card-body">
                            <h5 class="card-title">{{producto.nombre}}</h5>
                            <p class="card-text">{{producto.descripcion}}</p>
                        </div>
                        <div class="card-footer">
                            <small class="text-body-secondary">${{producto.precio}}</small>
                        </div>
                    </div>
                </div>
                {% endfor %}             
            </div>

        </main>

        <!-- Footer-->
        <footer class="py-5 bg-primary mb-2">
            <div class="container"><p class="m-0 text-center text-white">Copyright &copy; Escuela de Emprendimiento (EELA) 2024</p></div>
        </footer>
    
    </div>

    <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.3/dist/js/bootstrap.bundle.min.js" integrity="sha384-C6RzsynM9kWDrMNeT87bh95OGNyZPhcTNXj1NW7RuBCsyN/o0jlpcV8Qyq46cDfL" crossorigin="anonymous"></script>
</body>
</html>`
```

Este layout está incorporando el uso de archivos estáticos, por lo cual debemos configurarlo en el proyecto.

- Creemos la carpeta `static` en el directorio del proyecto.
- Vamos a ir a `settings.py` para registrar la variable STATICFILES_DIRS de la siguiente manera:

`STATICFILES_DIRS = (BASE_DIR / 'static',)`

Para probar agreguemos una subcarpeta `img` donde guardemos imágenes como el favicon de la web.

Cuando necesitemos usar los archivos estáticos en una plantilla debemos incluir la directiva `{% load static %}` al inicio de la plantilla y para un archivo específico usamos `{% static 'path_del_archivo' %}`.


**2. Herencia de plantillas **
Para realizar la herencia de plantillas vamos a incorporar en la plantilla base la definición de un bloque. Por ejemplo:

En la plantilla `index.html` declaramos:

```
<main class="my-5">
  {% block contenido %}
  {% endblock %}
</main>
```

Y creamos una nueva plantilla `catalog.html` la cual extenderá `index.html` y definirá el bloque contenido:

```
{% extends 'index.html' %}

{% block contenido %}
  
  <!-- Aquí va el código para presentar el detalle del catálogo -->

{% endblock %}
```