folderweb/docs/04-development/09-breadcrumbs.md

2.3 KiB

Breadcrumbs

buildBreadcrumbs(Context $ctx): array

Returns a breadcrumb trail for nested content directories.

Condition Return
Empty requestPath (frontpage) []
Level 1 path (e.g., /nyheter/) []
Level 2 path (e.g., /nyheter/riksrevisjonen/) []
Level 3+ (e.g., /nyheter/riksrevisjonen/artikkel/) Array of breadcrumb items

Breadcrumb Item Structure

[
    'title' => string,     // Display title
    'url' => string,       // URL with trailing slash
    'isCurrent' => false   // Always false (current page excluded)
]

Title Resolution

  1. title field from metadata.ini
  2. First <h1> in content files (.md, .html, .php)
  3. ucfirst(folder_name) as fallback

URL Construction

Uses slug from metadata if available, otherwise the folder name. URLs are:

  • Encoded with rawurlencode() for safety
  • Always include trailing slash
  • Prefixed with language prefix (from $ctx->get('langPrefix', ''))

Security

  • Path segments containing .. are skipped (path traversal protection)
  • Only existing directories are included
  • URLs are encoded to prevent injection

Usage in Templates

<?php if (!empty($breadcrumbs)): ?>
<nav aria-label="Breadcrumb">
    <ol>
        <?php foreach ($breadcrumbs as $crumb): ?>
        <li>
            <a href="<?= htmlspecialchars($crumb['url']) ?>">
                <?= htmlspecialchars($crumb['title']) ?>
            </a>
        </li>
        <?php endforeach; ?>
        <li aria-current="page"><?= htmlspecialchars($pageTitle ?? '') ?></li>
    </ol>
</nav>
<?php endif; ?>

Tests

Located in devel/tests/helpers/:

  • build_breadcrumbs_empty_path.phpt — frontpage returns empty array
  • build_breadcrumbs_level1.phpt — single level returns empty array
  • build_breadcrumbs_level2.phpt — two levels returns empty array
  • build_breadcrumbs_level3.phpt — three+ levels returns breadcrumb array
  • build_breadcrumbs_security_traversal.phpt — path traversal attempts are skipped
  • build_breadcrumbs_skips_missing_dirs.phpt — missing directories are handled gracefully
  • build_breadcrumbs_slug_override.phpt — metadata slug overrides folder name
  • build_breadcrumbs_extract_title_from_content.phpt — title extracted from content files

Run tests:

cd devel && ./tests/run.sh helpers