Regístrate para acceder a más de 15 cursos gratuitos de programación con un simulador

Plantillas JS: Desarrollo web

En esta lección nos familiarizaremos con los motor de plantillas.

Fastify y otros frameworks similares permiten crear sitios web completos sin herramientas adicionales. Un sitio web funcional simplemente debe devolver una respuesta con código HTML, que el navegador mostrará como una página:

app.get('/', (req, res) => {
  res.type('html');
  res.send('<h1>Hello World!</h1>');
});

Aquí vemos un ejemplo simplificado, en el que solo devolvemos un encabezado H1.

En las aplicaciones reales, el HTML devuelto consta de cientos y miles de líneas. Trabajar con estos volúmenes de la manera estándar es muy complicado. Aquí están solo algunos de los problemas que encontraremos:

  • Este código es difícil de formar, editar y mantener.
  • Es muy fácil cometer un error en este código y es muy difícil detectarlo.
  • En este código pueden surgir problemas con comillas simples o dobles; será necesario manejar adecuadamente estos caracteres y mantener una vigilancia constante.

Para resolver este problema se utilizan los motores de plantillas. Son bibliotecas que permiten generar HTML en archivos separados, con resaltado y sustitución de datos de manera conveniente. En otras palabras, obtenemos no HTML dentro del código, sino código dentro del HTML.

En el mundo de Fastify existen varios motores de plantillas diferentes. Para este curso elegimos Pug.

Veamos cómo se ve una plantilla en PUG:

doctype html
html(lang='en')
 head
   title Hello, World!
 body
   h1 Hello, World!
   div.remark
     p Pug rocks!

Cómo comenzar a trabajar con PUG 🐾

Para comenzar a trabajar con pug en Fastify, debes instalar dos paquetes:

npm i pug @fastify/view

El paquete @fasitfy/view agrega soporte para motores de plantillas en Fastify. Cuando se conecta el complemento, debes indicar que deseas usar Pug como el motor de plantillas en nuestra aplicación:

import fastify from 'fastify';
import view from '@fastify/view';
import pug from 'pug';

const app = fastify();
const port = 3000;

// Conectamos pug a través del complemento
await app.register(view, { engine: { pug } });

app.listen({ port }, () => {
  console.log(`Example app listening on port ${port}`);
});

Las plantillas Pug se almacenan en el directorio src/views y tienen la extensión pug. Para practicar, vamos a agregar la primera plantilla para la página principal del sitio web. Para ello, realizaremos dos acciones:

  1. Crearemos la plantilla src/views/index.pug con el siguiente contenido:

    doctype html
    html(lang='en')
    head
        title Hello Códica!
    body
    main
    h1 Hello, World!
    p Fastify + Pug
    
  2. Indicaremos al controlador de la página principal que use esta plantilla:

    app.get('/', (req, res) => res.view('src/views/index'));
    

Fíjate en el método res.view() en el código anterior. Se encarga de renderizar la plantilla especificada y agregar el resultado a la respuesta HTTP.

La ruta a la plantilla se especifica en relación a la directorio raíz de la aplicación:

# Por ejemplo, la estructura puede verse así
views
├── cursos
│   ├── edit.pug
│   ├── index.pug
│   ├── new.pug
│   └── show.pug
├── index.pug
└── usuarios
    ├── edit.pug
    ├── index.pug
    └── new.pug

Las propias plantillas pueden ubicarse a un nivel más profundo. Esto se vuelve importante cuando aumenta el número de plantillas.

El motor de plantillas no establece reglas de nombrado y estructura interna de las plantillas. Pero trabajar sin reglas es demasiado complicado, por lo tanto, con el tiempo desarrollaremos nuestras propias reglas y las seguiremos.

Cómo funciona la representación de datos

Por lo general, el HTML dentro de las plantillas se genera a partir de datos que queremos mostrar. Por ejemplo, para mostrar información sobre un curso en la página /cursos/:id, pasamos un objeto de ese curso a la plantilla y generamos el HTML en base al contenido del mismo.

Veamos cómo los controladores normalmente trabajan con plantillas:

  1. Primero extraen todos los datos que necesitan.
  2. Luego crean un objeto con los datos para la plantilla.
  3. Finalmente pasan este objeto a la plantilla como un objeto.
const state = {
  cursos: [
    {
      id: 1,
      titulo: 'JS: Arrays',
      description: 'Curso sobre arrays en JavaScript',
    },
    {
      id: 2,
      titulo: 'JS: Funciones',
      description: 'Curso sobre funciones en JavaScript',
    },
  ],
};

app.get('/courses/:id', (req, res) => {
  const { id } = req.params
  const course = state.courses.find(({ id: courseId }) => courseId === parseInt(id));
  if (!course) {
    res.code(404).send({ message: 'Course not found' });
    return;
  }
  const data = {
    course,
  };
  res.view('src/views/courses/show', data);
});

Queda un último paso: mostrar los datos del curso en la plantilla. Para hacerlo, en las plantillas tenemos acceso al objeto que pasamos en el controlador:

doctype html
html
  head
    title Hello Códica!
  body
    main
      h1= course.title
      p= course.description

¿Qué estructuras de control se utilizan en Pug?

Aparte de la salida normal de valores, en las plantillas a menudo se utilizan estructuras de control y bucles. Con su ayuda, se muestran listas, se ocultan o se muestran bloques específicos, etc.

Puedes leer más sobre todas estas estructuras en la documentación oficial. Pero aquí desglosaremos un ejemplo basado en la ruta /cursos, en la cual se muestra una lista de cursos con descripciones y enlaces a los cursos.

  1. Controlador de la ruta:

    app.get('/courses', (req, res) => {
      const data = {
        courses: state.courses, // En algún lugar se almacena una lista de cursos
        header: 'Cursos de programación',
      };
        res.view('src/views/courses/index', data);
    });
    
  2. Plantilla

    html
    head
        title Códica
    body
        h1= header
        if courses.length === 0
          p Aún no se ha añadido ningún curso
        else
          each course in courses
            div
              h2
                a(href=`/courses/${course.id}`)= course.title
              p= course.description
    

La lógica de salida aquí es la siguiente:

  • Si la lista de cursos está vacía, se muestra un mensaje correspondiente.
  • Si hay cursos en la lista, se generan bloques HTML con información del curso y enlaces a su página a partir de esta lista.

Estas estructuras son suficientes para resolver la mayoría de las tareas estándar.


Materiales adicionales

  1. Pug Sitio web

Para acceder completo a curso necesitas un plan básico

El plan básico te dará acceso completo a todos los cursos, ejercicios y lecciones de Códica, proyectos y acceso de por vida a la teoría de las lecciones completadas. La suscripción se puede cancelar en cualquier momento.

Obtener acceso
130
cursos
1000
ejercicios
2000+
horas de teoría
3200
test

Obtén acceso

Cursos de programación para principiantes y desarrolladores experimentados. Comienza tu aprendizaje de forma gratuita

  • 130 cursos, 2000+ horas de teoría
  • 1000 ejercicios prácticos en el navegador
  • 360 000 estudiantes
Al enviar el formulario, aceptas el «Política de privacidad» y los términos de la «Oferta», y también aceptas los «Términos y condiciones de uso»

Nuestros graduados trabajan en empresas como:

Bookmate
Health Samurai
Dualboot
ABBYY