Theme development・Framing with templates

Splitting shared parts into header.php and footer.php

The header and footer are shared by every page. Split them out into header.php / footer.php so any template can call them in. The important wp_head() incantation shows up too.

We’re about to build several templates, but the header (logo and nav) and the footer are shared by every page. If you copy-pasted them each time, fixing one thing would mean editing every file—so WordPress gives you a way to split shared parts out into separate files. They are header.php and footer.php.

How the “parts” mechanism works

Put a header.php in your theme folder, and any template can call it in with a single line: get_header(). The footer works the same way.

Template (index.php and so on)
┌────────────────────┐
│ <?php get_header(); ?>   │ ← the contents of header.php go in here
│                          │
│ this page's own content  │
│                          │
│ <?php get_footer(); ?>   │ ← the contents of footer.php go in here
└────────────────────┘

“Make the shared top and bottom into parts, and each page writes only its own content”—it’s the same idea as making a shared class in CSS: cutting out repetition.

Create header.php

Create two new files in your theme folder: header.php and footer.php. Your folder now looks like this.

shimaenagado/
├── footer.php   ← create this now
├── header.php   ← create this now
├── index.php
└── style.css

Cut the top half of your current index.php and make it into header.php. Let’s also build Shimaenagado’s header (logo + nav) here.

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <?php wp_head(); ?>
</head>
<body>
  <header class="site-header">
    <a class="site-title" href="<?php echo home_url(); ?>">
      <?php bloginfo('name'); ?>
    </a>
    <nav class="site-nav">
      <a href="<?php echo home_url(); ?>">Home</a>
      <a href="#">About</a>
      <a href="#">News</a>
    </nav>
  </header>

There are two things you may not have seen before.

  • <?php wp_head(); ?>—“a hole for WordPress and each plugin to slip in whatever they want to put in the head.” It’s an incantation that every theme must have, and without it many plugins won’t work. Always place it just above the closing </head>
  • There’s no <title> tag—leaving the title to WordPress is the modern practice (we’ll enable it with functions.php in the next chapter). For now it’s fine even if the browser tab looks a bit plain

The # link targets in the nav are just placeholders for now, and that’s fine too. We’ll swap them for a real menu you can edit from the admin screen in a later chapter.

Create footer.php

Likewise, move the bottom half into footer.php.

  <footer class="site-footer">
    <p>© 2026 <?php bloginfo('name'); ?></p>
  </footer>
  <?php wp_footer(); ?>
</body>
</html>

The must-have incantation here is wp_footer(). The admin bar (the black bar that appears at the top while you’re logged in) and plugins’ JavaScript get slipped in through this hole. Its home position is just before </body>.

Make index.php “content only”

Once the parts are split out, index.php gets this tidy.

<?php get_header(); ?>

<main class="section">
  <h1><?php bloginfo('name'); ?></h1>
  <p>The theme is working!</p>
</main>

<?php get_footer(); ?>

Summary of this lesson

  1. Split shared parts out into header.php / footer.php, and call them from each template with get_header() / get_footer()
  2. wp_head() (just before /head) and wp_footer() (just before /body) are must-have incantations—the slots where plugins and WordPress core itself slip things in
  3. Once split into parts, each template holds only “that page’s own content”

Try it: give your theme a three-file structure

Let’s split the Shimaenagado theme into parts.

  1. Create header.php and save the code above (feel free to add more nav items to your liking)
  2. Create footer.php and save the code above
  3. Rewrite index.php into the “get_header + content + get_footer” shape
  4. Reload the front side—success if the site name shows in the header and the © shows in the footer
  5. If you’re logged in, also check that the black admin bar appears at the top of the screen (proof that wp_footer is working)

The look is still plain, being raw HTML, but the framework’s division of labor is now complete. Next, at last, we build the face of the site: the top page.