File: /var/www/html/wp-content/themes/custom-theme/inc/breadcrumb.php
<?php
/**
* Breadcrumb — reusable PHP partial
*
* Auto-generates from WordPress page hierarchy.
* Call cae_breadcrumb() from any template.
*
* Built forward-from-Figma 2026-04-16 by Sprout.
* Figma source: Breadcrumb component (4151:425120)
* Used on: Ways to Give (19268:574315), Donate VFF (19268:584285), and all pages.
*
* Typography: Acumin Pro 18px/26px
* - Ancestor items: Regular, granite (#767769), linked
* - Current page: Bold, evergreen (#004F39), not linked
* - Separator: " / " with 8px horizontal padding
*/
if (!defined('ABSPATH')) {
exit;
}
/**
* Render the breadcrumb navigation.
*
* @param array $args Optional overrides:
* 'figma_id' => data-figma-id for the container (default: 4151:425120)
* 'home_text' => label for home link (default: 'Home')
*/
function cae_breadcrumb($args = []) {
$defaults = [
'figma_id' => '4151:425120',
'home_text' => 'Home',
];
$args = wp_parse_args($args, $defaults);
// Don't render on the front page
if (is_front_page()) {
return;
}
$crumbs = [];
// Home
$crumbs[] = [
'label' => $args['home_text'],
'url' => home_url('/'),
];
if (is_page()) {
$ancestors = get_post_ancestors(get_the_ID());
// Ancestors come in reverse order (immediate parent first)
$ancestors = array_reverse($ancestors);
foreach ($ancestors as $ancestor_id) {
$crumbs[] = [
'label' => get_the_title($ancestor_id),
'url' => get_permalink($ancestor_id),
];
}
// Current page (no link)
$crumbs[] = [
'label' => get_the_title(),
'url' => null,
];
} elseif (is_single()) {
// For single posts, show the post type archive if it exists
$post_type = get_post_type();
$post_type_obj = get_post_type_object($post_type);
if ($post_type_obj && $post_type_obj->has_archive) {
$crumbs[] = [
'label' => $post_type_obj->labels->name,
'url' => get_post_type_archive_link($post_type),
];
}
$crumbs[] = [
'label' => get_the_title(),
'url' => null,
];
} elseif (is_archive()) {
$crumbs[] = [
'label' => get_the_archive_title(),
'url' => null,
];
} elseif (is_search()) {
$crumbs[] = [
'label' => 'Search Results',
'url' => null,
];
} elseif (is_404()) {
$crumbs[] = [
'label' => 'Page Not Found',
'url' => null,
];
}
// Don't render if only Home
if (count($crumbs) < 2) {
return;
}
$last_index = count($crumbs) - 1;
?>
<nav class="cae-breadcrumb" data-figma-id="<?php echo esc_attr($args['figma_id']); ?>" aria-label="Breadcrumb">
<ol class="cae-breadcrumb__list" itemscope itemtype="https://schema.org/BreadcrumbList">
<?php foreach ($crumbs as $i => $crumb):
$is_last = ($i === $last_index);
?>
<li class="cae-breadcrumb__item" itemprop="itemListElement" itemscope itemtype="https://schema.org/ListItem">
<?php if (!$is_last && $crumb['url']): ?>
<a href="<?php echo esc_url($crumb['url']); ?>"
class="cae-breadcrumb__link"
itemprop="item">
<span itemprop="name"><?php echo esc_html($crumb['label']); ?></span>
</a>
<?php else: ?>
<span class="cae-breadcrumb__current" itemprop="item" aria-current="page">
<span itemprop="name"><?php echo esc_html($crumb['label']); ?></span>
</span>
<?php endif; ?>
<meta itemprop="position" content="<?php echo esc_attr($i + 1); ?>">
<?php if (!$is_last): ?>
<span class="cae-breadcrumb__separator" aria-hidden="true">/</span>
<?php endif; ?>
</li>
<?php endforeach; ?>
</ol>
</nav>
<?php
}