Pug, antes llamado Jade, es el motor de plantillas por defecto de ExpressJS. Al comienzo, puede ser un poco complicado de usar, requiere un periódo de aprendizaje hasta que podamos hacernos con su sintaxis. Pero una vez dominado no querremos dejar de escribir con él, su minimalismo y su obligatoria indentación hacen que generemos un código muy ligero y limpio, por lo tanto, es muy recomendable darle una oportunidad.
Necesitamos crear varios archivos para las vistas de la lógica que ya tenemos en el Servidor. Dentro del directorio views crearemos una carpeta users, y dentro de ella, ubicaremos dos archivos index.pug y show.pug.
Antes de continuar vamos a crear una tarea Gulp que nos va a ayudar a agilizar el proceso de
creación de vistas. Al crear Vistas estamos abordando el desarrollo Front-End de la Aplicación, donde
tocaremos varios archivos css y js. Con cada modificación de estos archivos que hagamos, será necesario
recompilar todo el código lanzando la tarea por defecto que tenemos definida, mediante el comando gulp
.
Estar escribiendo constantemente dicho comando puede ser demasiado tedioso, por esta razón, usaremos una oportuna funcionalidad de gulp llamada watch que básicamente se encargará de escuchar los archivos indicados ante cualquier cambio, para seguidamente ejecutar alguna tarea que le indiquemos.
Editaremos nuestro gulpfile.js para añadir dicha tarea, tal que así:
/**
* GULP WATCHER TASKS
*/
gulp.task('watch', () => {
gulp.watch('resources/js/**/*.js', ['scripts']);
gulp.watch('resources/sass/**/*.scss', ['sass']);
});
Ejecutamos la tarea:
gulp watch
Con esto se estarán observando todos los ficheros .js y .scss del front-end. Cada vez que uno de esos archivos sea modificado, se lanzará la tarea correspondiente con su compilación. De este modo podemos ir realizando cambios en los ficheros del front-end sin preocuparnos por estar compilando los archivos a cada rato.
La primera vista que vamos a tratar será la encargada de listar a todos los usuarios de nuestra BBDD. Para ello, editaremos el archivo views/users/index.pug con:
extends ../layout
block content
.container
h1 Usuarios
each user in users
.col-xs-6.col-sm-4.col-md-3
.users-box
span.user-name=user.name
span.user-email=user.email
En esta vista estamos recorriendo una variable users, que será nuestro array de Usuarios. Seguidamente sólo imprimimos su name y su nombre.
No debemos olvidar que ahora hay que modificar el archivo server/controllers/UsersCtrl.js en el
método getUsers(), modificaremos la línea res.json()
para que ahora sea así:
res.render('users/index', {users: users});
De este modo, en lugar de devolver un JSON, devolveremos una vista (en concreto views/users/index.pug).
Finalmente, añadiremos un poco de estilo. Para ello crearemos un directorio partials dentro del directorio resources. Dentro del directorio partials crearemos un archivo con el nombre _users-box.scss y lo editaremos con el siguiente contenido:
.users-box{
height: 80px;
padding: 10px;
margin: 10px;
box-shadow: -5px 5px 10px black;
background: white;
&:hover{
background: #EEE;
cursor: pointer;
}
.user-name, .user-email{
color: black;
display:block;
}
.user-name{
font-weight: 600;
}
}
No olvidemos importar nuestro fichero en el main.scss!
...
@import "../../node_modules/font-awesome/scss/font-awesome";
@import "./partials/users-box";
html, body{
height: 100%
}
...
Compilamos todo con gulp
y accedemos a la url /users
para ver el resultado:
Ha quedado genial verdad? Un listado con nuestro usuarios.
Para la vista que muestra un único usuario, simplemente pondré esto:
extends ../layout
block content
.container
.users-box
span.user-name=user.name
span.user-email=user.email
Y no nos olvidamos de modificar el controlador UsersCtrl.js, en el método, showUser(), para
que devuelva la vista res.render('users/show', {user: user});
.
module.exports.showUser = (req, res) => {
var user = User.findOne({email: req.params.email}, function (err, user) {
if(err) console.log(err);
res.status(200);
res.render('users/show', {user: user});
});
}
Es importante el método findOne de Mongoose, que nos permitirá obtener un único registro en lugar de un array como ocurre con find().
Ahora vamos a proceder a crear la vista del formulario de Login. Crearemos un directorio auth dentro de views y en él crearemos un archivo login.pug. El contenido de esta vista será:
block content
.container
form.small-form(action="/auth/login", method="post")
h1 Login
.form-group
label.control-label Email
input(type="email", name="email" required).form-control
.form-group
label.control-label Password
input(type="password", name="password" required).form-control
button.btn.btn-primary Submit
module.exports.getLogin = (req, res) => {
res.render('auth/login', {});
};
Esto quiere decir que accederemos a dicha ruta mediante la url localhost:3000/auth/login
Agregaremos un poco de estilo. Crearemos un archivo _forms.scss dentro de resources/sass/globals. En este archivo escribiremos:
.small-form{
max-width: 600px;
margin: 0 auto;
}
Con esto, visualizaríamos un formulario así:
*Hice un pequeño ajuste al footer para centrarlo (en un archivo resources/sass/globals/_footer.scss como debes de suponer ya).
footer{
margin-top: 30px;
text-align: center;
}
Ahora, introduciendo las credenciales adecuadas (email de algún Usuario de la BBDD y de pass 123456) podremos logarnos! Si lo hacemos, en la consola del servidor veremos un mensaje indicando qué usuario se ha logado.
Finalmente, nos falta la vista del Registro, un formulario con todos los campos necesarios para que un Usuario se registre en nuestra aplicación. En este archivo register.pug escribiremos:
extends ../layout
block content
.container
form.small-form(action="/auth/register", method="post")
h1 Register
.form-group
label.control-label Name
input(type="text", name="name").form-control
.form-group
label.control-label Email
input(type="email", name="email").form-control
.form-group
label.control-label Password
input(type="password", name="password").form-control
.form-group
label.control-label Password confirmation
input(type="password", name="password_confirmation").form-control
button.btn.btn-primary Submit
Y ya esta! Con esta vista, ya podrá registrarse nuestros Usuarios. Este formulario hace un POST a la url /auth/register donde es recibido por nuestro AuthCtrl.js con su método register(). Este método register() guarda al Usuario en la BBDD y seguidamente lo loguea automáticamente.
Nos quedaría realizar validaciones en el servidor para segurarnos de que los datos recibidos cumplen con ciertas normas (el email es un email real, no están vacíos, etc) pero eso lo dejaremos para más adelante. El código, una vez más aquí.