Preface
Goal: Feeding Data in ExpressJS, and Process in a Loop with Handlebars.
Consider continue with handlebars
example.
This should be the easiest part,
because official express
example is using handlebars
.
Official Documentation
Source Examples
You can obtain source examples here:
Handlebars Case
The handlebars
case is the same,
with the one utilizing grunt
in previous article
with a few differences.
-
express
configuration -
Using data to provide hyperlink in both
navbar
andsidebar
.
Directory Structure
Consider an express
structure with handlebars
views.
❯ tree
.
├── app.js
├── package.json
├── public
│ ├── css
│ │ └── w3.css
│ ├── favicon.ico
│ └── js
│ └── script.js
└── views
├── css.hbs
├── html.hbs
├── index.hbs
├── javascript.hbs
├── partials
│ ├── head.hbs
│ ├── layout.hbs
│ ├── navbar.hbs
│ └── sidebar.hbs
└── php.hbs
5 directories, 14 files
The views
structure is similar to previous case with grunt
.
I suggest that you have fast reading for this article first.
package.json
All you need to know is the devDependencies
.
"devDependencies": {
"express": "^4.17.1",
"handlebars": "^4.7.6"
},
To begin with expressjs
, you need to run npm install
first.
app.js
You also need to a write a simple application in app.js
.
// Basic Stuff
var express = require('express');
var path = require('path');
var app = express();
app.set('views', path.join(__dirname, 'views'));
app.use(express.static(path.join(__dirname, 'public')));
app.locals.pretty = true;
// Handlebars Configuration
var exphbs = require('express-handlebars');
app.set('view engine', 'hbs');
app.set('view options', { layout: 'partials' });
app.engine('.hbs', exphbs({
layoutsDir : 'views/partials/',
partialsDir : 'views/partials/',
defaultLayout: 'layout',
extname : '.hbs'
}));
// Example Pages
var pages = [
{ link: '/', short: 'Home', long: 'Home' },
{ link: '/html', short: 'HTML', long: 'HTML Link' },
{ link: '/css', short: 'CSS', long: 'CSS Link' },
{ link: '/php', short: 'PHP', long: 'PHP Link' },
{ link: '/javascript', short: 'Javascript', long: 'Javascript Link' }
];
// Router
app.get('/', function(req, res) {
res.render('index', { pages: pages, layout: false });
console.log("choice page is index");
});
const choices = ['index', 'html', 'css', 'php', 'javascript'];
app.get('/:page', function(req, res) {
page = req.params.page;
if (choices.includes(page)) {
res.render(page, { pages: pages, layout: false });
console.log("choice page is " +page);
} else {
res.send('404: Page not Found', 404);
}
});
// Run, Baby Run
app.listen(3000);
console.log('Express started on port 3000');
The application is short enough to be self explanatory.
Handlebars Template Specific Code
Different with the pug
or EJS
example,
we need a longer configuration for handlebars
.
var exphbs = require('express-handlebars');
app.set('view engine', 'hbs');
app.set('view options', { layout: 'partials' });
app.engine('.hbs', exphbs({
layoutsDir : 'views/partials/',
partialsDir : 'views/partials/',
defaultLayout: 'layout',
extname : '.hbs'
}));
Beware of the partials
registering parts.
Also if you are using extension other than .handlebars
such as .hbs
,
then you require more effort to pick the correct configuration.
Hyperlink Data
The same for every templates
To provide hyperlink in both navbar
and sidebar
,
we need to setup the data in app.js
as below:
var pages = [
{ link: '/', short: 'Home', long: 'Home' },
{ link: '/html', short: 'HTML', long: 'HTML Link' },
{ link: '/css', short: 'CSS', long: 'CSS Link' },
{ link: '/php', short: 'PHP', long: 'PHP Link' },
{ link: '/javascript', short: 'Javascript', long: 'Javascript Link' }
];
We will feed the data for each request.
app.get('/', function(req, res) {
res.render('index', { pages: pages, layout: false });
console.log("choice page is index");
});
The sidebar
will use long
text,
and the navbar
will use short
one.
Router
Almost the same for every templates
For simplicity, I put all the routes in app.js
.
app.get('/', function(req, res) {
res.render('index', { pages: pages, layout: false });
console.log("choice page is index");
});
const choices = ['index', 'html', 'css', 'php', 'javascript'];
app.get('/:page', function(req, res) {
page = req.params.page;
if (choices.includes(page)) {
res.render(page, { pages: pages, layout: false });
console.log("choice page is " +page);
} else {
res.send('404: Page not Found', 404);
}
});
Beware that handlebars
require the layout
to be set as false
.
res.render('index', { pages: pages, layout: false });
If the request does not contain any of the above page,
express
will send 404
error response.
Loop in Template
This time, consider alter a bit,
both the sidebar
and the navbar
,
so we can render each data in loop.
<div class="w3-sidebar w3-bar-block w3-card w3-animate-left"
style="display:none" id="mySidebar">
<button class="w3-bar-item w3-button w3-large"
id="closeNav" >Close ×</button>
{{#each pages}}
<a class="w3-bar-item w3-button"
href="{{link}}">{{long}}</a>
{{/each}}
</div>
<div class="w3-teal">
<button class="w3-button w3-teal w3-xlarge"
id="openNav">☰</button>
<div class="w3-container">
<h1>My Page</h1>
</div>
</div>
<div class="w3-bar w3-black">
{{#each pages}}
<a class="w3-bar-item w3-button"
href="{{link}}">{{short}}</a>
{{/each}}
</div>
All you need to know is these lines:
{{#each pages}}
<a class="w3-bar-item w3-button"
href="{{link}}">{{short}}</a>
{{/each}}
This will render a hyperlink, with result about the same with previous example.
Running Express
Running express is as easy as this command below.
$ node app.js
Click any hyperlink on the example case,
and you will get the response in console.log
immediately.
You are ready to run a website,
with expressjs
backend, using handlebars
.
What’s Next?
After ExpressJS
we can move on to other popular NodeJS
called KoaJS
.
Consider continue reading [ Template - Koa ].