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:
<!-- 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:
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:
<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>
Klickbare vs. nicht-klickbare Links
Das Script entscheidet automatisch, welche Breadcrumb-Elemente anklickbar sind:
- Klickbar
<a>: Ordner, die eineindex.htmlenthalten - Nicht klickbar
<span>: Ordner ohneindex.html - Aktuelle Seite: Immer nicht klickbar
.breadcrumb-current
// 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:
// 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:
tutorials→ Tutorialscss→ CSSmisc→ Verschiedenes
css-basics→ CSS Basics (enthält "basics")seo-optimization→ SEO Optimization (fileNameToTitle)
Dateinamen mit customTitles anpassen
Die aktuelle Seite (letztes Breadcrumb) nutzt customTitles, falls
vorhanden:
// 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.html→ CSS Einbinden (automatisch formatiert)
Mit customTitle:
css-einbinden.html→ CSS 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:
- Öffne
generate-navigation.js - Finde die Breadcrumb-Funktion
generateBreadcrumbs() - Füge die neue Kategorie hinzu:
// 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';
// ...
- Führe
npm run generateaus
Ordner in blacklistFolders werden automatisch übersprungen und
erscheinen nicht in den Breadcrumbs:
const blacklistFolders = ['noupload', 'node_modules', '.git', 'assets'];
Breadcrumb-Separator ändern
Der Separator (›) kann in der Funktion generateBreadcrumbsHTML()
geändert
werden:
if (!isLast) {
html += '<span class="breadcrumb-separator">›</span>'; // ← Hier ändern
}
// Alternativen:
// → / // > » ⟩
Vollständiger Code
Vollständiger JavaScript-Code
// ============================================================================
// 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:
npm run generate
Mehr aus DevPanicZone!
Tutorials werden geladen...