Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Views: Write Draft For Introduction #27618

Merged
merged 56 commits into from
May 5, 2024
Merged
Changes from 40 commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
a31d239
Create testFile.md
Sep 4, 2023
c5fe72e
Change Added File
Sep 4, 2023
02a6a59
Write Views Introduction Draft
Mar 15, 2024
3450d33
Merge branch 'main' into node_revamp
Mar 15, 2024
b815dcd
Delete javascript/testing_javascript/testFile.md
jasonHYLam Mar 15, 2024
a06eea4
Add EJS Installation And Syntax And Example
Mar 15, 2024
0a360d6
Delete Test File
Mar 15, 2024
56a701d
Merge branch 'node_revamp' of github.com:prodijay777/TOP-curriculum-g…
Mar 15, 2024
08bebe2
Add Example Of Using EJS With Express
Mar 20, 2024
9fe9fd8
Add Examples Of Include Command
Mar 20, 2024
f6c63b8
Add Case For Includes Tag With Header And Footer
Mar 20, 2024
c3414cb
Add Knowledge Checks And Add To Intro
Mar 20, 2024
5317d7c
Remove Confusing Sentence From Intro
Mar 20, 2024
df69247
Add To Introduction
Mar 20, 2024
1d38a65
Merge branch 'main' into node_revamp
Mar 20, 2024
f5eebba
Remove Script Tag From EJS Express Example
Mar 27, 2024
ea62a7b
Rewrite Example To Include Data In App.js
Mar 27, 2024
4cf7f06
Merge branch 'main' into node_revamp
Mar 27, 2024
1fb4572
Add EJS Tutorial To Additional Resource
Mar 27, 2024
12376a8
Add Sentence about EJS Syntax Similarity To HTML
Mar 27, 2024
326ef90
Update nodeJS/express/views.md
jasonHYLam Apr 2, 2024
e20483e
Update nodeJS/express/views.md
jasonHYLam Apr 2, 2024
ec65d3a
Update nodeJS/express/views.md
jasonHYLam Apr 2, 2024
0630529
Update nodeJS/express/views.md
jasonHYLam Apr 2, 2024
a33c1a1
Update nodeJS/express/views.md
jasonHYLam Apr 2, 2024
26624ab
Update nodeJS/express/views.md
jasonHYLam Apr 2, 2024
131cf2e
Update nodeJS/express/views.md
jasonHYLam Apr 2, 2024
0741f08
Update nodeJS/express/views.md
jasonHYLam Apr 2, 2024
d42ff5c
Update nodeJS/express/views.md
jasonHYLam Apr 2, 2024
3ec2e9a
Update nodeJS/express/views.md
jasonHYLam Apr 2, 2024
a0f31be
Update nodeJS/express/views.md
jasonHYLam Apr 2, 2024
6637971
Update nodeJS/express/views.md
jasonHYLam Apr 2, 2024
f1ce83d
Replace js Codeblock Keyword With javascript
jasonHYLam Apr 2, 2024
6a2e89d
Update nodeJS/express/views.md
jasonHYLam Apr 13, 2024
85f1488
Update nodeJS/express/views.md
jasonHYLam Apr 13, 2024
3f81a38
Update nodeJS/express/views.md
jasonHYLam Apr 13, 2024
ad3a4e0
Update nodeJS/express/views.md: Fix Typo
jasonHYLam Apr 13, 2024
4c1d03a
Update nodeJS/express/views.md: Remove Unnecessary Backticks
jasonHYLam Apr 13, 2024
73e2ab0
Fix Linting Issues
jasonHYLam Apr 13, 2024
81447f8
Add Assignments
jasonHYLam Apr 13, 2024
a78a226
Update nodeJS/express/views.md: Update example to use forEach()
jasonHYLam Apr 15, 2024
c6b776d
Update views.md: Update Relevant Blocks With EJS Tag
jasonHYLam Apr 15, 2024
33c60a5
Update views.md: Use Templates Instead Of Components For KC
jasonHYLam Apr 15, 2024
85e4658
Update nodeJS/express/views.md
jasonHYLam Apr 15, 2024
94d8835
Update views.md: Add EJS Docs To Assignment Item
jasonHYLam Apr 15, 2024
0d8b53d
Update views.md: Add Static Assets Section
jasonHYLam Apr 15, 2024
790c433
Update nodeJS/express/views.md: Correct Assignment Operator For Href
jasonHYLam Apr 16, 2024
aec384a
Update nodeJS/express/views.md: Use List Tags And Clarify Loop
jasonHYLam Apr 16, 2024
69f2b8c
Update nodeJS/express/views.md: Use Lowercase For Express
jasonHYLam Apr 16, 2024
cf45e3e
Update nodeJS/express/views.md
jasonHYLam Apr 16, 2024
6752b78
Update nodeJS/express/views.md: Fixing Numbering
jasonHYLam Apr 16, 2024
d074e53
Update views.md: Provide Instructions In Assignment
jasonHYLam Apr 16, 2024
eefa89a
Merge branch 'main' into node_revamp
Apr 28, 2024
15bfc96
Merge branch 'node_revamp' of github.com:prodijay777/TOP-curriculum-g…
Apr 28, 2024
00c179c
Update Views lesson: Fix linting errors
Apr 28, 2024
9ad9eda
Update views.md: Add closing div tag to note
jasonHYLam May 5, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
180 changes: 180 additions & 0 deletions nodeJS/express/views.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
### Introduction

Views are the user-facing part of the application, in this case, HTML files. We've dealt with views in an earlier project where the server would send HTML files to the user. These files are static, but many of our use cases require views to be dynamic w.r.t. data.

Hence, we use template engines to create our views. As the name suggests, we write template files in our codebase that get transformed into HTML when we respond to a server request. Any variables defined in our template files are replaced with actual data. Additionally, we can insert conditional and/or loop logic into our template file, e.g. render the user's username once they have logged in. This would not be possible with plain HTML.

In this course, we will use [EJS](https://ejs.co/). EJS's syntax is very similar to that of HTML, meaning that the learning curve is relatively low compared to other template engines.

### Lesson overview

This section contains a general overview of topics that you will learn in this lesson.

- How to setup EJS in an Express project
- How to use EJS

### Setting up EJS

Let's get started with EJS! Install EJS into your application by typing the following into your terminal:

```bash
npm install ejs
```

At the root of your project, create a subfolder called `views`.

Next, we need to let our app know that we intend to use `EJS` as a template engine, as well as where to look for view files.

In your `app.js` file, set the following application properties:

```javascript
app.set("views", path.join(__dirname, "views"));
app.set("view engine", "ejs");
```

This enables EJS as the view engine, and that our app should look for templates in the `/views` subdirectory.

### EJS syntax

In EJS, the `<%` and `%>` tags allow us to use JavaScript. This lets us write conditional statements, `for` loops, as well as use variables.

In order to output a variable as a value, we use the `<%=` tag.

Here's a quick example that makes includes arrays and loop logic.

```javascript
<% const animals = ["Cat", "Dog", "Lemur", "Hawk"] %>

<% animals.map(animal => { %>
- <%= animal%>s are cute <% }) %>
jasonHYLam marked this conversation as resolved.
Show resolved Hide resolved
```

### Using EJS with Express

Let's use EJS with Express. First, create an EJS template file called `index.ejs` in the `views` subdirectory, and add the following:

```html
<html>
<body>
<%= message %>
</body>
</html>
```

And in app.js, render this template file in one of your routes:

```javascript
app.get("/", (req, res) => {
res.render("index", { message: "EJS rocks!" });
});
```

Start the server and go to the `/` route in the browser. You should see:

```html
EJS rocks!
```

If you inspect the HTML in the browser's dev tools, you can see HTML is structures exactly like how we wrote the EJS template with the `message` variable replaced with its value.

When you hit the `/` route, `res.render("index", { message: "EJS rocks!" });` is the line that sends back the response. Since we've already defined the `views` and `view engine` app properties, the first argument of `res.render` is programmed to look for "a template called index in the specified folder", while the second argument is an object of variables that are to be made available to that specific template.

### Reusable templates

You may want to include webpage components that are shared across different pages, such as a sidebar or a header. To insert such components into your pages, we make use of the `include` command. This requires the name of the file to be inserted, and optionally an object of data you wish to pass.

Say you have the following navbar component called `"navbar.ejs"`:

```html
<!-- navbar.ejs -->
<nav>
<ul>
<% for (let i = 0; i < links.length; i++) { %>
<li>
<a href="<%= links[i].href %>">
<span> <%= links[i].text %> </span>
</a>
</li>
<% } %>
</ul>
</nav>
```

You can insert this component into another EJS file like so:

```html
<!-- index.ejs -->
<html>
<head>
<title>Homepage</title>
<body>
<%- include('navbar', {links: links}) %>
</body>
</head>
</html>
```

This can be used to include headers and footers in all of your pages, for example.

Note that the navbar expects a `links` value. To pass this data into the navbar, you can pass it when rendering `index.ejs` which contains the navbar. Modify `app.js` such that a `links` object is defined and passed into the `render` function in the `"/"` route handler:

```javascript
// app.js
const links = [
{ href: "/", text: "Home" },
{ href: "about", text: "About" },
];

app.get("/", (req, res) => {
res.render("index", { links: links });
});
```

Here's another example of how to use `includes` to dynamically render a list of variables:

```html
<ul>
<% users.map( user => { %> <%- include('user/show', {user: user}) %> <% }) %>
</ul>
jasonHYLam marked this conversation as resolved.
Show resolved Hide resolved
```
jasonHYLam marked this conversation as resolved.
Show resolved Hide resolved

jasonHYLam marked this conversation as resolved.
Show resolved Hide resolved
<div class="lesson-note lesson-note--tip" markdown="1">

#### Directories within the views folder

We can have nested directories of EJS template files within the views. For example, to render the template file `./views/user/show.ejs`, we'll need to provide the relative path like so:

```javascript
// in res.render
res.render("user/show")

// in include
include("user/show")
jasonHYLam marked this conversation as resolved.
Show resolved Hide resolved
```

Note the use of the raw output tag `<%-` with the `include` which is used to avoid double-escaping the HTML output.

### Assignment

<div class="lesson-content__panel" markdown="1">

1. Read through the [Express resource on template engines](https://expressjs.com/en/guide/using-template-engines.html). The resource uses Pug for the examples which has a different syntax, however the information should still be a useful supplement to this lesson.
jasonHYLam marked this conversation as resolved.
Show resolved Hide resolved
2. Add a view for an about page, which should render on the `/about` route.

Check failure on line 162 in nodeJS/express/views.md

View workflow job for this annotation

GitHub Actions / Lint lesson files

Ordered list item prefix

nodeJS/express/views.md:162:1 MD029/ol-prefix Ordered list item prefix [Expected: 1; Actual: 2; Style: 1/1/1] https://github.com/DavidAnson/markdownlint/blob/v0.32.1/doc/md029.md
3. Create a reusuable footer component and render it in the `/` route.

Check failure on line 163 in nodeJS/express/views.md

View workflow job for this annotation

GitHub Actions / Lint lesson files

Trailing spaces

nodeJS/express/views.md:163:71 MD009/no-trailing-spaces Trailing spaces [Expected: 0 or 2; Actual: 1] https://github.com/DavidAnson/markdownlint/blob/v0.32.1/doc/md009.md

Check failure on line 163 in nodeJS/express/views.md

View workflow job for this annotation

GitHub Actions / Lint lesson files

Ordered list item prefix

nodeJS/express/views.md:163:1 MD029/ol-prefix Ordered list item prefix [Expected: 1; Actual: 3; Style: 1/1/1] https://github.com/DavidAnson/markdownlint/blob/v0.32.1/doc/md029.md
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Linting errors here will need addressing

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what the linting error is, is it regarding the extra space at end of the 3rd line? I'll resolve that but please let me know if there are any other errors.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The 3 linting errors for this part at not using lazy numbering for ordered lists and the trailing space at the end of line 163.

You can see the linting errors as annotations in the Files changed tab up top.

jasonHYLam marked this conversation as resolved.
Show resolved Hide resolved

</div>

### Knowledge check

The following questions are an opportunity to reflect on key topics in this lesson. If you can't answer a question, click on it to review the material, but keep in mind you are not expected to memorize or master this knowledge.

- [How do you configure EJS for Express projects?](#setting-up-ejs)
- [What is the difference between "<%" and "<%=" tags?](#ejs-syntax)
- [How do you render a view in a controller callback?](#using-ejs-with-express)
- [How can components be included in other components?](#reusuable-web-components)

Check failure on line 174 in nodeJS/express/views.md

View workflow job for this annotation

GitHub Actions / Lint lesson files

Link fragments should be valid

nodeJS/express/views.md:174:3 MD051/link-fragments Link fragments should be valid [Context: "[How can components be included in other components?](#reusuable-web-components)"] https://github.com/DavidAnson/markdownlint/blob/v0.32.1/doc/md051.md
jasonHYLam marked this conversation as resolved.
Show resolved Hide resolved

### Additional resources

This section contains helpful links to related content. It isn't required, so consider it supplemental.

- [How to Use EJS to Template Your Node.js Application](https://blog.logrocket.com/how-to-use-ejs-template-node-js-application/)