Pug, que antes se llamaba jade (y mucha información hay que buscarla como "jade"), es un lenguaje que "compila" a HTML, con influencia del CSS.
Por ejemplo, este código de pug:
div.card header h2 Hello section p ¿Qué tal, mundo? footer a.button.up Muy bien a.button.down Podría estar mejor
Compila al siguiente HTML:
<div class="card"> <header> <h2>Hello</h2> </header> <section> <p>¿Qué tal, mundo?</p> <footer> <a class="button up">Muy bien</a> <a class="button down">Podría estar mejor</a> </footer> </div>
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
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):
import ./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: id }, function (err, entry) { res.render('project', entry); }); });