SponsoredHosinger Special Offer

WP WordPress Theme Development

Build classic and block WordPress themes from scratch: the template hierarchy, The Loop, the_title() and the_content(), template parts, menus, the Customizer, child themes and theme.json.

header.php, footer.php, wp_head() and wp_footer()

WordPress Theme Development Lesson 9 of 30 ~4 min read

Overview

Every page of a site shares the same opening <html>, <head> and site header and the same closing footer, so classic themes write them once in header.php and footer.php and pull them into each template with get_header() and get_footer().

header.php

<?php
/**
 * The header for GDC Starter.
 */
?>
<!DOCTYPE html>
<html <?php language_attributes(); ?>>
<head>
    <meta charset="<?php bloginfo( 'charset' ); ?>">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <?php wp_head(); ?>
</head>

<body <?php body_class(); ?>>
<?php wp_body_open(); ?>

<a class="skip-link screen-reader-text" href="#primary">
    <?php esc_html_e( 'Skip to content', 'gdc-starter' ); ?>
</a>

<header class="site-header">
    <div class="site-branding">
        <?php if ( has_custom_logo() ) : ?>
            <?php the_custom_logo(); ?>
        <?php else : ?>
            <a class="site-title" href="<?php echo esc_url( home_url( '/' ) ); ?>" rel="home">
                <?php bloginfo( 'name' ); ?>
            </a>
        <?php endif; ?>
    </div>
</header>

<div id="primary" class="site-content">

What every line is for

CodeWhy it matters
language_attributes()Prints lang="en-US" and dir="rtl" for right-to-left languages. Screen readers use lang to choose a pronunciation.
bloginfo( 'charset' )Prints the site's character set, normally UTF-8.
wp_head()The most important line in the file. WordPress and every plugin print their <head> output here: your enqueued CSS and JS, the <title> tag, SEO meta, the admin bar styles, analytics. Leave it out and half the site breaks.
body_class()Adds classes such as home, single, page-id-12 and logged-in that you can target in CSS.
wp_body_open()A hook directly after <body> for plugins that must print there, such as tag managers.
Skip linkLets keyboard users jump past the navigation. Required for WordPress.org themes.
Watch out: Do not hard-code a <title> tag in header.php. Since WordPress 4.1, themes add title-tag support (lesson 11) and WordPress prints the title inside wp_head(). A hard-coded one creates two titles and breaks SEO plugins.

footer.php

<?php
/**
 * The footer for GDC Starter.
 */
?>
</div><!-- #primary -->

<footer class="site-footer">
    <p class="site-info">
        &copy; <?php echo esc_html( wp_date( 'Y' ) ); ?>
        <?php bloginfo( 'name' ); ?>
    </p>
</footer>

<?php wp_footer(); ?>
</body>
</html>

wp_footer() is the partner of wp_head(). Scripts enqueued "in the footer" are printed here, and so is the admin toolbar. If the toolbar vanishes from your front end, a missing wp_footer() is the cause nine times out of ten.

Using them in a template

<?php
/**
 * index.php — the main fallback template.
 */
get_header();
?>

<main class="site-main">
    <?php if ( have_posts() ) : ?>
        <?php while ( have_posts() ) : the_post(); ?>
            <?php the_title( '<h2>', '</h2>' ); ?>
            <?php the_excerpt(); ?>
        <?php endwhile; ?>
    <?php endif; ?>
</main>

<?php
get_footer();

Alternative headers

Pass a name to load a different file. get_header( 'minimal' ) loads header-minimal.php, falling back to header.php if it does not exist. This is ideal for a landing page that should hide the main navigation.

You can also pass data to it (WordPress 5.5+), which arrives in the file as $args:

<?php get_header( 'minimal', array( 'show_search' => false ) ); ?>

<?php // Inside header-minimal.php: ?>
<?php if ( ! empty( $args['show_search'] ) ) : ?>
    <?php get_search_form(); ?>
<?php endif; ?>

Practice

  • Move your <head> markup from index.php into header.php and the closing tags into footer.php.
  • Log in, view the front end and confirm the admin toolbar appears — proof that wp_head() and wp_footer() are wired correctly.
  • Create header-minimal.php and use it on one template.
Create a free account to save which lessons you've finished. Save my progress