Jade, que acaban de cambiarle el nombre a Pug (pero mucha información hay que buscarla como "jade"), es un lenguaje que compila a HTML, con una sintaxis con influencia de python y CSS.
Por ejemplo, este código de HTML:
<div class="card"> <header> <h2>Hello</h2> </header> <section> <p>¿Qué tal, mundo?</p> </section> <footer> <a class="button up">Muy bien</a> <a class="button down">Podría estar mejor</a> </footer> </div>
Se escribiría así en jade:
div.card header h2 Hello section p ¿Qué tal, mundo? footer a.button.up Muy bien a.button.down Podría estar mejor
Instalar Jade
Primero tendremos que instalar Jade y configurarlo:
npm install jade --save
Después tendremos que decirle a express que use jade dentro de app.js:
app.set('views', './views'); app.set('view engine', 'jade');
DRY (Don't Repeat Yourself)
Pug tiene un potente motor para no tener que repetir bloques con estructuras de control. Por ejemplo, para mostrar todas las entradas de blog en una página web lo podríamos hacer así:
each entry in posts div.card(data-id=entry._id) header h2= entry.title section= entry.body
La principal diferencia con el HTML estático es que creamos una plantilla que se rellena con la información almacenada en la base de datos (strings, números....) tantas veces como objetos post tengamos almacenados en la bbdd. La ventaja de esto es que si tenemos 50 post no tendremos que copiar y pegar el código HTML de cada elemento 50 veces.
Otra forma de no repetirte es no tener que hacer copy/paste de las partes en común del HTML. Por ejemplo, nos definiríamos un archivo en común llamado "layout.jade" el cual extenderíamos en otros. Para el mismo ejemplo de layout del HTML inicial:
doctype html html head title Página Web meta(charset="utf-8") meta(name='viewport' content='width=device-width, initial-scale=1') link(rel="stylesheet" href="https://cdn.jsdelivr.net/picnicss/4.1.1/plugins.min.css") link(rel="stylesheet" href="style.css") body block content
Este último block content
es donde pondremos nuestro contenido. Para usar este layout desde otras páginas, tenemos que poner (por ejemplo en index.jade):
extend ./layout.jade block content p Hola!
Lo mismo podemos hacer si queremos por ejemplo editar el title dentro del header, solo que esta vez sí que definiremos uno por defecto en layout.jade:
doctype html html head block title title Mi Web meta(charset="utf-8") meta(name='viewport' content='width=device-width, initial-scale=1') link(rel="stylesheet" href="https://cdn.jsdelivr.net/picnicss/4.1.1/plugins.min.css") link(rel="stylesheet" href="style.css") body block content
Y después, cuando queramos cambiar el title en una página en concreto, como en index.jade:
extend ./layout.jade block title title Índice de la web - Mi Web block content p Hola! Mostrando la lista de proyectos: // ...
Y en project.jade:
extend ./layout.jade block title title= project.title + " - Mi Web" block content h2= project.title article= project.body
Incluir datos
Pero, ¿de dónde salen estos datos y variables? Pues hay que pasárselos desde el javascript del servidor (en app.js o desde el controlador). Veamos una sencilla ruta para la página principal en app.js:
app.get('/', function (req, res) { Posts.find({}, function (err, posts) { res.render('index', { posts: posts }); }); });
Y ahora un pequeño ejemplo para projects.jade en app.js:
app.get('/project/:id', function (req, res) { Posts.find({ _id: req.params.id }, function (err, entry) { res.render('project', entry); }); });
Estructura de archivos
Creamos una carpeta que se llame "views", movemos todos los archivos HTML que tengamos y si no los tenemos creamos los siguientes dentro de la carpeta views:
- layout.jade
- index.jade
- project.jade