3: Rutas, Partials y Bootstrap
馃幆 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