Last updated on June 8, 2026
Goal: make every CPT page and its search results reuse the same shared template parts.
What was done
Main CPT listing pages (page templates, archives) were updated to call template-parts/* instead of duplicating loop/markup. Search page (search.php) was refactored to use a central CPT mapping and to call per‑CPT search wrappers which simply pass the search WP_Query to the shared template-parts.
For each CPT there are now two pieces:
template-parts/<cpt>-grid.phportemplate-parts/<cpt>-list.php— the single reusable layout (grid or compact list).template-parts/search/<cpt>.php— minimal wrapper used bysearch.phpthat forwards query, info, and search_term into the shared template part.
This makes search results and original CPT pages identical in layout and behavior (only the query source differs).
Centralized CPT metadata (emoji / title / links)
A central mapping of CPT display metadata (title, emoji, link) was created so search.php, footnotes, and all template‑parts read the same values. The mapping was reordered specifically for the search results so result sections appear in the desired grouping/order.
Result: headings, emojis, and links are consistent across all templates and footnotes.
Files created / updated (high level)
Shared template parts (single source for layout):
template-parts/artist-grid.php(artists listing — portraits)template-parts/song-grid.php(search‑style song grid partial)template-parts/image-grid.php(image gallery partial — square/rounded thumbnails)template-parts/book-grid.phptemplate-parts/movie-grid.phptemplate-parts/organization-grid.phptemplate-parts/reference-list.phptemplate-parts/quote-list.phptemplate-parts/excerpt-list.phptemplate-parts/concept-list.phptemplate-parts/profile-list.phptemplate-parts/lyric-grid.php(lyric / song‑excerpt list)template-parts/chapter-grid.php(used for chapters + fragments)
Search wrappers (minimal files that forward $query):
template-parts/search/artist.php, .../song.php, .../image.php, .../book.php, etc. (one per CPT).
Page templates updated to call shared parts:
e.g. page-books.php → now calls get_template_part('template-parts/book','grid', [...])
e.g. page-image-gallery.php → now calls get_template_part('template-parts/image','grid', [...])
(All CPT directory pages were converted to the same pattern.)
Footnotes / inc/footnotes: Existing footnotes code was adapted where needed to use the same image fallback logic and the same UI pattern for small referenced lists (fn_images, fn_references updated to prefer ACF image then featured image, output rounded thumbnails, etc.).
Uniform UX details implemented
- Heading alignment fix: headings moved outside grid wrappers (no more heading becoming the first grid item and causing an indent).
- Heading format: all CPT sections consistently show emoji + title + optional “containing ‘search term’” (search wrappers pass
search_termto the part). - Image handling (consistent across all templates): Prefer
cover_image(ACF) when present, else fall back topost_thumbnail. Deliver a consistent thumbnail size (use WP image sizes, e.g.mediumorthumbnail) and render withobject-fit: coverand a fixed width/height to square and round. This fixes the “disparate image sizes” problem while keeping the grid/list layout. - List style: compact lists (quotes, excerpts, lyrics, concepts, profiles, references) follow same structural pattern: 48×48 circular thumbnail on the left, title + trimmed text on the right, “Source: …” link under the text when relevant.
- Lyric (song excerpt) behavior: title still links to the lyric post; a “Source:” line was added beneath each lyric item that links to the song CPT (via the
songACF object field). - Search wrappers are minimal: they only prepare query, info, search_term and call
get_template_part()so future changes live in one file.
Search‑specific behavior
search.php now:
- Uses the centralized CPT mapping (
$cpt_sections) as the single source for section titles & emojis. - Builds a
WP_Queryper CPT (and runs Relevanssi if available) and then calls the per‑CPT search wrapper to render results using the shared template part.