Preface
Goal: Build static HTML files using partial Pug utilizing Grunt.
pug
is good for beginner who want to step into templating engine
.
-
First the indented looks, that is entirely different with
html
. -
Second, it just works with Command Line Interface. No need third party tools such as
grunt
orgulp
.
Unfortunately, not all html processor
as easy as pug
.
So for the rest of the chapter here,
we are going to build html
using grunt
.
Official Documentation
Pug With Grunt
I have already wrote an article about pug
here:
Along with an example of how to build grunt
.
Source Examples
You can obtain source examples here:
1: Pug Case
We use pug
as html preprocessor
to build html
documents.
Consider transform our last HTML Case into Pug Case.
Install
$ npm i -g pug-cli
Directory Structure
Consider pug
structure.
└── views
├── css.pug
├── html.pug
├── index.pug
├── javascript.pug
├── partials
│ ├── head.pug
│ ├── layout.pug
│ ├── navbar.pug
│ └── sidebar.pug
└── php.pug
We want the pug
to build html
artefacts as below:
└── build
├── css.html
├── html.html
├── index.html
├── javascript.html
└── php.html
Now we can separate each html parts.
Layout
doctype html
html(lang="en")
- var title = "Link Example: Default"
head
include head.pug
body
include sidebar.pug
#main
include navbar.pug
.w3-container
block content
p Default Page
As shown in order we have three include
artefacts.
include head.pug
,include sidebar.pug
,include navbar.pug
,
One variable named title
,
- var title = "Link Example: Default"
And one block named content
.
block content
p Default Page
Head
It is a simple pug
translation.
meta(charset='utf-8')
block title
title= title
meta(name='viewport', content="width=device-width, initial-scale=1")
link(href='https://www.w3schools.com/w3css/4/w3.css', rel='stylesheet', type='text/css')
script(src='../js/script.js')
script(src='//localhost:35729/livereload.js')
Here we put the title
variable inside a block named title
.
block title
title= title
I also add livereload
for use with grunt
later.
Sidebar
It is simply a html
tag in pug
. Nothing special.
#mySidebar.w3-sidebar.w3-bar-block.w3-card.w3-animate-left(style='display:none')
button#closeNav.w3-bar-item.w3-button.w3-large
| Close ×
a.w3-bar-item.w3-button(href='index.html')
| Home
a.w3-bar-item.w3-button(href='html.html')
| HTML Link
a.w3-bar-item.w3-button(href='css.html')
| CSS Link
a.w3-bar-item.w3-button(href='php.html')
| PHP Link
a.w3-bar-item.w3-button(href='javascript.html')
| Javascript Link
Navbar
It is also simply a html
tag in pug
. Nothing special either.
.w3-teal
button#openNav.w3-button.w3-teal.w3-xlarge
| ☰
.w3-container
h1 My Page
.w3-bar.w3-black
a.w3-bar-item.w3-button.w3-large(href='index.html')
| Home
a.w3-bar-item.w3-button.w3-large(href='html.html')
| HTML
a.w3-bar-item.w3-button.w3-large(href='css.html')
| CSS
a.w3-bar-item.w3-button.w3-large(href='php.html')
| PHP
a.w3-bar-item.w3-button.w3-large(href='javascript.html')
| Javascript
Index
By extending the partials/layout.pug
,
we can alter the content of each block: title
and content
.
extends partials/layout.pug
block title
title Link Example: Home
block content
p Home Page
2: Pug Content Propagation
How does it works ?
Block and Inheritance
In partials/layout.pug
we have this block.
#main
include navbar.pug
.w3-container
block content
p Default Page
Then we can replace the content,
of the block in child layout index.pug
.
extends partials/layout.pug
block content
p Home Page
Title: Using Variable
Variable Propagation Between Template
In partials/layout.pug
we have this variable.
- var title = "Link Example: Default"
This should work perfectly with include partials/head.pug
title= title
But unfortunately, pug
cannot have variable,
in top level of extended files.
This means we cannot alter the default variable.
Title: Using Block
The solution is to wrapped the content in block
instead.
As in index.pug
below:
block title
title Link Example: Home
The partials/head.pug
would be
block title
title Link Example: Default
Or if you wish to use default variable.
block title
title =title
Where the title
variable comes from partials/layout.pug
.
Main Files
This time, all the main files can be so short as below:
extends partials/layout.pug
block title
title Link Example: CSS
block content
p CSS Page
extends partials/layout.pug
block title
title Link Example: PHP
block content
p PHP Page
Result
Finally we can check if the result is right in build/index.html
.
<!DOCTYPE html>
<html lang="en"></html>
<head>
<meta charset="utf-8">
<title>Link Example: Home</title>
...
</head>
<body>
...
<div id="main">
...
<div class="w3-container">
<p>Home Page</p>
</div>
</div>
</body>
3: Grunt Configuration
Command Line Interface
Without grunt
, you can run pug
in command line interface.
$ cd views
$ pug -w -P -p . -o ../build *.pug
- .
Now consider discuss this grunt
stuff.
package.json
All you need to know is the devDependencies
.
"devDependencies": {
"grunt": "^1.0.1",
"grunt-contrib-pug": "^2.0.0",
"grunt-contrib-watch": "^1.1.0",
"pug": "^2.0.4"
}
To begin with grunt
, you need to run npm install
first.
Gruntfile.js
You also need to a configuration file named Gruntfile.js
.
module.exports = function(grunt) {
// configure the tasks
let config = {
pug: {
compile: {
options: {
data: {
debug: false
},
pretty: true
},
files: [ {
cwd: "views",
src: "*.pug",
dest: "build",
expand: true,
ext: ".html"
} ]
}
},
watch: {
pug: {
files: ['views/**/*'],
tasks: ['pug'],
options: {
livereload: true,
interrupt: false,
spawn: false
}
}
}
};
grunt.initConfig(config);
// load the tasks
grunt.loadNpmTasks('grunt-contrib-pug');
grunt.loadNpmTasks('grunt-contrib-watch');
// define the tasks
grunt.registerTask('default', [
'pug', 'watch'
] );
};
The configuration is self explanatory.
Just read the official documentation of grunt-contrib-pug
.
Running Grunt
Now you can build your own static html
files using pug
.
What’s Next?
We still have three grunt
example: nunjucks
, EJS
and handlebars
.
Consider continue reading [ Template - Grunt - Nunjucks ].