Day 41: Treehouse Full Stack JavaScript Techdegree

Express Basics Continuation

Today I learned about template rendering and using Pug with Express.

What is template rendering?

The HTML we serve from an app usually never change. If a user views photos in a gallery, the photos change. But the HTML of the gallery never changes. The caption or content-specific information may change but the overall structure or html of the photo gallery would remain the same.

Web frameworks handles this situation by using templates.

A template provides basic HTML for your app and serves it to users.

Templates also let you vary the output to provide customized responses — for example displaying usernames

Templates are a special type of file that have their own syntax and language — they live on the server and act as some kind of form letter for your HTML. It is like an HTML page with blanks and we could fill those blanks with the information / variables to the template. Then the result is a full HTML page sent to the client

The process is called rendering the template — Because the result is what the client sees on their screens templates are referred to as views.

JavaScript Template languages

  • Handlebars
  • EJS
  • Pug (formerly Jade)

We can use any templating engine with Express. But Pug is the most popular

— —

Templates are stored on the server

— — -

What is Pug?

Pug is one of the most popular templating engines for node. Commonly used for express.

Pug is a language that combines or translates to HTML

Instead of using opening and closing tags we just use the tag name then a space then the content:

h1 I love treehouse

For nested elements:

h1 I love treehouse

ul

li red

li blue

li yellow

Adding attributes to elements

div (class = “wrapper”) or div.wrapper

If you need an attribute that is not a class or id use a parenthesis and include the key value pair.

— — -

Using pug in your express app

Steps to using Pug:

  • Download pug with NPM
  • Update code in app to use Pug
  • app.set methods defines different settings in express. This line just tells express which template engine to use. By default, express will look at a file called views in the root of your project. Anytime we ask express to render a template response it will look at the views folder.
  • Create templates
  • First we have to create a views folder because this is where express will look for the template
  • We will create our first template called index.pug and this is the template that will render when the client or user visits the root URL
  • Render templates with response.render()
  • Now we will replace our res.send to res.render(template name)
  • No need to put .pug file extension since we already set the view engine to pug, express knows to look for files with the pug extension

If we inspect -> sources -> { } we will see this

— -

Practice:

— — —

Why is template rendering so important? It allows developers to reuse more of their code.

— —

Express’s response.render() method

We have only been using static data (which means its fixed) — the real power of using templates is when we inject variables into the template that dynamically changes depending on the user’s actions.

A lot of the tags like the doctype, html and body tags are similar to what we’ll use with other pages on the site.

We will put these in a new .pug file called card.pug as a base template

How we render a variable in pug:

h1 = variable

On app.js:

How to pass variables to the template:

[ ] means its optional

Res.render takes in these parameters

res.render (view, [locals], [callback])

The second parameter is called locals — placing an object here will define locals for the view.

Locals is the name for variables we want to have access to when it’s being rendered. The properties we pass in the second template will define the locals in the template.

app.get(“/cards”, (req, res) => {

res.render(“card”, { prompt: “Who is buried in grant’s tomb?” });

});

Another way

app.get(“/cards”, (req, res) => {

res.locals.prompt = “Who’s buried in grant’s”;

res.render(“card”);

});

To interpolate with static text we can add #{text}

Interpolation does not work with attributes, we need to concatenate strings with +

Adding more than one local object:

app.get(“/cards”, (req, res) => {

res.render(“card”, {

prompt: “Who’s buried in grant’s tomb?”,

hint: “Think about it!”,

});

});

doctype html

html(lang=”en”)

head

title Flash Cards

body

h1 Flash Cards

section#content

h2= prompt

p

i Hint: #{hint}

footer

p An app that helps you study

— — -

Using logic in Pug

Let’s delete the hint object

app.get(“/cards”, (req, res) => {

res.render(“card”, {

prompt: “Who’s buried in grant’s tomb?”,

});

});

It would still show “Hint” — let’s use a conditional statement to only add “Hint” if the hint value is true

body

h1 Flash Cards

section#content

h2= prompt

if hint

p

i Hint: #{hint}

footer

p An app that helps you study

Now there is no more

And if we add the hint object back

It’s back!

Adding an else clause and removing the hint object again

h2= prompt

if hint

p

i Hint: #{hint}

else

p (There is no hint.)

footer

p An app that helps you study

Now let’s look at how pug handles iterating over an array of values

each is a pug keyword to indicate that a lib is starting

each in color in colors

const express = require(“express”);

const app = express();

const colors = [“red”, “orange”, “yellow”, “green”, “blue”, “purple”];

app.set(“view engine”, “pug”);

app.get(“/”, (req, res) => {

res.render(“index”);

});

app.get(“/cards”, (req, res) => {

res.render(“card”, {

prompt: “Who’s buried in grant’s tomb?”,

colors,

});

});

On pug — don’t forget, every time you use each you have to indent the element you want each value to be in

doctype html

html(lang=”en”)

head

title Flash Cards

body

h1 Flash Cards

section#content

ul

each color in colors

li= color

h2= prompt

if hint

p

i Hint: #{hint}

footer

p An app that helps you study

Challenge:

doctype html

html(lang=”en”)

head

title Flash Cards

body

h1 Flash Cards

section#content

div

ul

each firstName in firstNames

li= firstName

ul

each lastName in lastNames

li= lastName

h2= prompt

if hint

p

i Hint: #{hint}

footer

p An app that helps you study

app.get(“/sandbox”, (req, res) => {

res.render(“sandbox”, { firstNames, lastNames });

});

const firstNames = [“Renzo”, “Alex”, “Miguel”, “Ichi”];

const lastNames = [“Regio”, “Yang”, “Mercardo”, “Bautista”];