/** * Template-Rendering und Filterung. * * Rendert die Template-Karte und wendet Filter (Typ, Suche) an. */ let currentEditTemplate = null; /** * Render Template-Karten in den Container * @param {Array} templates - Zu rendernde Templates */ function renderTemplates(templates) { const container = document.getElementById('templates'); const count = document.getElementById('count'); count.textContent = `${templates.length} Template(s)`; if (templates.length === 0) { container.innerHTML = '

Keine Templates gefunden

Füge Templates in den templates/ Ordnern hinzu.

'; return; } container.innerHTML = templates.map(t => `

${esc(t.name)}

🏷️ ${esc(t.type)} 📄 ${esc(t.format)} 📌 v${esc(t.version)}

${esc(t.description) || 'Keine Beschreibung'}

${t.tags.map(tag => `${esc(tag)}`).join('')}
`).join(''); } /** * Filter-State: aktueller Typ-Filter */ let currentType = null; let currentQuery = ''; /** * Extrahiere Typ aus URL-Hash * @returns {string|null} Typ-Filter oder null */ function parseTypeFromHash() { const match = window.location.hash.match(/[?&]type=([^&]+)/); return match ? decodeURIComponent(match[1]) : null; } /** * Setze Nav-Active-State basierend auf Typ * @param {string|null} type - Typ-Filter */ function setNavActive(type) { document.querySelectorAll('.nav a').forEach(a => { const m = (a.getAttribute('href') || '').match(/type=([^&]+)/); const aType = m ? m[1] : null; a.classList.toggle('active', aType === type); }); } /** * Wende Filter an und render Templates */ function applyFilters() { let list = window.allTemplates || []; if (currentType) { list = list.filter(t => t.type === currentType); } if (currentQuery) { const q = currentQuery; list = list.filter(t => (t.name || '').toLowerCase().includes(q) || (t.description || '').toLowerCase().includes(q) || (t.tags || []).some(tag => tag.toLowerCase().includes(q)) ); } setNavActive(currentType); renderTemplates(list); } // Event delegation: click on template cards routes to action functions document.addEventListener('click', (e) => { const btn = e.target.closest('.btn[data-path]'); if (!btn) return; const card = btn.closest('.template-item'); if (!card) return; const path = btn.dataset.path; const action = btn.classList.contains('btn-view') ? 'viewTemplate' : btn.classList.contains('btn-edit') ? 'editModalContent' : btn.classList.contains('btn-copy') ? 'copyContent' : btn.classList.contains('btn-tune') ? 'tuneModalContent' : null; if (action) window[action](path); }); // Export for main.js (global scope, loaded before main.js) // renderTemplates, applyFilters, parseTypeFromHash, setNavActive // currentType, currentQuery sind als globale Variablen verfügbar