This recipe demonstrates how to set up Pug as your HTML template engine. In a similar way you can implement a different engine, like Haml.
We assume your directory structure will look something like this:
webapp
└── app
├── about.pug
├── contact.pug
├── index.pug
├── includes
│ ├── footer.pug
│ └── header.pug
└── layouts
└── default.pug
If you had something different in mind, modify paths accordingly.
Install the Pug gulp plugin:
$ npm install --save-dev gulp-pug
Add this task to your gulpfile.js
, it will compile .pug
files to .html
files in .tmp
:
gulp.task('views', () => {
return gulp.src('app/*.pug')
.pipe($.plumber())
.pipe($.pug({pretty: true}))
.pipe(gulp.dest('.tmp'))
.pipe(reload({stream: true}));
});
We are passing pretty: true
as an option to get a nice HTML output, otherwise Pug would output the HTML on a single line, which would break our comment blocks for wiredep and useref.
gulp.task('html', ['views', 'styles', 'scripts'], () => {
...
gulp.task('serve', ['views', 'styles', 'scripts', 'fonts'], () => {
...
We want to parse the compiled HTML:
gulp.task('html', ['views', 'styles'], () => {
var assets = $.useref.assets({searchPath: ['.tmp', 'app', '.']});
- return gulp.src('app/*.html')
+ return gulp.src(['app/*.html', '.tmp/*.html'])
.pipe($.useref({searchPath: ['.tmp', 'app', '.']}))
.pipe($.if('*.js', $.uglify()))
.pipe($.if('*.css', $.cssnano()))
.pipe($.if('*.html', $.htmlmin({collapseWhitespace: true})))
.pipe(gulp.dest('dist'));
});
We don't want to copy over .pug
files in the build process:
gulp.task('extras', () => {
return gulp.src([
'app/*.*',
- '!app/*.html'
+ '!app/*.html',
+ '!app/*.pug'
], {
dot: true
}).pipe(gulp.dest('dist'));
});
Wiredep supports Pug:
gulp.task('wiredep', () => {
gulp.src('app/styles/*.scss')
.pipe(wiredep({
ignorePath: /^(\.\.\/)+/
}))
.pipe(gulp.dest('app/styles'));
- gulp.src('app/*.html')
+ gulp.src('app/layouts/*.pug')
.pipe(wiredep({
exclude: ['bootstrap-sass'],
ignorePath: /^(\.\.\/)*\.\./
}))
- .pipe(gulp.dest('app'));
+ .pipe(gulp.dest('app/layouts'));
});
Assuming your wiredep comment blocks are in the layouts.
Recompile Pug templates on each change and reload the browser after an HTML file is compiled:
gulp.task('serve', ['views', 'styles', 'scripts', 'fonts'], () => {
...
gulp.watch([
'app/*.html',
'app/images/**/*',
'.tmp/fonts/**/*'
]).on('change', reload);
+ gulp.watch('app/**/*.pug', ['views']);
gulp.watch('app/styles/**/*.scss', ['styles']);
gulp.watch('app/scripts/**/*.js', ['scripts']);
gulp.watch('app/fonts/**/*', ['fonts']);
gulp.watch('bower.json', ['wiredep', 'fonts']);
});
To partially automatize this job, you can use html2jade. However, at the time of this writing html2jade has some drawbacks (e.g. doesn't support conditional comments) and the output requires cleanup.
doctype html
html.no-js(lang='')
head
meta(charset='utf-8')
meta(name='description', content='')
meta(name='viewport', content='width=device-width, initial-scale=1')
title webapp
link(rel='apple-touch-icon', href='apple-touch-icon.png')
// Place favicon.ico in the root directory
// build:css styles/vendor.css
// bower:css
// endbower
// endbuild
// build:css styles/main.css
link(rel='stylesheet', href='styles/main.css')
// endbuild
// build:js scripts/vendor/modernizr.js
script(src='/bower_components/modernizr/modernizr.js')
// endbuild
body
<!--[if lt IE 10]>
p.browserupgrade You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.
<![endif]-->
.container
.header
ul.nav.nav-pills.pull-right
li.active: a(href='#') Home
li: a(href='#') About
li: a(href='#') Contact
h3.text-muted webapp
block content
.footer
p ♥ from the Yeoman team
// Google Analytics: change UA-XXXXX-X to be your site's ID.
script.
(function(b,o,i,l,e,r){b.GoogleAnalyticsObject=l;b[l]||(b[l]=
function(){(b[l].q=b[l].q||[]).push(arguments)});b[l].l=+new Date;
e=o.createElement(i);r=o.getElementsByTagName(i)[0];
e.src='https://www.google-analytics.com/analytics.js';
r.parentNode.insertBefore(e,r)}(window,document,'script','ga'));
ga('create','UA-XXXXX-X');ga('send','pageview');
// build:js scripts/vendor.js
// bower:js
script(src='/bower_components/jquery/dist/jquery.js')
script(src='/bower_components/modernizr/modernizr.js')
// endbower
// endbuild
// build:js scripts/plugins.js
script(src='/bower_components/bootstrap-sass/assets/javascripts/bootstrap/affix.js')
script(src='/bower_components/bootstrap-sass/assets/javascripts/bootstrap/alert.js')
script(src='/bower_components/bootstrap-sass/assets/javascripts/bootstrap/dropdown.js')
script(src='/bower_components/bootstrap-sass/assets/javascripts/bootstrap/tooltip.js')
script(src='/bower_components/bootstrap-sass/assets/javascripts/bootstrap/modal.js')
script(src='/bower_components/bootstrap-sass/assets/javascripts/bootstrap/transition.js')
script(src='/bower_components/bootstrap-sass/assets/javascripts/bootstrap/button.js')
script(src='/bower_components/bootstrap-sass/assets/javascripts/bootstrap/popover.js')
script(src='/bower_components/bootstrap-sass/assets/javascripts/bootstrap/carousel.js')
script(src='/bower_components/bootstrap-sass/assets/javascripts/bootstrap/scrollspy.js')
script(src='/bower_components/bootstrap-sass/assets/javascripts/bootstrap/collapse.js')
script(src='/bower_components/bootstrap-sass/assets/javascripts/bootstrap/tab.js')
// endbuild
// build:js scripts/main.js
script(src='scripts/main.js')
// endbuild
extends layouts/default
block content
.jumbotron
h1 'Allo, 'Allo!
p.lead Always a pleasure scaffolding your apps.
p: a.btn.btn-lg.btn-success(href='#') Splendid!
.row.marketing
.col-lg-6
h4 HTML5 Boilerplate
p HTML5 Boilerplate is a professional front-end template for building fast, robust, and adaptable web apps or sites.
h4 Sass
p Sass is the most mature, stable, and powerful professional grade CSS extension language in the world.
h4 Bootstrap
p Sleek, intuitive, and powerful mobile first front-end framework for faster and easier web development.
h4 Modernizr
p Modernizr is an open-source JavaScript library that helps you build the next generation of HTML5 and CSS3-powered websites.
Check if everything is working properly. Run gulp serve
and try changing a .pug
file to see if the page updates etc.
This wasn't exactly the simplest recipe ever; go grab a 🍺 or something.