Hero Breadcrumbs

Automatisierte Brotkrumen-Navigation

Hero Breadcrumbs

Breadcrumbs (Brotkrumen-Navigation) zeigen den Pfad zur aktuellen Seite und werden automatisch aus der Ordnerstruktur generiert.

HTML-Struktur in der Hero-Section

Die Breadcrumbs werden in der Hero-Section als erstes Element eingefügt:

HTML
<!-- Hero Section -->
<section class="hero tutorial-hero">
    <div class="container">
        <!-- Breadcrumbs werden hier automatisch eingefügt -->
        <nav class="breadcrumbs"></nav>
        
        <h1 class="hero-title">Seitentitel</h1>
        <p class="hero-subtitle">Untertitel</p>
    </div>
</section>

Wie funktioniert's?

Das Script analysiert den Dateipfad und erstellt daraus eine Breadcrumb-Kette:

Plain Text
Dateipfad:
tutorials/css/css-basics/css-einbinden.html

Wird zu Breadcrumbs:
Home › Tutorials › CSS › CSS Basics › CSS einbinden

Beispiel: Generierte Breadcrumbs

Aus dem leeren <nav class="breadcrumbs"></nav> wird:

HTML
<nav class="breadcrumbs">
    <a href="/" class="breadcrumb-link">Home</a>
    <span class="breadcrumb-separator">›</span>
    <a href="/tutorials/" class="breadcrumb-link">Tutorials</a>
    <span class="breadcrumb-separator">›</span>
    <a href="/tutorials/css/" class="breadcrumb-link">CSS</a>
    <span class="breadcrumb-separator">›</span>
    <a href="/tutorials/css/css-basics/" class="breadcrumb-link">CSS Basics</a>
    <span class="breadcrumb-separator">›</span>
    <span class="breadcrumb-current">CSS einbinden</span>
</nav>

Das Script entscheidet automatisch, welche Breadcrumb-Elemente anklickbar sind:

  • Klickbar <a>: Ordner, die eine index.html enthalten
  • Nicht klickbar <span>: Ordner ohne index.html
  • Aktuelle Seite: Immer nicht klickbar .breadcrumb-current
JavaScript
// URL: Wenn es ein index.html im Ordner gibt, verlinken
const indexPath = path.join(BASE_DIR, currentPath, 'index.html');
const url = fs.existsSync(indexPath) ? `/${currentPath}/` : null;

// url = '/tutorials/css/' → Klickbar
// url = null → Nicht klickbar

Ordnernamen automatisch umbenennen

Bestimmte Ordnernamen werden automatisch in schönere Labels umgewandelt:

JavaScript
// Spezielle Ordner umbenennen
let label = part;
if (part === 'tutorials') label = 'Tutorials';
else if (part === 'html') label = 'HTML';
else if (part === 'css') label = 'CSS';
else if (part === 'bootstrap') label = 'Bootstrap';
else if (part === 'javascript') label = 'JavaScript';
else if (part === 'php') label = 'PHP';
else if (part === 'misc') label = 'Verschiedenes';
else if (part.includes('basics')) label = 'Basics';
else if (part.includes('advanced')) label = 'Advanced';
else if (part.includes('specials')) label = 'Specials';
else {
    // Normale Ordnernamen formatieren (z.B. 'my-folder' → 'My Folder')
    label = fileNameToTitle(part);
}

Beispiele der Umwandlung:

  • tutorialsTutorials
  • cssCSS
  • miscVerschiedenes
  • css-basicsCSS Basics (enthält "basics")
  • seo-optimizationSEO Optimization (fileNameToTitle)

Dateinamen mit customTitles anpassen

Die aktuelle Seite (letztes Breadcrumb) nutzt customTitles, falls vorhanden:

JavaScript
// In generate-navigation.js
const customTitles = {
    'tutorials/css/css-basics/css-einbinden.html': 'CSS einbinden',
    'tutorials/html/html-advanced/html-iframes.html': 'iFrames',
    'tutorials/misc/projects/devpaniczone-tutorial-template.html': 'Diese Seite',
    // ...
};

// Im Breadcrumb-Code:
const fileName = part.replace('.html', '');
const label = customTitles[filePath] || fileNameToTitle(fileName);

Ohne customTitle:

  • css-einbinden.htmlCSS Einbinden (automatisch formatiert)

Mit customTitle:

  • css-einbinden.htmlCSS einbinden (wie definiert in customTitles)

Neue Hauptkategorie zu Breadcrumbs hinzufügen

Wenn du eine neue Hauptkategorie erstellst (z.B. "React"), füge sie zur Ordner-Mapping hinzu:

  1. Öffne generate-navigation.js
  2. Finde die Breadcrumb-Funktion generateBreadcrumbs()
  3. Füge die neue Kategorie hinzu:
JavaScript
// Spezielle Ordner umbenennen
let label = part;
if (part === 'tutorials') label = 'Tutorials';
else if (part === 'html') label = 'HTML';
else if (part === 'css') label = 'CSS';
else if (part === 'bootstrap') label = 'Bootstrap';
else if (part === 'javascript') label = 'JavaScript';
else if (part === 'php') label = 'PHP';
else if (part === 'react') label = 'React';  // ← Neue Kategorie
else if (part === 'misc') label = 'Verschiedenes';
// ...
  1. Führe npm run generate aus
Hinweis: Blacklist

Ordner in blacklistFolders werden automatisch übersprungen und erscheinen nicht in den Breadcrumbs:

const blacklistFolders = ['noupload', 'node_modules', '.git', 'assets'];

Der Separator (›) kann in der Funktion generateBreadcrumbsHTML() geändert werden:

JavaScript
if (!isLast) {
    html += '<span class="breadcrumb-separator">›</span>';  // ← Hier ändern
}

// Alternativen:
// → / // > » ⟩

Vollständiger Code

Vollständiger JavaScript-Code
JavaScript
// ============================================================================
// BREADCRUMBS
// ============================================================================

/**
 * Generiert Breadcrumbs aus dem Dateipfad
 */
function generateBreadcrumbs(filePath) {
    const parts = filePath.replace(/\\/g, '/').split('/');
    const breadcrumbs = [{ label: 'Home', url: '/' }];

    let currentPath = '';

    for (let i = 0; i < parts.length; i++) {
        const part = parts[i];

        // Letztes Element (Dateiname)
        if (i === parts.length - 1) {
            const fileName = part.replace('.html', '');
            const label = customTitles[filePath] || fileNameToTitle(fileName);
            breadcrumbs.push({ label, url: null }); // Kein Link für aktuelle Seite
        }
        // Ordner
        else if (part && !blacklistFolders.includes(part)) {
            currentPath += (currentPath ? '/' : '') + part;

            // Spezielle Ordner umbenennen
            let label = part;
            if (part === 'tutorials') label = 'Tutorials';
            else if (part === 'html') label = 'HTML';
            else if (part === 'css') label = 'CSS';
            else if (part === 'bootstrap') label = 'Bootstrap';
            else if (part === 'javascript') label = 'JavaScript';
            else if (part === 'php') label = 'PHP';
            else if (part === 'misc') label = 'Verschiedenes';
            else if (part.includes('basics')) label = 'Basics';
            else if (part.includes('advanced')) label = 'Advanced';
            else if (part.includes('specials')) label = 'Specials';
            else {
                // Normale Ordnernamen formatieren
                label = fileNameToTitle(part);
            }

            // URL: Wenn es ein index.html im Ordner gibt, verlinken
            const indexPath = path.join(BASE_DIR, currentPath, 'index.html');
            const url = fs.existsSync(indexPath) ? `/${currentPath}/` : null;

            breadcrumbs.push({ label, url });
        }
    }

    return breadcrumbs;
}

/**
 * Generiert HTML für Breadcrumbs
 */
function generateBreadcrumbsHTML(breadcrumbs, currentFile) {
    let html = '';

    breadcrumbs.forEach((crumb, index) => {
        const isLast = index === breadcrumbs.length - 1;

        if (crumb.url) {
            // Verwende absolute Pfade
            const absolutePath = crumb.url === '/' ? '/' : crumb.url;
            html += `<a href="${absolutePath}" class="breadcrumb-link">${crumb.label}</a>`;
        } else {
            html += `<span class="breadcrumb-current">${crumb.label}</span>`;
        }

        if (!isLast) {
            html += '<span class="breadcrumb-separator">›</span>';
        }
    });

    return html;
}

/**
 * Aktualisiert Breadcrumbs in allen HTML-Dateien
 */
function updateBreadcrumbs(files) {
    let updatedCount = 0;

    files.forEach(file => {
        const filePath = path.join(BASE_DIR, file);
        let content = fs.readFileSync(filePath, 'utf8');

        // Suche nach <nav class="breadcrumbs"></nav>
        const breadcrumbsRegex = /<nav\s+class=["']breadcrumbs["'][^>]*>[\s\S]*?<\/nav>/;

        if (breadcrumbsRegex.test(content)) {
            const breadcrumbs = generateBreadcrumbs(file);
            const breadcrumbsHTML = generateBreadcrumbsHTML(breadcrumbs, file);

            const newBreadcrumbs = `<nav class="breadcrumbs">\n        ${breadcrumbsHTML}\n    </nav>`;
            content = content.replace(breadcrumbsRegex, newBreadcrumbs);

            fs.writeFileSync(filePath, content, 'utf8');
            updatedCount++;
        }
    });

    console.log(`✅ Breadcrumbs aktualisiert in ${updatedCount} Dateien`);
}

Ausführen

Nach allen Änderungen ausführen:

Plain Text
npm run generate

Mehr aus DevPanicZone!

Tutorials werden geladen...