Al estar usando un motor de plantillas (en este caso Pug) podemos modularizar distintos elementos del html separándolos en distintos archivos. A esto le llamaremos partials. Los partials serán aquellos elementos comunes de varias páginas, como por ejemplo, la barra de navegación, el footer o un módulo para mostrar mensajes flash.
Crearemos un directorio llamado partials dentro de la carpeta views. En este directorio albergaremos todos los siguientes ficheros.
La barra de navegación es un elemento indispensable en la mayoria de Aplicaciones Web. Además nos ayudará a desarrollar al permitirnos navegar por nuestra aplicación más fácilmente, sin tener que estar escribiendo la url de las distintas zonas constantemente.
El primer partial que vamos a crear será navBar.pug. El contenido de dicho archivo será:
nav.navbar.navbar-default
.container-fluid
.navbar-header
button(type="button", data-toggle="collapse", data-target="#navbar").navbar-toggle.collapsed
span.icon-bar
span.icon-bar
span.icon-bar
a(href="/").navbar-brand Home
div(id="navbar").collapse.navbar-collapse
ul.nav.navbar-nav.navbar-right
li
a(href="/users") Usuarios
if(user)
li.dropdown
a(href="#", data-toggle="dropdown", role="button").dropdown-toggle=user.name
span.caret
ul.dropdown-menu
li
a(href="/auth/logout") Logout
else
li.dropdown
a(href="#", data-toggle="dropdown", role="button").dropdown-toggle Enter
span.caret
ul.dropdown-menu
li
a(href="/auth/login") Login
a(href="/auth/register") Register
Usando Bootstrap hemos creado una barra de navegacion sencilla. En ella hemos creado un enlace hacia las rutas que tenemos desarrolladas. Hemos controlado si un Usuario esta logado o no para mostrarle en la barra de navegacion los enlaces apropiados segun su estado .
A partir de ahí, podéis ir añadiendo nuevos links hacia nuevas zonas de la aplicacion que vayais desarrollando.
En este pequeño apartado simplemente desacoplaremos el footer de la plantilla base. Editaremos el fichero layout.pug y cortaremos las líneas que definen al footer. Seguidamente, crearemos un fichero footer.pug en el directorio partials con el contenido cortado:
footer
.center-block
span © ExpressDev all rights are not reserved
Así, ya tenemos al footer en su propio archivo.
Editaremos el layout.pug para incluir los dos partials que acabamos de crear:
doctype html
html
head
title= title
link(rel='stylesheet', href='/css/main.css')
body
include partials/navbar
block content
include partials/footer
script(src='/js/main.js')
block scripts
Perfecto, ahora procederemos a crear un partial más, encargado de suministrar mensajes flash a los usuarios.
Los mensajes flash son geniales. Sirven para realizar notificaciones rápidas a los usuarios, informandoles de algún detalle, como por ejemplo, cuando se han logado o deslogado, o cuando ha habido un error. Este tipo de mensajes sólo debe existir por un periódo breve de tiempo y para ello, emplearemos un paquete especial llamado Express Flash. Lo instalamos con:
npm install -S express-flash
Y lo añadimos a nuestra Aplicación editando app.js:
...
const flash = require('express-flash');
...
app.use(session({
secret: 'keyboard cat',
resave: false,
saveUninitialized: false
}));
app.use(flash()); // <-- Nuevo
app.use(passport.initialize());
...
Ahora crearemos el partial encargado de mostrar los mensajes. Crearemos un archivo flash.pug y le añadiremos el siguiente contenido:
if(messages.info)
.flash-message.alert.alert-info
button(data-dismiss="alert").close
span(aria-hidden="true") ×
span= messages.info
if(messages.success)
.flash-message.alert.alert-success
button(data-dismiss="alert").close
span(aria-hidden="true") ×
span= messages.success
if(messages.error)
.flash-message.alert.alert-danger
button(data-dismiss="alert").close
span(aria-hidden="true") ×
span= messages.error
Hemos creado tres tipos de mensajes, que simplementen muestran un mensaje usando los alert de Bootstrap. Comparten mucho código, por lo que podría refactorizarse por algo mejor, pero por ahora, lo dejaremos así.
Les crearemos un estilo en un archivo _flash-message.scss dentro de nuestro directorio partials. Escribiremos:
.flash-message{
text-align: center;
max-width: 300px;
position: absolute;
top: 0;
right: 0;
left: 0;
margin: 10px auto;
}
@import "./partials/flash-message";
Tampoco olvides incluir todo este partial en el layout.pug.
...
include partials/navbar
include partials/flash
...
Ahora modificaremos el AuthCtrl.js para que registre mensajes haciendo uso del módulo Express Session. Lo editamos añadiendo las siguientes líneas:
En la función register() ponemos:
req.login(user, function(err) {
if (err) console.log(err);
req.flash('success', `Welcome ${user.name}!`); // <-- Nuevo
console.log(`User ${req.user.name} registered`);
return res.redirect('/'); //res.redirect('/users/' + req.user.username);
});
Modificamos la función de login() con:
module.exports.login = (req, res, next) => {
passport.authenticate('local', function(err, user, info) {
if (err) { return next(err); }
if (!user) {
req.flash('error', `Error: ${info.message}!`); // <-- Nuevo
return res.redirect('/auth/login');
}
req.logIn(user, function(err) {
if (err) { return next(err); }
//return res.redirect('/users/' + user.username);
req.flash('success', `Hi ${user.name}!`); // <-- Nuevo
console.log(`User ${req.user.name} logged in`);
return res.redirect('/');
});
})(req, res, next);
};
Y tambien modificamos la funcion de logout():
module.exports.logout = (req, res) => {
console.log(`User ${req.user.name} logged out`);
req.flash('info', `Goodbye ${req.user.name}!`); // <-- Nuevo
req.logout();
res.redirect('/');
};
Tras reiniciarse el servidor, podremos ver algunos mensajes flash !
Podemos seguir mejorando el sistema de mensajes flash añadiendo animaciones. Como ejemplo, vamos a usar una librería excelente que trae consigo un montón de animaciones en CSS. Esta es AnimateCSS.
Para incluirla en el proyecto, primero deberemos instalarlo, en este caso usaremos la versión sass:
npm install -S animate.scss
Ahora, crearemos un fichero _animations.scss dentro de sass/globals con:
// Base
@import "../../../node_modules/animate.scss/vendor/assets/stylesheets/animate";
// Animations
@import "../../../node_modules/animate.scss/vendor/assets/stylesheets/animate/fadeIn";
Y no nos olvidamos de incluir la importación en nuestro main.scss:
@import "./globals/animations";
Con esto, entonces, editamos nuestro partial _flash-message.scss para añadir la animación:
.flash-message{
@include animate(fadeIn, 1s); // <-- Nuevo
text-align: center;
max-width: 300px;
position: absolute;
top: 0;
right: 0;
left: 0;
margin: 10px auto;
}
Y ya está! Ahora nuestros mensajes flash harán un fade cada vez que aparezcan!