Log in
If you're a student, please log in, so you can get the most from this page.
Lesson contents
Navbar reuse = happiness
On most sites, the same, or a similar, navbar is used on all pages. You can copy-and-paste the same navbar code to each page. Makes sense.
Until you need to change the navbar. Add a new page that needs a navbar link? You need to change every page. All 392 of them, or whatever the number is.
What if you could have the navbar in a separate HTML file, maybe called top-menu.inc
, and insert top-menu.inc
into every page on the site? Woo-hoo! Then, when you want to add a menu item, change that one file top-menu.inc
, and every page on the site changes.
(BTW, the inc
in top-menu.inc
stands for "include.")
That's what this lesson is about. It's a big productivity win.
DoggoLand example
Let's make a site about DoggoLand, a theme park.
Here are the pages:
index.html
is the home page. location.html
has a map, and directions to the park. tickets.html
is where you can buy tickets.
rides
is a folder. It has three pages, each one about a different ride.
You can try the site. You'll see that each page has the same navbar:
How it works
We make one file with the navbar code. Then, on each page, we leave a gap, where we want the navbar to appear. Then, when the page loads, we want the navbar code to be injected into the gap.
When the browser loads a page, we want it to run some JavaScript code, that will fetch top-menu.inc
, and inject it into the page. You don't need to write JavaScript code. I've done that for you, and put it in a file. All you need to do, is use a script
tag to load the file on each page.
Make a library
folder
To start, we'll need a place for top-menu.inc
to live. The file with the JS (JavaScript) will live in the same place. Let's make a library
folder for our new stuff.
Make top-menu.inc
with the navbar code
Let's make top-menu.inc
, the file with the navbar HTML. This HTML will be inserted into each of your pages.
You learned to make navbar HTML in the previous lesson. Like this:
- <nav class="navbar navbar-expand-lg navbar-light bg-light">
- <a class="navbar-brand" href="index.html" title="Home">DoggoLand</a>
- ...
- </nav>
Important! This file contains just the code for the navbar. No body tag, and no start html tag, no CSS file link, nothing else. The file with the navbar code is never used by itself. It's inserted into another page, that already has the html tag, link tag, body tag, etc.
Make top-menu.inc
in library
, and put the navbar code in it:
Copy the JavaScript file
Now, let's add the JavaScript code, in a file called loader.js
in library
.
To get a copy of loader.js
, right-click on this link and choose "Save link as..." (Firefox and Chrome), "Save target as" (Edge), or whatever on another browser.
You don't need to change the file at all. Just save it into the library
folder.
Preparing the webpages
Remember that we want to inject code into our pages.
We have top-menu.inc
. We have the JavaScript code that will do the injection. Now, we need to prep our webpages, like index.html
, dogarium.html
, and tickets.html
.
There are two steps.
- Include the JavaScript code on the page.
- Mark where you want the navbar to be injected.
Including the JavaScript code
We've been using an HTML template for our BS pages, with this at the bottom:
- <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-A3rJD856KowSb7dwlZdYEkO39Gagi7vIsF0jrRAoQmDKKtQBHUuLZ9AsSv4jD4Xa" crossorigin="anonymous"></script>
- </body>
- </html>
Let's add two new lines:
- <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-A3rJD856KowSb7dwlZdYEkO39Gagi7vIsF0jrRAoQmDKKtQBHUuLZ9AsSv4jD4Xa" crossorigin="anonymous"></script>
- <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
- <script src="library/loader.js"></script>
- </body>
- </html>
One line adds loader.js
from the library
folder. The other loads jQuery, a popular JavaScript library, that loader.js
uses.
The Angely Trap
Angely discovered a trap here. If you switch the order of the last two script tags...
- <script src="library/loader.js"></script>
- <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
... you get an error. Check the console in the browser's dev tools (F12 on a PC) to see it. The error message will be something like "$ not defined." $ is defined in the JQuery file. If loader.js is listed first, it tries to access $ before it is defined.
So, keep the lines in this order:
- <script src="https://code.jquery.com/jquery-3.3.1.min.js"></script>
- <script src="library/loader.js"></script>
Thanks to the interpid Angely for discovering the Angely Trap.
Marking the injection point
Recall that BS uses rows and columns. Like this:
- <body>
- <div class="container">
- <div class="row">
- <div class="col-sm-12">
- <!-- Navbar -->
- </div>
- </div>
- <div class="row">
- <div class="col-sm-12">
- <!-- Content -->
- </div>
- </div>
- </div>
- </body>
We want the navbar in the first row. Let's mark the place where we want the navbar to be injected.
- <body>
- <div class="container">
- <div class="row">
- <div class="col">
- <div data-replacement="library/top-menu.inc"></div>
- </div>
- </div>
data-replacement
gives the name of the file to inject. loader.js
(we added that JS file earlier, remember) will look for elements with the data-replacement
property, and replace them with the file given.
Georgina
You used a div
there, not a nav
.
- <div data-replacement="top-menu.inc"></div>
Does that matter?
No. The file we're injecting, top-menu.inc
, has the nav
element.
Actually, this isn't just for navbars. It will inject any HTML. Have a photo of your fave doggo, that you want on your site, in many places? Make a file in the library
folder, and inject it as needed.
For example, best-doggo.inc
might have this:
- <p>
- <img src="rosie1.jpg" alt="Best doggo!">
- </p>
In your pages:
- <div data-replacement="library/best-doggo.html"></div>
Use this as many times as you like.
If you get a better photo of your best dog, change the code in best-doggo.html
:
- <p>
- <img src="rosie-blue-ribbon.jpg" alt="Rosie gets the blue!">
- </p>
All of your pages that inject best-doggo.html
will use the new photo.
Summary so far
To reuse some HTML:
- Make a
library
folder. - Make a file there with the HTML you want to reuse.
- Put
loader.js
inlibrary
. - Include
loader.js
in each page (with ascript
tag). - Mark the element you would like to replace, with
data-replacement="path-to-the-file"
.
Changing other site elements
Adela
A question. I'm making a site for a student org. We want to include the name and email of our membership person on the site, on maybe ten different pages. Trouble is, that person changes. Currently, it's Buffy Summers, but next year, it'll be Willow Rosenberg. That means we'll have to go through all the pages, and change the membership contact.
No big deal, but it takes time, and it would be easy to miss one. Could we use this inject-HTML-in-several-files thing, to make the site easier to change?
Yes, you could. You could make a file called membership-questions.inc
, or something like that. Put it in library
. It would have HTML, like this:
- <p>
- For membership info, please contact Buffy Summers, at slayer83@sunnydale.edu.
- </p>
When you want to use it on a page, type in this:
- <p data-replacement="library/membership-questions.inc"></p>
Use the data-replacement
thing as many times as you like, on as many pages as you like.
Next semester, update membership-questions.inc
with the new contact info. Everything will change across the site, automatically.
Georgina
Wow, that's so useful! I did an internship last summer, updating a website. I kept making the same changes all over the site. This would have saved a lot of time.
Right! And Benjamins. When a large site is set up this way, one person can do a job it might take two or three people to do otherwise.
Ray
Hey, I was thinking. Pretend I'm interviewing for a job, and they asked what I know about making websites. I can talk about HTML, OK. But what might impress them, is if I tell them about productivity hacks I learned.
Like using Bootstrap templates, with good a11y built-in. Making responsive sites, so one site looks good on phones, tablets, and PCs. No duplication of effort.
This reusing HTML thing is another one.
Good thinking, Ray! Talking about productivity is good to do in interviews. The technique we're using here is called code reuse by geeks. Talking about how code reuse makes sites cheaper to maintain, could impress the interviewers.
Georgina
Yeah, that's a good idea, Ray.
It takes a server
Here's part of the code from loader.js
:
- $(replacementElement).load(pathToFile...
The load()
method contacts the server the HTML file is from, and gets the file named in the variable pathToFile
. There has to be a server to respond, for this to work.
If the HTML page is being served from your Reclaim Hosting account, no problem. There is a server. But suppose you opened the HTML file on your PC, by double-clicking on the file name in Explorer. In that case, your browser opens the file directly from your C: or D: drive, or whatever. There is no server involved, and nothing for load()
to send its request to.
Exercise
The subfolder problem
There's just one more wrinkle to deal with. Remember that we have pages in a subfolder:
We want top-menu.inc
to work on all the pages on our site, whether the page is in the root folder, like location.html
is, or whether the page is in a subfolder, like dogarium.html
is.
Here's part of top-menu.inc
:
- <nav class="navbar navbar-expand-lg navbar-light bg-light">
- <a class="navbar-brand" href="index.html" title="Home">DoggoLand</a>
- ...
- </nav>
Adela
It looks OK...
No, wait. It says href="index.html"
. That would work for tickets.html
, because tickets.html
and index.html
are in the same folder.
But href="index.html"
wouldn't work for dogarium.html
, because dogarium.html
is in a subfolder. Then the link is in dogarium.html
, it needs to be href="../index.html"
. Go up a level, then look for index.html
.
Right! The links in top-menu.inc
should change, depending on whether the page we're inserting top-menu.inc
into is in a subfolder.
Marcus
Argh! That sounds hard!
No worries. loader.js
know how to deal with this. If the page you want to inject the HTML into is in a subfolder, just tell loader.js
the path to the site root. So, dogarium.html
is inside rides
:
The path from dogarium.html
to the site root is ../
, that is, up one level. In dogarium.html
, when you tell loader.js
to inject top-menu.inc
, you add something:
- <body>
- <div class="container">
- <div class="row">
- <div class="col">
- <nav data-replacement="../library/top-menu.inc" data-path-to-root="../">
- </nav>
- </div>
- </div>
When you use the data-replacement
, you can add the data-path-to-root
. loader.js
will adjust the paths in top-menu.inc
, adding ../
to them all.
Well, almost all the paths. It won't adjust absolute paths, like this:
- <a class="nav-link" href="https://www.google.com/search?tbm=isch&q=cute+goat">Cute goats</a>
This link searches Google for images of cute goats. Adding ../
to the front would break the link. So, loader.js
won't adjust links that start with http
or https
.
You can also tell loader.js
to not adjust individual links, like this:
- <a class="nav-link" href="monkey-mania.html" data-no-update>Location</a>
data-no-update
tells loader.js
not to change the link. I'm not sure when you would use that, but it lets you skip links, when needed.
One last thing. The pages in the folder need to be able to find loader.js
. You have to change the line that loads loader.js
into your pages. From this...
- <script src="library/loader.js"></script>
... to this...
- <script src="../library/loader.js"></script>
Why do you need to change the link to loader.js
?
Marcus
Oh, I get it! The pages in the folder must go up a level, then down into the library, to find loader.js
.
Right! You got it!
Also notice:
- <body>
- <div class="container">
- <div class="row">
- <div class="col">
- <nav data-replacement="../library/top-menu.inc" data-path-to-root="../">
- </nav>
- </div>
- </div>
The browser has to go up a level, then down into library
to find top-menu.inc
.
Video lesson
Here's a video version of some of the stuff above.
Exercise
Code reuse with path adjustment
Log in
If you're a student, please log in, so you can get the most from this page.
Earlier, you made a site about two yummy things. Now make a similar site, about yucky things.
A good way to do it is to copy the folder you made earlier. Then change the bits you need.
Here's my site's home page:
I put three things. You can have two, if you want.
Put your pages about yucky things in the subfolder yucky-things
. Here's my file tree:
Reuse the navbar and footer. For example, here's what happens if I change the text in footer.html
:
Submit your URL as usual.
Up next
We'll end the course by looking at two more useful BS components.