3: Rutas, Partials y Bootstrap-TAREAS
🎯 Objetivo de esta parte
Aprender a organizar un proyecto Node.js/Express usando:
Carpeta
routes/para separar las rutas del servidorCarpeta
views/partials/para reutilizar componentes HTMLBootstrap para estilos rápidos
Estructura profesional de archivos
1️⃣ Estructura final del proyecto
Basado en tus imágenes, esta es la estructura que lograremos:
ejs-node/
├── node_modules/
├── routes/
│ └── index.js
├── views/
│ ├── partials/
│ │ ├── head.ejs
│ │ └── header.ejs
│ ├── index.ejs
│ └── new-entry.ejs
├── app.js
├── package.json
└── package-lock.json2️⃣ Crear la carpeta routes y el archivo index.js
Paso 1: Crear la carpeta routes
mkdir routesPaso 2: Crear routes/index.js
const express = require('express');
const router = express.Router();
router.get('/', (req, res) => {
res.render('index', {
title: 'Inicio'
});
});
router.get('/new-entry', (req, res) => {
res.render('new-entry', {
title: 'Nueva Entrada'
});
});
module.exports = router;📖 Explicación del código:
| Elemento | Función |
|---|---|
express.Router() | Crea un manejador de rutas independiente |
router.get() | Define rutas dentro de este módulo |
module.exports | Exporta el router para usarlo en app.js |
3️⃣ Modificar app.js para usar las rutas
Actualiza tu app.js para importar y usar el router:
const express = require('express');
const morgan = require('morgan');
const path = require('path');
const bodyParser = require('body-parser');
const app = express();
// Configuraciones
app.set('port', process.env.PORT || 3000);
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'ejs');
// Middlewares
app.use(morgan('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
// Rutas - IMPORTANTE: deben ir después de los middlewares
app.use('/', require('./routes/index'));
// Iniciar servidor
app.listen(app.get('port'), () => {
console.log(`servidor en puerto ${app.get('port')}`);
});🔑 Clave:
app.use('/', require('./routes/index'))le dice a Express que use todas las rutas definidas enroutes/index.jspara las URLs que empiecen con/.
4️⃣ Crear la carpeta partials y sus archivos
Crear la carpeta:
mkdir views/partialsCrear views/partials/head.ejs
Este archivo contendrá todo lo relacionado con <head> y Bootstrap:
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css">
<style>
body {
padding-top: 70px;
}
</style>Crear views/partials/header.ejs
Este es el menú de navegación:
<nav class="navbar navbar-default navbar-fixed-top">
<div class="container">
<div class="navbar-header">
<a class="navbar-brand" href="/">Express GuestBook</a>
</div>
<ul class="nav navbar-nav">
<li><a href="/">Inicio</a></li>
<li><a href="/new-entry">Nueva entrada</a></li>
</ul>
</div>
</nav>5️⃣ Crear las vistas principales
Crear views/index.ejs
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title><%= title %> | GuestBook</title>
<% include partials/head %>
</head>
<body class="container">
<% include partials/header %>
<div class="jumbotron">
<h1>Libro de Visitas</h1>
<p>Bienvenido a nuestro libro de visitas. Deja tu mensaje y lee lo que otros han escrito.</p>
<a href="/new-entry" class="btn btn-primary btn-lg">Escribir mensaje</a>
</div>
<h2>Mensajes recientes</h2>
<div class="alert alert-info">
Próximamente: lista de mensajes
</div>
</body>
</html>Crear views/new-entry.ejs
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title><%= title %> | GuestBook</title>
<% include partials/head %>
</head>
<body class="container">
<% include partials/header %>
<div class="row">
<div class="col-md-6 col-md-offset-3">
<div class="panel panel-default">
<div class="panel-heading">
<h3>Escribe un mensaje</h3>
</div>
<div class="panel-body">
<form action="/add-entry" method="POST">
<div class="form-group">
<label for="title">Título</label>
<input type="text" name="title" id="title" class="form-control" required>
</div>
<div class="form-group">
<label for="message">Mensaje</label>
<textarea name="message" id="message" rows="5" class="form-control" required></textarea>
</div>
<button type="submit" class="btn btn-primary">Guardar mensaje</button>
<a href="/" class="btn btn-default">Cancelar</a>
</form>
</div>
</div>
</div>
</div>
</body>
</html>6️⃣ La sintaxis include en EJS
Observa cómo estamos reutilizando código:
<% include partials/head %>
<% include partials/header %>📖 Beneficios de los partials:
Reutilización: Un mismo menú en todas las páginas
Mantenimiento: Cambias el menú una sola vez
Organización: Código más limpio y ordenado
7️⃣ Probar la aplicación
Iniciar el servidor:
npm run devVerificar las rutas:
http://localhost:3000/→ Página de iniciohttp://localhost:3000/new-entry→ Formulario de nueva entrada
8️⃣ Explicación de las rutas (importante)
En routes/index.js definimos:
| Ruta | Método | Archivo renderizado | URL amigable |
|---|---|---|---|
/ | GET | index.ejs | Página principal |
/new-entry | GET | new-entry.ejs | Formulario |
En app.js conectamos el router:
app.use('/', require('./routes/index'));Esto significa: "Todas las rutas definidas en routes/index.js serán accesibles desde la raíz /".
Si quisieras un prefijo como /api, harías:
app.use('/api', require('./routes/index'));
// Ahora las rutas serían /api/ y /api/new-entry📝 Resumen de lo aprendido
| Concepto | Código clave |
|---|---|
| Router de Express | const router = express.Router() |
| Exportar rutas | module.exports = router |
| Importar rutas | app.use('/', require('./routes/index')) |
| Incluir partials | <% include partials/header %> |
| Pasar título dinámico | { title: 'Inicio' } y <%= title %> |
🎨 Bootstrap incluido
Ya tienes Bootstrap funcionando gracias a partials/head.ejs:
Estilos profesionales
Navbar fijo
Sistema de grillas
Botones y paneles con estilo
🚀 Próximo paso: Recibir datos del formulario (POST)
En la siguiente parte aprenderemos a:
Capturar los datos enviados por el formulario usando
body-parserAlmacenar mensajes en un arreglo
Mostrar la lista de mensajes en la página principal
Redireccionar después de guardar
🔧 Nota sobre body-parser (actualizada)
Siguiendo tus imágenes, mantenemos body-parser. Pero recuerda que en versiones actuales puedes usar:
// En lugar de:
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
// Puedes usar directamente:
app.use(express.json());
app.use(express.urlencoded({ extended: false }));Para la próxima parte (formularios POST), necesitaremos urlencoded() para leer los datos del formulario.
✅ Verifica tu estructura
Tu proyecto debería verse así (como en tus imágenes):
ejs-node/
├── node_modules/
├── routes/
│ └── index.js
├── views/
│ ├── partials/
│ │ ├── head.ejs
│ │ └── header.ejs
│ ├── index.ejs
│ └── new-entry.ejs
├── app.js
├── package.json
└── package-lock.json¿Quieres que continúe con la Parte 4 donde procesamos el formulario POST y mostramos los mensajes guardados?
Completar el formulario en new-entry.ejs
Basado en tus imágenes, este es el formulario completo que debes tener en views/new-entry.ejs:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title><%= title %></title>
<% include partials/head %>
</head>
<body class="container">
<% include partials/header %>
<div class="col-xs-8 col-xs-offset-2">
<h2 class="text-center">Write a new Entry</h2>
<form method="POST" action="/add-entry">
<div class="form-group">
<label for="title">Title:</label>
<input
type="text"
name="title"
id="title"
class="form-control"
placeholder="Enter a new Title"
required>
</div>
<div class="form-group">
<label for="body">Entry Text:</label>
<textarea
class="form-control"
id="body"
name="body"
rows="5"
required></textarea>
</div>
<div class="form-group">
<input type="submit" value="Post Entry" class="btn btn-primary">
<a href="/" class="btn btn-default">Cancel</a>
</div>
</form>
</div>
</body>
</html>📖 Explicación del formulario:
| Atributo | Valor | Función |
|---|---|---|
method | POST | Envía datos ocultos (no en la URL) |
action | /add-entry | URL donde se enviarán los datos |
name="title" | - | Nombre del campo (lo usaremos en el servidor) |
name="body" | - | Nombre del campo para el mensaje |
required | - | El campo es obligatorio (HTML5) |
class="form-control" | - | Estilo de Bootstrap |
Comentarios
Publicar un comentario