Pug: A HTML Templating Language
Tags: webdev, html, pug, tutorial
Published: 2023-01-03 10:00:00

This series builds on my post, [Supercharge Your Web Dev Workflow With Emmet](https://dev.to/jessewei/supercharge-your-web-dev-workflow-with-emmet-3cg4), to which [Maciek Fitzner](https://dev.to/mackfitz) posted a comment mentioning [Pug](https://pugjs.org/api/getting-started.html).

Templating languages are widely used in Web development and two of the most popular ones are [Pug](https://pugjs.org/api/getting-started.html) and [Slim](https://github.com/slim-template/slim). In this series, we're going to learn the basics of these two and hopefully they would help improve your workflow further. 


## Table of Contents

- [Emmet vs. Templating Languages](#emmet-vs-templating-languages)
- [Meet Pug](#meet-pug)
  * [An Overview](#an-overview)
  * [How It Works](#how-it-works)
- [Start a Pug Project](#start-a-pug-project)
- [Next Steps](#next-steps)

---

## Emmet vs. Templating Languages

The fundamental difference between Emmet and templating languages like Pug and Slim is that,

- With the former which is just an editor extension, we write abbreviations which expand to full HTML code instantly when we press TAB. So we're basically **still writing in HTML**.
- The latter, however, are different languages than HTML and have their own syntax. This means these template files must be **converted (compiled, as we call it in the programming world) to HTML** before being forwarded to browsers to render.

It should be noted that many templating languages do not only support HTML, but can generate other types of files as well. In this series, however, we'll focus on HTML.

---

## Meet Pug

### An Overview

[Pug](https://pugjs.org/api/getting-started.html) is a templating language for Node.js and the browser. It is often used to generate HTML, but it can also be used to generate XML or other types of documents.

### How It Works

Here's an example of a simple Pug template that generates an HTML page with a heading and a paragraph:

```pug
doctype html
html
  head
    title My Site
  body
    h1 Hello, World!
    p This is my site.
```

This template would be _compiled_ into the following HTML:

```html
<!DOCTYPE html>
<html>
  <head>
    <title>My Site</title>
  </head>
  <body>
    <h1>Hello, World!</h1>
    <p>This is my site.</p>
  </body>
</html>
```

The rendered page from the HTML looks like this:


![Rendered page from sample](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/4kx3e9wk3xstl5q5b0of.png)


<figcaption>Rendered page from sample</figcaption>

As the example demonstrates, Pug uses a combination of whitespace, indentation, and special characters to distinguish between HTML elements, code blocks, and other constructs.

The Pug file is then _compiled_ into HTML files before being served to the browser for rendering. In fact, all templating languages work in similar manner because browers can only read HTML.

![How Pug works](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/qx3xeee5l6x689p9xdbh.png)

<figcaption>How Pug works</figcaption>

---

## Start a Pug Project

Before starting a pug project, make sure you have Node.js installed in your computer. Installation of Node.js is beyond this post, so do a bit of googling if you need any help.

Follow these steps to start a new Pug project:

**Step 1:**

Create a new directory for your project and navigate to it in the terminal. For example:

```bash
mkdir ~/my-pug-project
cd ~/my-pug-project
```

**Step 2:**

Initialize the project by creating a `package.json` file in your project root and install the Pug package. For example:

```bash
npm init -y
npm install pug
```

Or if you choose to use `yarn`:

```bash
yarn init -y
yarn add pug
```

**Step 3:**

Create a directory in your project root to hold your Pug templates and create a pug file in it:

```bash
mkdir views
touch views/index.pug
```

Then give the new file the following content:

```pug
doctype html
html
  head
    title My Site
  body
    - var name = 'Jesse'
    h1 Hello, #{name}!
    p
      | This is my site. It is powered by
      |
      strong Pug
      | .
    - var users = ['Alice', 'Bob', 'Charlie', 'Dan']
    ul
      each user in users
        li= user
    if users.length > 3
      p There are more than 3 users in the list.
    else
      p There are 3 or fewer users in the list.
```

In this pug file, we used some more advanced features of Pug such as [variables](https://pugjs.org/language/interpolation.html), [piped text](https://pugjs.org/language/plain-text.html#piped-text), [iteration](https://pugjs.org/language/iteration.html) and [conditionals](https://pugjs.org/language/conditionals.html). If you want to further familiarize yourself with these concepts, check out the links.

Our pug template generates the following HTML code:

```html
<!DOCTYPE html>
<html>
  <head>
    <title>My Site</title>
  </head>
  <body>
    <h1>Hello, Jesse!</h1>
    <p>This is my site. It is powered by
      <strong>Pug</strong>.
    </p>
    <ul>
      <li>Alice</li>
      <li>Bob</li>
      <li>Charlie</li>
      <li>Dan</li>
    </ul>
    <p>There are more than 3 users in the list.</p>
  </body>
</html>
```

**Step 4:**

We need a server to compile our Pug file into HTML file, so at our project root, create a `server.js` file:

```bash
touch server.js
```

And add the following content to it:

```javascript
const express = require('express');
const app = express();

// Set the view engine to pug
app.set('view engine', 'pug');

// Set the views directory
app.set('views', './views');

// Define a route for the home page
app.get('/', (req, res) => {
  res.render('index');
});

// Start the server
const port = process.env.PORT || 3000;
app.listen(port, () => {
  console.log(`Listening on port ${port}...`);
});
```

As we're using the `express` package here, we need to install it:

```bash
npm install express
```

Or:

```bash
yarn add express
```

If you need help with `express` or want to learn more about it, check out its [official docs](https://expressjs.com/).

**Step 5:**

Start the server by running:

```bash
node server.js
```

Now go to http://localhost:3000 and boom! Our page should be rendered properly like this:


![Rendered page from advanced example](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/0jjacfigke44vlg5ankd.png)

<figcaption>Rendered page from advanced example</figcaption>

---

## Next Steps

In the first part of the series, we learned the basics of Pug, a popular templating language for generating HTML. We saw some simple but inspiring examples that should be enough to help you get started.

If you want to dive a bit deeper into Pug, I'd recommend you have a look at their [docs](https://pugjs.org/api/getting-started.html). Each of the topics is explained with code examples that you can try out instantly.

In the next part, I'll walk you through another templating language, Slim. So please follow me to stay tuned.