Handlebars.js
All about Handlebars.js
Template Engines π
Express supports template engines such as Pug, EJS, and Handlebars, among others. Called Dynamic HTMLs.
- Useful for reusing repeating HTML layouts in different HTML files in our project and allows us to use JS code into HTML
- So useful!!
Suppose an user access the route /
. Our function app.get
can render html by passing into the response.render()
along with any data or variable.
app.get("/", (request, response) => {
const variables = {
semester: "Summer",
greeting: "Welcome to the course site"
}
response.render("welcome", variables); // Passing variables to welcome.html
});
The semester
and greeting
variables are passed to welcome.html
// welcome.html
<body>
<h1>Introduction (<%= semester %>)</h1>
<p>The usual greeting is <%= greeting %> </p>
</body>
Set Up Template Engines
- In order to use a template engine, we must set this up to our app
- We gonna use
app.set()
, which means "set up this to our app"
To specify the engine template, we gonna do two things:
- Set template engine extension:
.ejs
(from handlerbars)s - Set the folder where EJS files will be located
const express = require('express')
const app = express()
app.set('view engine', '.ejs') // set extension ejs
app.set('views', './pages') // In pages folder are our ejs files
Warning
If you are working on macOS or Windows, use path.resolve
which will give you the full path no matter what OS you working on. This might fix some issues when working with macOS or Windows on the same project.
The path.resolve()
takes two arguments:
pathToProject
- full path of your project. Use__dirname
built-in node variable.folder
- the folder where your HTMLs/Template Engine are located
const path = require('path') //necessary for resolve()
const FULLPATH = path.resolve(__dirname, './pages')
app.set('view engine', '.ejs') // set extension ejs
app.set('views', FULLPATH) // resolved path
Read Input from Forms/Send Data with Template Engine π
Used to parse the data that comes from an HTML form submission. Specifically, it parses application/x-www-form-urlencoded data, which is the default content type when submitting forms via the POST method.
const express = require('express')
const app = express()
const bodyParser = require('body-parser')
// app.use(express.urlencoded({extended:true}))
// If expected forms with complex/nested data -> extended: true
app.use(bodyParser.urlencoded({extended:false}));
// if donβt need to parse complex, nested objects, it keeps the middleware lighter
Our app now can read inputs from user forms, but how can we catch those inputs?
- In a method post (meaning when an user press a submit button), the user inputs will be saved in the
body
, specifically in therequest.body
- We can create an object to store these
request.body.semester
andrequest.body.teacher
- Or we can use destructuring on
request.body
to get these inputs (preference)
app.post("/". (request,resposne) => {
// Using destructuring - Preference
// const {semester,teacher} = request.body
// Using object - Instructor notes
const variables =
{
semester: request.body.semester,
teacher: request.body.teacher
},
// Generate HTML and passing this variables
response.render("courseInfo", variables);
})
But, you may ask, How do I actually know the user's inputs are called semester
and teacher
and are store in the request.body
? The answer: the name
attribute!!
- Note that when user fill the fields
Semeter:
andTeacher:
, these values are store in body asrequest.body.semester
andrequest.body.teacher
semester
andteacher
because of the placeholdername="semester"
andname="teacher"
respectively.- This is how we catch these values into our index.js - app.post()
<form action="http://localhost:7003/" method="post">
<strong>Semester: </strong><input type="text" name="semester">
<strong>Teacher: </strong><input type="text" name="teacher">
<input type="submit" value="Submit Data">
</form>
Now that we have access to user inputs, we can send these variables to another HTML.
In brief, semester
and teacher
from the form will go thru app.post()
, then app.post()
will catch these variables and will send to another HTML using the template engine EJS.
<%= semester %>
means that we gonna replace THIS with an variable calledsemester
<%= teacher %>
means that we gonna replace THIS with an variable calledteacher
<!doctype html>
<html lang="en">
<head>
<title>Course Web Page</title>
<meta charset="utf-8" />
</head>
<body>
<h1>Course Information</h1>
<p>
Additional information for the
<strong> <%= semester %> </strong> semester taught by
<strong> <%= teacher %> </strong> is available on the CS Dept web site.
</p>
</body>
</html>