Layouts & Controllers
Express gives us a lot of flexibility out of the box (configuration over convention). While this is a good thing, it can become a problem when we don't take the time to organize our project.
Objectives
Utilize layouts and controllers in an Express app
Prereqs:
ability to create a basic node/express app with basic routes and views
Set Up a new Express App
Before we do anything else, let's set up a new basic Express app called love-it-or-leave-it
.
1. Create a new project
2. Initialize Node
3. Install Dependencies
express
ejs
4. Set up Express
index.js
filerequire express
create an instance of express
tell the app which port to listen to
5. Set up EJS
set view engine to ejs
create a
views
folder
EJS Layouts
Adding partials can dry up the code a bit, but EJS Layouts can take this modularity even farther and make a big diffence with large applications.
EJS layouts is a node package that allows us to create a boilerplate (aka a layout) that we can inject content into based on which route is reached. Layouts normally include header and footer content that you want to display on every page (navbar, sitemap, logo, etc.).
Install EJS Layouts
Step 1: Install EJS layouts
Install express-ejs-layouts
via npm
Step 2: Set up EJS layouts
Require the module and add it to the app.
index.js
What is app.use()
? This is an express function that indicates middleware. Middleware functions intercepts the request object when it comes in from the client, but before it hits any route. We'll see more examples of middleware later.
How are you supposed to know that ejs layouts requires middleware? The docs.
Step 3: Create a Layout
In the root of the views
folder, add a layout called layout.ejs
. It must be called layout.ejs
, as mandated by express-ejs-layouts
.
layout.ejs
This layout will be used by all pages, and the content will be filled in where the <%- body %>
tag is placed. <%- body %>
is a special tag used by express-ejs-layouts
that cannot be renamed.
Step 4: Use the Layout
In the views folder, create a home.ejs
file:
home.ejs
Now create a home route in index.js
below the middleware:
Ejs will assume that home
means home.ejs
. Now starte nodemon and check that your home page renders as desired.
Step 5: Set up a few more views/routes
index.js
animals.ejs
Visit localhost:3000/animals
to make sure that all is well.
Exercise
Create a
foods
route and view that displays your favorite foods, just like you did with animals.Create a
movies
route and view that displays your least favorite movies.Create a
products
route and view that displays your least favorite products.
Bonus: Add Navigation
Add a simple navigation list to the top of the layout page so there's a link to every page from every page:
layout.ejs
Controllers & Express Router
Controllers become important organizational tools when you start making apps with several views, so let's organize the routs/views we have into two sections: love-it
and leave-it
.
1. Change your routes to have the following url patterns:
/loveit/food
/loveit/animals
/leaveit/movies
/leaveit/products
Now check that these new url patterns render the expected html, and fix your nav bar to have the correct links.
We have been placing all routes into index.js
when creating a Node/Express app, but this can get cumbersome when dealing with many routes. The solution is to group related routes and separate these groups into separate files. These files will go into a controllers
folder.
2. Create a controllers
folder inside the root directory that will contain all routes except for the home route.
4. Inside the controllers
folder, create a file called loveit.js
, and copy your two loveit
routes into this file.
with the following routes:
But wait! app
doesn't exist in this file! Express has a Router()
function that will help us wrap these routes into a module that we'll export back into our main server file.
5. Add these wrapper lines of code to loveit.js
, and replace app
with router
.
6. Now back in index.js
, we just need to add some middleware to get these routes working again!
index.js
This middelware says "Dear Express, if you get a request for a url pattern that starts with /loveit
, please to to the loveit
controller file to find the relevant routes." SO, by the time express is looking in the right controller file, it already has processed the /loveit
part of the url pattern, thus, we can now remove that part from the routes in controllers/loveit.js
:
Note that we defined the routes relative to the definition in app.use
. In other words, take note that our URL patterns in loveit.js
don't inclued '/loveit'
, because that is taken care of by the middleware.
Check that these routes are working by visiting http://localhost/loveit/foods
and http://localhost/loveit/animals
.
Finally, it is standard to organize your views the same way you organize your routes. This means we should create a subdirectory inside of views
called loveit
and move our animals.ejs
and food.ejs
files into it.
We also need ot update our res.render()
lines accordingly:
Now finish the lab off by doing the same for your leave-it routes/pages!
Last updated
Was this helpful?