Spectre Base — Reference
Template hierarchy, shell class reference, PHP hook API, child theme patterns, and Spectre Icons integration for Spectre Base.
Reference for @phcdevworks/spectre-base (current version 1.0.0). For an
introduction, installation, quick start, and when-to-use guidance, see the
Spectre Base overview.
Template hierarchy
The theme ships a complete WordPress template hierarchy. Each file handles a specific route:
| Template file | WordPress route |
|---|---|
index.php |
Catch-all fallback for all unmatched routes |
home.php |
Blog posts index (when a static front page is set) |
front-page.php |
Static front page |
single.php |
Single post |
page.php |
Static page |
archive.php |
Date, category, tag, and author archives |
search.php |
Search results |
404.php |
Not found |
header.php |
Shared header — loaded via get_header() |
footer.php |
Shared footer — loaded via get_footer() |
sidebar.php |
Sidebar — loaded via get_sidebar() |
searchform.php |
Search form partial |
comments.php |
Comments section |
Template parts
Files in spectre-theme/template-parts/:
| Part | Used by |
|---|---|
content-card.php |
index.php, home.php, archive.php |
content-single.php |
single.php |
content-page.php |
page.php, front-page.php |
content-none.php |
All list templates when no posts are found |
Shell class reference
These CSS classes are defined in src/styles/main.css and are safe to use in
any PHP template. All values come from var(--sp-*) tokens.
| Class | Purpose |
|---|---|
spectre-site-container |
Centered, max-width container |
spectre-site-header |
Header shell with neutral background |
spectre-site-footer |
Footer shell with neutral background |
spectre-main |
Main content area with grid spacing |
spectre-main--spacious |
Variant with more block padding |
spectre-panel |
Bordered, padded surface (pages, 404) |
spectre-panel--roomy |
Panel with extra padding |
spectre-panel--centered |
Center-aligned panel |
spectre-panel--dashed |
Panel with dashed border (empty states) |
spectre-card |
Post card with hover shadow |
spectre-card__media |
Image area of a card |
spectre-card__body |
Content area of a card |
spectre-card__title |
Card headline |
spectre-card__excerpt |
Card excerpt text |
spectre-card__readmore |
Card “Read more” anchor |
spectre-post-grid |
Responsive auto-fit grid for cards |
spectre-section |
Content section with gap |
spectre-content |
Post body content area |
spectre-entry-meta |
Date and author metadata row |
spectre-eyebrow |
Small uppercase label |
spectre-title-lg |
Large heading |
spectre-title-xl |
Extra-large heading |
spectre-title-2xl |
2× extra-large heading |
spectre-muted |
Muted text color |
spectre-button |
Base anchor-as-button shell |
spectre-button--primary |
Primary filled button variant |
spectre-widget |
Sidebar widget wrapper |
spectre-widget-title |
Sidebar widget heading |
PHP hook API
The theme exposes action and filter hooks so a child theme or site plugin can
customize header, footer, navigation, and sidebar behavior without copying
parent template files. Place add_action / add_filter calls in your child
theme’s functions.php.
Action hooks
| Hook | Fires in | When |
|---|---|---|
spectre_base_before_header |
header.php |
Immediately before the <header> element |
spectre_base_before_site_branding |
header.php |
Inside .spectre-site-branding, before the logo/site title |
spectre_base_after_site_branding |
header.php |
Inside .spectre-site-branding, after the logo/site title |
spectre_base_after_header |
header.php |
Immediately after the </header> element |
spectre_base_before_footer |
footer.php |
Immediately before the <footer> element |
spectre_base_after_footer |
footer.php |
Immediately after the </footer> element |
spectre_base_before_sidebar($sidebar_id) |
sidebar.php |
Before the <aside> wrapper, only when the sidebar is active |
spectre_base_after_sidebar($sidebar_id) |
sidebar.php |
After the <aside> wrapper, only when the sidebar is active |
// Inject a promo banner just inside the header, in your child theme's functions.php:
add_action('spectre_base_before_site_branding', function () {
echo '<p class="spectre-eyebrow">'
. esc_html__('Now booking 2026 projects', 'your-child-theme')
. '</p>';
});
These complement the core WordPress template-loading hooks that already fire
around these files: get_header, get_footer, and get_sidebar, plus
wp_head, wp_body_open, and wp_footer inside header.php/footer.php.
Filter hooks
| Hook | Declared in | Purpose |
|---|---|---|
spectre_base_primary_nav_args |
header.php |
Filters the wp_nav_menu() args array for the primary navigation |
spectre_base_footer_nav_args |
footer.php |
Filters the wp_nav_menu() args array for the footer navigation |
spectre_base_footer_social_icons |
footer.php |
Filters the array of social icon entries rendered in the footer |
spectre_base_sidebar_id |
sidebar.php |
Filters which registered sidebar ID sidebar.php renders (default sidebar-main) |
// Swap the registered sidebar that sidebar.php renders:
add_filter('spectre_base_sidebar_id', fn () => 'sidebar-shop');
// Add a custom menu class to the primary navigation:
add_filter('spectre_base_primary_nav_args', function (array $args) {
$args['menu_class'] .= ' my-client-nav';
return $args;
});
Footer social icons
Add site-specific social icon links without modifying the theme directly:
// In your child theme's functions.php or a site plugin:
add_filter('spectre_base_footer_social_icons', function () {
return [
['name' => 'github', 'size' => '20', 'url' => 'https://github.com/yourorg'],
['name' => 'linkedin', 'size' => '20', 'url' => 'https://linkedin.com/company/yourco'],
];
});
This requires the spectre-icons plugin to be active. If the plugin is not active, the social row is not rendered regardless of the filter output.
Swapping templates entirely
For changes too large for a hook, WordPress’s standard child theme lookup
applies: any file a child theme provides under the same name (header.php,
footer.php, sidebar.php, files in template-parts/, etc.) takes priority
over the parent theme’s copy. No filter is required. Prefer the hooks above
when possible — they keep the child theme on the parent theme’s update path.
CSS custom property namespace
Every --sp-* custom property consumed by this theme is owned and defined by
Spectre Tokens (via Spectre UI). The theme
itself never declares a --sp-* custom property — it only reads them with
var().
Safe to consume (read-only): any --sp-* variable, in any child theme
stylesheet or theme.json, via var(--sp-...).
Not safe to declare: do not define or redeclare a --sp-* custom property
in a child theme, site plugin, or theme.json. The --sp-* namespace is
reserved for the upstream Spectre token contract; locally redefining one of
these variables creates drift and will be flagged by npm run check:drift.
To change a token’s value for a client brand, override the relevant entries
in the child theme’s theme.json settings.color, settings.typography, and
settings.spacing palettes/presets (which already reference var(--sp-*)),
or configure @phcdevworks/spectre-tokens upstream. Never hardcode hex, rem,
or px values in place of token references.
Adding custom shell styles
Always use var(--sp-*) tokens in child theme or additional CSS:
@layer components {
.my-hero {
background-color: var(--sp-surface-alternate);
padding-block: var(--sp-space-64);
}
}
Child themes
Generating a child theme
npm run create:child -- <client-name>
This scaffolds spectre-child-<client-name>/ with:
style.css— WordPress child theme header declaringTemplate: spectre-theme, GPL license, and WP.org standard tagsfunctions.php— enqueues the child stylesheet withspectre-base-styleas its dependency so it loads after the parent bundletheme.json— minimal, inherits the full parent token set and is ready for brand-specific overrides
The Template: spectre-theme header must match the parent theme’s directory
name exactly.
Overriding tokens via theme.json
Override color, typography, and spacing presets in the child theme’s
theme.json. Keep every value as a var(--sp-*) reference. Do not introduce
hex codes, raw px/rem values, or new custom properties.
Overriding templates
Provide a same-named file in the child theme directory — WordPress loads it instead of the parent’s copy. Prefer hook-based overrides for smaller customizations (see PHP hook API above).
Validation commands
| Command | What it does |
|---|---|
npm run build |
TypeScript check + Vite production build |
npm run check |
Full validation gate — must pass before any handoff |
npm run check:assets |
Validate Vite manifest and asset contract |
npm run check:drift |
Scan for hardcoded visual values and design-system drift |
npm run lint |
ESLint for TypeScript |
npm run lint:php |
PHP syntax validation |
npm run format |
Apply Prettier formatting |
check:drift expected output is empty or only token-backed references. Any
local visual value must be removed or justified before merging.
Spectre Icons integration
This theme is compatible with the spectre-icons WordPress plugin. Once
installed and activated, the [spectre-icon] shortcode is available in any
template or content area.
The theme footer automatically renders icon links when the plugin is active. To check availability before rendering icons in a custom template:
<?php if (spectre_base_has_icons()) : ?>
<?php echo do_shortcode('[spectre-icon name="arrow-right" size="16"]'); ?>
<?php endif; ?>
Standard icon shortcode usage:
[spectre-icon name="github" size="20"]
[spectre-icon name="twitter" size="20"]
[spectre-icon name="linkedin" size="20"]
Troubleshooting
| Failure | Cause | Fix |
|---|---|---|
| Blank page in production | Compiled manifest missing or stale | Run npm run build then npm run check:assets; confirm spectre-theme/dist/.vite/manifest.json lists src/js/main.ts as an entry |
| Styles not updating in development | Wrong environment or dev server not running | Confirm WP_ENVIRONMENT_TYPE=development in wp-config.php and npm run dev is running on the expected port |
check:drift reports unexpected matches |
Raw hex, pixel, rem, or Tailwind utility added to src/ or PHP |
Replace with a var(--sp-*) token or a Spectre component |
| PHP lint fails with syntax error | PHP syntax error in a template file | Fix the reported file, then rerun npm run lint:php (PHP 8.2 is the CI target) |
rg not found |
ripgrep not installed | Install ripgrep (brew install ripgrep on macOS, apt install ripgrep on Ubuntu) |
| Custom element not defined | CSS loaded but defineSpectreComponents() not called |
Confirm src/js/main.ts imports and calls defineSpectreComponents(), and that npm run build completed without errors |