Browse Source

phase 3: header -> FSE template part (bridged)

Same pattern as the footers. Header chrome (navbar + offcanvas nav) now lives in
parts/header.html; header.php keeps only the document <head> + wp_head() + <body>
open (can't live in a block part) then calls block_template_part('header').

- Nav links -> root-relative (domain-agnostic).
- theme.json registers the header part (area "header").
- Verified now/contact/about/studio render header + offcanvas + Work, 200, no errors;
  bespoke front-page.php unaffected.

All shared chrome (header + both footers) is now in parts/, live via the bridge and
ready for the FSE flip.
windhamdavid 3 days ago
parent
commit
e0d1eb21e2
5 changed files with 42 additions and 24 deletions
  1. 2 1
      _claude/notes/page-templates.md
  2. 8 0
      _claude/notes/upgrade-plan.md
  3. 6 23
      header.php
  4. 25 0
      parts/header.html
  5. 1 0
      theme.json

+ 2 - 1
_claude/notes/page-templates.md

@@ -46,6 +46,7 @@ Companion: [[upgrade-plan]]. Diff metric = changed lines vs plain `page.php`.
   `block_template_part(...)`. `get_footer('home')` → footer-home (about, archive, bio, contact, desk,
   `block_template_part(...)`. `get_footer('home')` → footer-home (about, archive, bio, contact, desk,
   sitemap, studio); default `get_footer()` → footer (analytics, art, music, now). In the FSE flip,
   sitemap, studio); default `get_footer()` → footer (analytics, art, music, now). In the FSE flip,
   templates reference these parts directly via `<!-- wp:template-part -->`.
   templates reference these parts directly via `<!-- wp:template-part -->`.
-- **Header (DONE):** single `header.php` (see note above).
+- **Header (DONE — now a block part):** single header, chrome in `parts/header.html`; `header.php`
+  keeps only `<head>`/`wp_head()`/`<body>` open + `block_template_part('header')`. FSE-ready.
 - **Already selectable (have `Template Name`):** about→Home, archive→Posts, desk→Desk, music→Music, now→Now, sitemap→Sitemap, + our no-title→No Title. The rest (analytics, art, bio, contact, studio) are **slug-based** (`page-{slug}.php` auto-applies).
 - **Already selectable (have `Template Name`):** about→Home, archive→Posts, desk→Desk, music→Music, now→Now, sitemap→Sitemap, + our no-title→No Title. The rest (analytics, art, bio, contact, studio) are **slug-based** (`page-{slug}.php` auto-applies).
 - **Bespoke/self-contained:** `front-page.php` (homepage) bypasses the header/footer system — decide in Phase 3 whether it stays bespoke PHP or becomes a block template.
 - **Bespoke/self-contained:** `front-page.php` (homepage) bypasses the header/footer system — decide in Phase 3 whether it stays bespoke PHP or becomes a block template.

+ 8 - 0
_claude/notes/upgrade-plan.md

@@ -136,6 +136,14 @@ Considering moving the whole site from **davidawindham.com → davidwindham.com*
 
 
 ## Changelog
 ## Changelog
 
 
+- **2026-06-19** — **Phase 3: header → FSE template part too.** Same bridge pattern as the footers:
+  the header chrome (navbar + offcanvas nav) now lives in `parts/header.html`; `header.php` keeps
+  only the document `<head>` + `wp_head()` + `<body>` open (can't go in a block part) and then calls
+  `block_template_part('header')`. Nav links → root-relative. `theme.json` registers the `header`
+  part (area "header"). Verified across now/contact/about/studio (header + offcanvas + Work item, 200,
+  no errors); bespoke `front-page.php` unaffected. **All shared chrome (header + both footers) is now
+  in `parts/`, rendered live via the bridge and ready for the FSE flip.**
+
 - **2026-06-19** — **Phase 3: footers migrated to FSE template parts (live via bridge).** Both
 - **2026-06-19** — **Phase 3: footers migrated to FSE template parts (live via bridge).** Both
   footer variations kept, now sourced from block template parts: `parts/footer.html` (minimal) +
   footer variations kept, now sourced from block template parts: `parts/footer.html` (minimal) +
   `parts/footer-home.html` (full nav columns + social + cookie notice). The classic `footer.php` /
   `parts/footer-home.html` (full nav columns + social + cookie notice). The classic `footer.php` /

+ 6 - 23
header.php

@@ -14,26 +14,9 @@
 <?php if ( is_singular() ) echo '<link rel="canonical" href="' . get_permalink() . '" />'; ?>
 <?php if ( is_singular() ) echo '<link rel="canonical" href="' . get_permalink() . '" />'; ?>
 </head>
 </head>
 <body <?php page_bodyclass(); ?>>
 <body <?php page_bodyclass(); ?>>
-<header id="header">
-	<div class="navbar fixed-top">
-		<div class="container">
-			<div class="site-title">
-        <a href="#offcanvasNav" class="navbar-brand navbar-right light"  data-bs-toggle="offcanvas" data-bs-target="#offcanvasNav" aria-controls="offcanvasNav" title="David A. Windham" rel="home">David A. Windham</a>
-			</div>
-		</div>
-	</div>
-</header>
-<div class="offcanvas offcanvas-top text-bg-blue" tabindex="-1" id="offcanvasNav" aria-labelledby="offcanvasNavLabel">
-  <nav class="d-flex justify-content-center" role="navigation">
-    <ul class="nav list-group list-group-horizontal pt-3 fs-5">
-      <li class="list-group-item list-group-flush"><a href="<?php echo home_url( '/' ); ?>"><i class="bi bi-house"></i></a></li>
-      <li class="list-group-item"><a href="<?php echo home_url( '/' ); ?>about"><i class="bi bi-person"></i> About</a></li>
-      <li class="list-group-item"><a href="<?php echo home_url( '/' ); ?>contact"><i class="bi bi-envelope"></i> Contact</a></li>
-      <li class="list-group-item"><a href="<?php echo home_url( '/' ); ?>desk"><i class="bi bi-pen"></i> Desk</a></li>
-      <li class="list-group-item"><a href="<?php echo home_url( '/' ); ?>now"><i class="bi bi-hourglass"></i> Now</a></li>
-      <li class="list-group-item"><a href="<?php echo home_url( '/' ); ?>studio"><i class="bi bi-lightbulb"></i> Studio</a></li>
-      <li class="list-group-item"><a href="<?php echo home_url( '/' ); ?>work"><i class="bi bi-briefcase"></i> Work</a></li>
-      <li class="list-group-item"><a href="<?php echo home_url( '/' ); ?>sitemap"><i class="bi bi-diagram-3"></i></a></li>
-    </ul>
-  </nav>
-</div>
+<?php
+/* Header chrome (navbar + offcanvas nav) lives in parts/header.html (block template
+   part), shared with the FSE flip; rendered here for the classic theme. The document
+   <head> + <body> open stay in PHP — they can't live in a block part. */
+block_template_part( 'header' );
+?>

+ 25 - 0
parts/header.html

@@ -0,0 +1,25 @@
+<!-- wp:html -->
+<header id="header">
+	<div class="navbar fixed-top">
+		<div class="container">
+			<div class="site-title">
+        <a href="#offcanvasNav" class="navbar-brand navbar-right light"  data-bs-toggle="offcanvas" data-bs-target="#offcanvasNav" aria-controls="offcanvasNav" title="David A. Windham" rel="home">David A. Windham</a>
+			</div>
+		</div>
+	</div>
+</header>
+<div class="offcanvas offcanvas-top text-bg-blue" tabindex="-1" id="offcanvasNav" aria-labelledby="offcanvasNavLabel">
+  <nav class="d-flex justify-content-center" role="navigation">
+    <ul class="nav list-group list-group-horizontal pt-3 fs-5">
+      <li class="list-group-item list-group-flush"><a href="/"><i class="bi bi-house"></i></a></li>
+      <li class="list-group-item"><a href="/about"><i class="bi bi-person"></i> About</a></li>
+      <li class="list-group-item"><a href="/contact"><i class="bi bi-envelope"></i> Contact</a></li>
+      <li class="list-group-item"><a href="/desk"><i class="bi bi-pen"></i> Desk</a></li>
+      <li class="list-group-item"><a href="/now"><i class="bi bi-hourglass"></i> Now</a></li>
+      <li class="list-group-item"><a href="/studio"><i class="bi bi-lightbulb"></i> Studio</a></li>
+      <li class="list-group-item"><a href="/work"><i class="bi bi-briefcase"></i> Work</a></li>
+      <li class="list-group-item"><a href="/sitemap"><i class="bi bi-diagram-3"></i></a></li>
+    </ul>
+  </nav>
+</div>
+<!-- /wp:html -->

+ 1 - 0
theme.json

@@ -132,6 +132,7 @@
     }
     }
   },
   },
   "templateParts": [
   "templateParts": [
+    { "name": "header", "title": "Header", "area": "header" },
     { "name": "footer", "title": "Footer", "area": "footer" },
     { "name": "footer", "title": "Footer", "area": "footer" },
     { "name": "footer-home", "title": "Footer (Home)", "area": "footer" }
     { "name": "footer-home", "title": "Footer (Home)", "area": "footer" }
   ]
   ]