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.
Lessons
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().
<?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">| Code | Why 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 link | Lets keyboard users jump past the navigation. Required for WordPress.org themes. |
Watch out: Do not hard-code a<title>tag inheader.php. Since WordPress 4.1, themes addtitle-tagsupport (lesson 11) and WordPress prints the title insidewp_head(). A hard-coded one creates two titles and breaks SEO plugins.
<?php
/**
* The footer for GDC Starter.
*/
?>
</div><!-- #primary -->
<footer class="site-footer">
<p class="site-info">
© <?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.
<?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();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; ?><head> markup from index.php into header.php and the closing tags into footer.php.wp_head() and wp_footer() are wired correctly.header-minimal.php and use it on one template.In accordance with Section 6 & Section 7 of the DPDP Act 2023, third-party analytics and marketing trackers are strictly gated behind your affirmative consent. You may withdraw consent at any time under Section 6(4).
Essential for session authentication (ci_session), Cross-Site Request Forgery security (csrf_cookie_name), and Cloudflare DDoS/bot prevention. Cannot be disabled.
Gated under DPDP Section 7. Allows Google Analytics 4 (Google Consent Mode v2) to measure aggregate, anonymized tool usage.
Enables browser local storage to preserve your theme selection (dark/light mode) and code editor layout between visits.
Used to display developer sponsorships and native tool partner notices.