In the last lesson, we looked at how to organize the files in a site. Now for another topic on site management: page components.
Most websites use the same page layout over and over. For example, the page you're looking at now has a menu at the top. Almost all pages use the same menu. They have the same footer as well. The lessons are on the left of every page. And so on.
There are hundreds of pages on this site. If I wanted to add something to the main menu, I'd have to touch every page, right? What a pain. Unless...
Maybe I could write the HTML for the menu once, and share it across pages. Hmm...
Regions
Here's the home page for Goatland. You can try it, and download it.
It has three regions:
- Top
- Content
- Footer
The two other pages, rides and tickets, have the same structure.
Here's the start of the code for the home page:
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title>Home | Goatland</title>
- <meta name="viewport"
- content="width=device-width, initial-scale=1, shrink-to-fit=no">
- <link rel="stylesheet" href="library/styles.css">
- </head>
- <body>
- <div id="top">
- <p id="site-name">Goatland</p>
- <nav>
- <a href="index.php">Home</a>
- <a href="rides.php">Rides</a>
- <a href="tickets.php">Tickets</a>
- </nav>
- </div>
- <h1>Welcome</h1>
- ...
Here's the code for rides. It's almost the same, with the differences marked.
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <meta charset="UTF-8">
- <title> Rides | Goatland</title>
- <meta name="viewport"
- content="width=device-width, initial-scale=1, shrink-to-fit=no">
- <link rel="stylesheet" href="library/styles.css">
- </head>
- <body>
- <div id="top">
- <p id="site-name">Goatland</p>
- <nav>
- <a href="index.php">Home</a>
- <a href="rides.php">Rides</a>
- <a href="tickets.php">Tickets</a>
- </nav>
- </div>
- <h1> Rides </h1>
- ...
Injecting page fragments
Let's take out the head
section, and put it in a separate file called, say, head.php
.
- <meta charset="UTF-8">
- <title> ??? | Goatland</title>
- <meta name="viewport"
- content="width=device-width, initial-scale=1, shrink-to-fit=no">
- <link rel="stylesheet" href="library/styles.css">
Hmm. How about we make a folder called library
, to keep things in. Put head.php
there.
We can use PHP's require_once
to insert one file inside another. So we could change the home page to:
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <?php
- require_once 'library/head.php';
- ?>
- </head>
Cool! Do the same for the other pages, and head.php
will be injected into every page. If we want to change the head
part of every page, change one file, head.php
, and be done! Even if there are thousands of pages on the site, change one file to change all pages.
Adela
What about that title
tag? That changes for every page.
Oh, right. No problem. Change the home page to:
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <?php
- $pageTitle = 'Home';
- require_once 'library/head.php';
- ?>
- </head>
The tickets page would have:
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <?php
- $pageTitle = 'Tickets';
- require_once 'library/head.php';
- ?>
- </head>
Change head.php
to:
- <meta charset="UTF-8">
- <title><?php print $pageTitle; ?> | Goatland</title>
- <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
- <link rel="stylesheet" href="library/styles.css">
Ethan
Cool! So in the page, set a variable. In the page fragment, output the variable.
Right!
We could do the same for the top and footer regions.
A template
I can make a template file, maybe called template.php
:
- <!DOCTYPE html>
- <html lang="en">
- <head>
- <?php
- // Title for tab goes here. | Goatland appended automatically.
- $pageTitle = '';
- require_once 'library/head.php';
- ?>
- </head>
- <body>
- <?php
- require_once 'library/top.php'
- ?>
- <h1>Page title</h1>
- <p>
- Some killer content.
- </p>
- <?php
- require_once 'library/footer.php';
- ?>
- </body>
- </html>
When someone wants to make a new page, they copy the template, and adjust it.
If we want to change the navbar across the site, edit top.php
. To change the footer, edit footer.php
.
Careful with the paths
PHPStorm gives me a warning about top.php
.
top.php
has a link to tickets.php
. PHPStorm says it can't find tickets.php
. But there it is, in the lower right of the screen shot, and the whole thing works.
Why is PHPStorm giving that warning?
Ethan
OK, top.php
has <a href="tickets.php">
, so PHPStorm is looking for tickets.php
in the same folder as top.php
. That's the library
folder.
But tickets.php
is in the folder above the library
folder.
That's right!
Ray
Wait, how come it works, then?
Georgina
Oh! I get it. The code in top.php
is never used by itself. It's injected into pages like rides.php
, that are in the folder above the library
folder. When top.php
is injected, the links are right.
Correct! When you're writing code to be injected, write it so it works after the injection had happened.
Reuse
This is an example of the "management" part of MIS. Simply moving common code into separate files makes a site cheaper to maintain. Cheap is good.
Reuse is a big cost controller. Look for ways to reuse what you're already done.
Job interview
This sounds good in a job interview: "I learned how to use page components to make sites cheaper and easier to manage."