Primeros pasos con Jinja y FastAPI

Un motor de plantillas es un recurso utilizado para separar la lógica de presentación de los datos. Mediante impresiones, filtros, condicionales, ciclos o importaciones, permite generar código HTML necesario para representar una página web. Son muy empleados en la programación del lado del servidor, ya que permiten la presentación de datos sin tener que modificar el código fuente.

En pocas palabras, con un motor de plantillas es posible presentar los datos manejados por el servidor, específicamente FastApi y generar el HTML en el proceso; por ejemplo, si tenemos una lista de usuarios, podemos imprimirlo en una tabla o similar en HTML usando ciertas funcionalidades (directivas).

Sobre Jinja

Jinja es un motor de plantillas escrito en Python diseñado para ser simple y expresivo; Jinja es el motor de plantillas usado en otros frameworks web de Python, como lo es Flask, también es muy similar al empleado por Django.

Con Jinja como motor de plantilla podemos representar fácilmente las respuestas de la API.

El motor de plantillas de Jinja utiliza corchetes { } para distinguir sus expresiones y sintaxis del HTML:

  1. La sintaxis {{ }} se denomina bloque variable y la podemos usar para imprimir en la plantilla. 
  2. La sintaxis {% %} alberga estructuras de control como if/else, bucles y macros.
  3. La sintaxis {#  #} son para comentarios.

Uso de Jinja en FastAPI

En este apartado, veremos cómo instalar Jinja dos en un proyecto en FastAPI y distintos ejemplos de cómo podemos emplear en conjunto ambas tecnologías para crear una aplicación web que no solamente permitirá procesar peticiones en el servidor y devolver una respuesta en formato JSON, si no, también procesar peticiones para devolver como respuestas páginas HTML con las cuales podremos gestionar datos.

Instalar Jinja

Para instalar el motor de plantillas conocido como Jinja, ejecutamos en el proyecto:

$ pip install Jinja2

Para utilizar Jinja, crearemos una carpeta para almacenar los templates:

templates

Y un apartado para las tareas:

templates\task

Y un archivo HTML:

templates\task\index.html

Con el siguiente contenido:

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>FastAPI</title>
</head>

<body>
    <h1>Hello world</h1>
</body>
</html>

En el archivo de arranque, crearemos un objeto instancia de Jinja2Templates que recibe como parámetro la carpeta raíz de los templates:

api.py

from fastapi import Request
from fastapi.templating import Jinja2Templates

templates = Jinja2Templates(directory="templates/")

Y creamos una función que recibe como parámetro la ubicación de la plantilla a renderizar y la petición del usuario:

@app.get('/page')
def index(request: Request):
    return templates.TemplateResponse('task/index.html',{"request": request})

Si accedemos desde el navegador, veremos:

Hello world

Primeros pasos con Jinja

En este apartado vamos a conocer las características principales de Jinja, que van desde el uso de  bloques de control, hasta el uso de filtros y del template en general.

Bloques de control

Uno de los elementos cruciales en los motores de plantillas son los bloques de control; podemos realizar desde condicionales hasta ciclos for que funcionan de la misma manera que en Python; con esto es posible realizar lógicas condicionales para renderizar bloques HTML si se cumple una condición al igual que iterar colecciones de datos completas, por ejemplo un listado de tareas en una tabla o similares.

Condicionales

Podemos hacer uso de los condicionales para evaluar condiciones de verdadero y falso:

<div>
    {% if True %}
        Is TRUE
    {% endif %}
</div>

Los condicionales en Jinja, son exactamente iguales que en Python, podemos usar el else, or, and, etc:

<div>
    {% if True and False %}
        Is True
    {% else %}
        Not is True
    {% endif %}
</div>

Ciclo for

Al igual que ocurre con el ciclo for en Python, podemos usarlo  en Jinja:

<ul>
{% for item in items %}
    <li>{{ item }}</li>
{% endfor %}
</ul>

Dentro de un bloque de bucle for, puede acceder a algunas variables especiales, entre las principales tenemos:

  • loop.index: Obtiene el índice actual de la iteración comenzando desde uno.
  • loop.index0: Obtiene el índice actual de la iteración comenzando desde cero.
  • loop.first: True si es la primera iteración.
  • loop.last: True si es la última iteración.
  • loop.length: Retorna el tamaño de la lista.

Por ejemplo, para usar la variable de last:

<ul>
    {% for e in [1,2,3,4,5,6,10] %}
    <li>{{ e }} {{ loop.last }} </li>
    {% endfor %}
</ul>

Todas las variables deben de ser empleadas dentro del ciclo for.

Filtros

Los filtros en Jinja son una de las características más importantes y versátiles que existen en este motor de plantillas; permiten manipular el contenido que se muestra en una plantilla. Hay varios filtros predefinidos en Jinja aunque podemos extender los existentes con filtros personalizados; los filtros se aplican a las variables que se para por ejemplo contar la longitud de una cadena de texto, unir textos en uno solo, separar por algún separador, dar formatos a fechas números y un largo etc; en resumen, permiten realizar manipulaciones personalizadas del contenido.

Para emplear un filtro, se usa el operador de pipe (|) luego de especificar el argumento o argumentos, y luego del operador de pipe, el filtro que quieras emplear:

<DATA> | <FILTER>

Veamos algunos filtros en Jinja.

Filtro default

El filtro default se usa para reemplazar la salida si la variable tiene un valor nulo (no se encuentra definida):

{{ task | default('This is a default Task') }}

Por ejemplo, si task es nula, tendremos una salida como:

This is a default Task

Si task estuviera definida o evaluamos por ejemplo, un número.

{{ 5 | default('This is a default Task') }}

Veríamos el número por pantalla:

5

Este material forma parte de mi curso y libro completo sobre FastAPI.

- Andrés Cruz

Andrés Cruz

Desarrollo con Laravel, Django, Flask, CodeIgniter, HTML5, CSS3, MySQL, JavaScript, Vue, Android, iOS, Flutter

Andrés Cruz En Udemy

Acepto recibir anuncios de interes sobre este Blog.