// If your pages are .html, rename them to .php OR configure Apache/Nginx to parse .html as PHP. function bc_base_url(): string { $isHttps = ( (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') || (!empty($_SERVER['SERVER_PORT']) && $_SERVER['SERVER_PORT'] == 443) || (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https') ); $scheme = $isHttps ? 'https' : 'http'; $host = $_SERVER['HTTP_HOST'] ?? 'localhost'; // If your site is in a subdirectory, set it here (e.g., '/site') $subdir = rtrim(dirname($_SERVER['SCRIPT_NAME'] ?? ''), '/\\'); if ($subdir === '/' || $subdir === '\\' || $subdir === '.') $subdir = ''; return $scheme.'://'.$host.$subdir; } function bc_segments(): array { // Strip query/hash, normalize, remove leading subdir if present $reqUri = $_SERVER['REQUEST_URI'] ?? '/'; $parsed = parse_url($reqUri); $path = $parsed['path'] ?? '/'; // Normalize: remove subdir portion so crumbs start after your base path $subdir = rtrim(dirname($_SERVER['SCRIPT_NAME'] ?? ''), '/\\'); if ($subdir && $subdir !== '.' && $subdir !== '/') { // Ensure we only strip an actual prefix match if (strpos($path, $subdir.'/') === 0) { $path = substr($path, strlen($subdir)); } } $path = trim($path, '/'); if ($path === '' || $path === 'index.php' || $path === 'index.html') { return []; // homepage → no segments } $raw = array_values(array_filter(explode('/', $path), function ($seg) { return $seg !== ''; })); // Remove a trailing index.* if present $last = end($raw); if ($last && preg_match('~^index\.(php|html|htm)$~i', $last)) { array_pop($raw); } return $raw; } function bc_humanize(string $seg): string { // Remove extensions, decode, replace separators, title-case lightly $seg = preg_replace('~\.(php|html|htm)$~i', '', $seg); $seg = urldecode($seg); $seg = str_replace(['-', '_'], ' ', $seg); $seg = trim($seg); // Uppercase first letter of words without mangling acronyms too much return preg_replace_callback('/\\b([a-z])/i', function ($m) { return strtoupper($m[1]); }, $seg); } function render_breadcrumb(array $title_map = [], bool $hide_on_home = true, string $home_label = 'Home'): void { $base = rtrim(bc_base_url(), '/'); $segs = bc_segments(); if ($hide_on_home && empty($segs)) { // On homepage: optionally print nothing. Flip flag to show just "Home" if you want. return; } // Visible breadcrumb echo ''; // JSON-LD schema $items = []; $position = 1; $items[] = [ '@type' => 'ListItem', 'position' => $position++, 'name' => $home_label, 'item' => $base.'/' ]; $build = ''; foreach ($segs as $seg) { $build .= '/'.$seg; $name = $title_map[$seg] ?? bc_humanize($seg); $items[] = [ '@type' => 'ListItem', 'position' => $position++, 'name' => $name, 'item' => $base.$build ]; } $schema = [ '@context' => 'https://schema.org', '@type' => 'BreadcrumbList', 'itemListElement' => $items ]; echo ''; }