Lädt...

HTML Testing und Validierung

HTML Testing und Validierung ist der Prozess der Überprüfung, ob HTML-Code syntaktisch korrekt und den geltenden Webstandards entsprechend geschrieben ist. Dieser Schritt ist entscheidend für die Erstellung stabiler, zugänglicher und plattformübergreifend kompatibler Websites.
Wie beim Bau eines Hauses bildet HTML das Fundament. Wenn dieses instabil oder fehlerhaft ist, werden CSS-Stile (die "Dekoration") oder JavaScript-Funktionen ("Elektronik") unzuverlässig funktionieren.
Ob Portfolio-Seite, Blog, Online-Shop, Nachrichtenportal oder soziale Plattform: HTML-Test und Validierung sollte vor jedem Deployment stattfinden. Tools wie der W3C Validator oder Browser-DevTools helfen dabei, Fehler wie fehlende Tags, fehlerhafte Verschachtelung oder ungültige Attribute aufzudecken.
In diesem Referenztext lernen Sie:

  • wie HTML-Validierung funktioniert,
  • welche Tools zur Verfügung stehen,
  • typische Fehlerquellen und deren Behebung,
  • Best Practices für robustes HTML.
    Ein gut getesteter HTML-Code spart Zeit beim Debugging, verbessert die Suchmaschinenfreundlichkeit und erhöht die Zugänglichkeit Ihrer Website.

Grundlegendes Beispiel

html
HTML Code
<!DOCTYPE html>

<html lang="de">
<head>
<meta charset="UTF-8">
<title>Testseite</title>
</head>
<body>
<h1>Willkommen</h1>
<p>Dies ist ein valider HTML-Abschnitt.</p>
</body>
</html>

Dieses einfache Beispiel zeigt eine korrekt strukturierte HTML-Seite. Der DOCTYPE deklariert HTML5. Das -Element besitzt das Attribut lang="de", was für Suchmaschinen und Screenreader relevant ist. Innerhalb des befinden sich die - und -Tags, die wichtige Metadaten bereitstellen.<br /> Im <body>-Bereich sehen wir eine Überschrift <h1> und einen Absatz <p>. Alle Elemente sind ordnungsgemäß verschachtelt und geschlossen. Dies ist besonders wichtig, da nicht geschlossene oder falsch verschachtelte Elemente unerwartete Renderings verursachen können.<br /> Viele Anfänger vergessen beispielsweise das Schließen von <p> oder setzen Blockelemente wie <div> innerhalb von Inline-Tags wie <span>, was ungültig ist. Dieses Beispiel demonstriert die absolute Minimalstruktur, mit der man HTML-Dateien validieren kann.<br /> Validierung hilft sicherzustellen, dass die Seite auf allen Browsern einheitlich aussieht und durch Suchmaschinen korrekt indexiert wird. Auch für Barrierefreiheit (Accessibility) ist valides HTML die Voraussetzung.</p> </div> <!-- Enhanced Code Block --> <div class="code-editor-container"> <div class="code-editor-header"> <h3 class="code-title">Praktisches Beispiel</h3> <span class="code-language-badge html">html</span> </div> <div class="code-display"> <div class="code-display-header"> <span>HTML Code</span> <div class="flex flex-col sm:flex-row gap-2"> <button type="button" class="copy-button" onclick="copyStaticCode('code-957', this)"> 📋 Kopieren </button> <button type="button" class="copy-button bg-green-600 hover:bg-green-700 text-white" onclick="openCodeRunner('html', 'Praktisches Beispiel', 957)"> 🚀 Live ausprobieren </button> </div> </div> <div class="code-block"> <pre><code id="code-957" class="language-html"><!DOCTYPE html> <html lang="de"> <head> <meta charset="UTF-8"> <title>Blogartikel</title> </head> <body> <article> <header><h1>HTML Validierung in der Praxis</h1></header> <section> <p>Gültiges HTML verbessert SEO und Zugänglichkeit.</p> </section> </article> </body> </html></code></pre> </div> </div> </div> <!-- Enhanced Text Block with Smart Links --> <div class="prose prose-lg max-w-none"> <p>Dieses Beispiel zeigt, wie semantisches HTML für einen Blogartikel genutzt wird. Die Verwendung von <article>, <header> und <section> unterstützt Screenreader und verbessert die strukturierte Darstellung für Suchmaschinen. Das ist besonders bei redaktionellen Inhalten wichtig, wie bei Nachrichten- oder Blog-Websites.<br /> Das <article>-Element dient als Container für einen eigenständigen Inhalt, während <header> den Titel enthält. Die <section> gruppiert verwandte Inhalte innerhalb des Artikels.<br /> Alle Elemente sind syntaktisch korrekt verschachtelt, mit Attributen versehen und validierbar. Diese Struktur bietet sich auch für Portfolio-Seiten oder Produktbeschreibungen in Online-Shops an.<br /> Dank Validierung stellen Sie sicher, dass der HTML-Code auf Mobilgeräten, Screenreadern und verschiedenen Browsern konsistent funktioniert. HTML-Test ist damit keine bloße Formalität, sondern Grundlage einer hochwertigen Webentwicklung.</p> </div> <!-- Enhanced Text Block with Smart Links --> <div class="prose prose-lg max-w-none"> <p>Best Practices:</p> <ol> <li>Verwenden Sie semantisches HTML (z.B. <main>, <section>, <article>) für klare Struktur.</li> <li>Schließen Sie alle HTML-Tags korrekt, auch wenn der Browser dies toleriert.</li> <li>Nutzen Sie Tools wie den W3C Validator frühzeitig im Entwicklungsprozess.</li> <li> <p>Achten Sie auf korrekte Attributnutzung, z.B. alt bei <img>.<br /> Typische Fehler:</p> </li> <li> <p>Fehlende oder doppelte <title>-Tags.</p> </li> <li>Ungültige Attribute (z.B. align, border im HTML5).</li> <li>Falsche Verschachtelung (z.B. Blockelemente in Inline-Elementen).</li> <li>Ignorieren von Warnungen im Validator.<br /> Debugging-Tipps:</li> </ol> <ul> <li>Verwenden Sie Browser-DevTools zur Strukturprüfung.</li> <li>Validieren Sie HTML nach jeder größeren Änderung.</li> <li>Entwickeln Sie mit HTML-Linter-Plugins im Editor.</li> </ul> </div> <!-- Enhanced Reference Table --> <div class="table-responsive"> <div class="bg-white p-6"> <h3 class="text-xl font-semibold mb-4 text-gray-800">📊 Schnelle Referenz</h3> <div class="overflow-x-auto"> <table class="w-full table-auto border-collapse"> <thead> <tr class="bg-gradient-to-r from-gray-50 to-gray-100"> <th class="border border-gray-300 px-4 py-3 text-left font-semibold text-gray-700">Property/Method</th> <th class="border border-gray-300 px-4 py-3 text-left font-semibold text-gray-700">Description</th> <th class="border border-gray-300 px-4 py-3 text-left font-semibold text-gray-700">Example</th> </tr> </thead> <tbody> <tr class="hover:bg-gray-50 transition-colors"> <td class="border border-gray-300 px-4 py-3 text-gray-600"><!DOCTYPE></td> <td class="border border-gray-300 px-4 py-3 text-gray-600">Dokumenttyp-Deklaration</td> <td class="border border-gray-300 px-4 py-3 text-gray-600"><!DOCTYPE html></td> </tr> <tr class="hover:bg-gray-50 transition-colors"> <td class="border border-gray-300 px-4 py-3 text-gray-600"><meta charset></td> <td class="border border-gray-300 px-4 py-3 text-gray-600">Zeichencodierung für Umlaute & Sonderzeichen</td> <td class="border border-gray-300 px-4 py-3 text-gray-600"><meta charset="UTF-8"></td> </tr> <tr class="hover:bg-gray-50 transition-colors"> <td class="border border-gray-300 px-4 py-3 text-gray-600">lang</td> <td class="border border-gray-300 px-4 py-3 text-gray-600">Sprache der Seite für Screenreader & SEO</td> <td class="border border-gray-300 px-4 py-3 text-gray-600"><html lang="de"></td> </tr> <tr class="hover:bg-gray-50 transition-colors"> <td class="border border-gray-300 px-4 py-3 text-gray-600"><header>/<section>/<article></td> <td class="border border-gray-300 px-4 py-3 text-gray-600">Semantische Strukturierung</td> <td class="border border-gray-300 px-4 py-3 text-gray-600"><article><header>...</header></article></td> </tr> <tr class="hover:bg-gray-50 transition-colors"> <td class="border border-gray-300 px-4 py-3 text-gray-600">alt</td> <td class="border border-gray-300 px-4 py-3 text-gray-600">Alternativtext für Bilder zur Barrierefreiheit</td> <td class="border border-gray-300 px-4 py-3 text-gray-600"><img src="bild.jpg" alt="Beschreibung"></td> </tr> <tr class="hover:bg-gray-50 transition-colors"> <td class="border border-gray-300 px-4 py-3 text-gray-600">W3C Validator</td> <td class="border border-gray-300 px-4 py-3 text-gray-600">Webtool zur HTML-Validierung</td> <td class="border border-gray-300 px-4 py-3 text-gray-600">https://validator.w3.org</td> </tr> </tbody> </table> </div> </div> </div> <!-- Enhanced Text Block with Smart Links --> <div class="prose prose-lg max-w-none"> <p>Zusammenfassung und Ausblick:<br /> Die Validierung von HTML ist kein optionaler Luxus, sondern eine Grundanforderung für qualitätsvolle Webentwicklung. Ob für Blogs, Shops oder Social-Media-Plattformen: korrekt strukturierter HTML-Code ist essenziell für Darstellung, Usability und SEO.<br /> Wer HTML testet und validiert:</p> <ul> <li>reduziert Fehlerrisiken,</li> <li>verbessert die Performance,</li> <li>schafft bessere Nutzererlebnisse.<br /> Der nächste Schritt ist das Zusammenspiel mit CSS (Design) und JavaScript (Interaktion). Ein valider Code bildet hier die stabile Grundlage. Themen wie "ARIA Roles für Barrierefreiheit", "Responsive HTML-Strukturen" oder "Linting-Tools" bieten sich für eine vertiefende Beschäftigung an.</li> </ul> </div> </div> <!-- Keywords Section --> <!-- Content Reporting Widget --> <!-- Content Reporting Widget --> <div class="content-report-container" id="report-container" data-content-type-id="10" data-object-id="42"> <div class="report-dropdown" id="report-dropdown"> <button type="button" class="report-button" id="report-button"> <span>👋</span> <span>Report Issue</span> </button> <div class="dropdown-menu" id="dropdown-menu"> <!-- Categories will be loaded dynamically by JavaScript --> </div> </div> </div> <!-- Load Required CSS and JS --> <link rel="stylesheet" href="/static/css/content-reporting.3f7dc51ec48b.css"> <script src="/static/js/content-reporting.37a7bd46d1db.js" defer></script> <!-- Enhanced Quiz Section --> <div class="mb-8"> <h2 class="text-2xl md:text-3xl font-bold mb-6 bg-clip-text"> 🧠 Testen Sie Ihr Wissen </h2> <!-- Modern Quiz Container - Direct Display --> <div id="quiz-container" class="quiz-modern-container"> <!-- Hidden CSRF Token --> <input type="hidden" name="csrfmiddlewaretoken" value="yAUJsDGDvtNwY3kgP3UZxNZaxH1GIJvxHZFmSy69ce79sb72CHKwJ30YIAWOcmkh"> <!-- Quiz Header with Progress --> <div class="quiz-header"> <div class="quiz-progress-wrapper"> <div class="quiz-progress-track"> <div id="quiz-progress-fill" class="quiz-progress-fill"></div> </div> <div class="quiz-progress-info"> <span id="progress-text" class="progress-current">Bereit zum Start</span> <span id="progress-stats" class="progress-stats"></span> </div> </div> <!-- Timer (if applicable) --> <div id="quiz-timer-wrapper" class="quiz-timer-wrapper" style="display: none;"> <div class="timer-icon">⏱️</div> <span id="timer-display" class="timer-display">10:00</span> </div> </div> <!-- Quiz Content Area --> <div class="quiz-content-area"> <!-- Quiz Introduction - Now Always Visible --> <div id="quiz-intro" class="quiz-intro-section"> <div class="quiz-intro-icon"> <div class="icon-circle"> <svg class="brain-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/> </svg> </div> </div> <h3 class="quiz-intro-title">اختبر معرفتك</h3> <p class="quiz-intro-subtitle">اختبر فهمك لهذا الموضوع بأسئلة عملية.</p> <!-- Quiz Stats Grid --> <div id="quiz-stats-grid" class="quiz-stats-grid"> <div class="quiz-stat-card"> <span class="stat-icon">❓</span> <div class="stat-value">3</div> <div class="stat-label">Fragen</div> </div> <div class="quiz-stat-card"> <span class="stat-icon">🎯</span> <div class="stat-value">70%</div> <div class="stat-label">Zum Bestehen</div> </div> <div class="quiz-stat-card"> <span class="stat-icon">♾️</span> <div class="stat-value">∞</div> <div class="stat-label">Zeit</div> </div> <div class="quiz-stat-card"> <span class="stat-icon">🔄</span> <div class="stat-value">∞</div> <div class="stat-label">Versuche</div> </div> </div> <!-- Quiz Instructions --> <div class="quiz-instructions"> <h4 class="instructions-title">📝 Anweisungen</h4> <ul class="instructions-list"> <li>Lesen Sie jede Frage sorgfältig</li> <li>Wählen Sie die beste Antwort für jede Frage</li> <li>Sie können das Quiz so oft wiederholen, wie Sie möchten</li> <li>Ihr Fortschritt wird oben angezeigt</li> </ul> </div> <button id="start-quiz-btn" class="quiz-start-button" onclick="startQuiz(42)"> <span class="button-content"> <svg class="button-icon" viewBox="0 0 24 24" fill="none" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M14.828 14.828a4 4 0 01-5.656 0M9 10h1m4 0h1m-6 4h8"/> </svg> Quiz starten </span> <div class="button-ripple"></div> </button> </div> <!-- Quiz Questions Section --> <div id="quiz-questions" class="quiz-questions-section" style="display: none;"> <!-- Question Header --> <div class="question-header"> <div class="question-meta"> <span id="question-number" class="question-counter">Frage 1</span> <div class="question-type-badge" id="question-type"> <span>📝</span> </div> </div> </div> <!-- Question Content --> <div id="current-question" class="question-content"> <!-- Question will be loaded here --> </div> <!-- Question Actions --> <div class="question-actions"> <button id="submit-answer" class="submit-answer-btn" onclick="submitAnswer()" disabled> <span class="btn-text">Antwort absenden</span> <div class="btn-loader" style="display: none;"> <div class="loader-spinner"></div> </div> </button> </div> </div> <!-- Quiz Results Section --> <div id="quiz-results" class="quiz-results-section" style="display: none;"> <!-- Results will be populated here --> </div> <!-- Loading State --> <div id="quiz-loading" class="quiz-loading-section" style="display: none;"> <div class="loading-animation"> <div class="loading-spinner"></div> <div class="loading-dots"> <span></span> <span></span> <span></span> </div> </div> <p class="loading-text">Ihr Quiz wird geladen...</p> </div> </div> <!-- Error Display --> <div id="quiz-error" class="quiz-error-display" style="display: none;"> <div class="error-content"> <div class="error-icon">⚠️</div> <div class="error-message"></div> <button class="error-close" onclick="hideError()">✕</button> </div> </div> </div> <script> let currentQuiz = null; let currentQuestionIndex = 0; let selectedAnswer = null; let quizTimer = null; let timeRemaining = null; let currentQuestionData = null; let quizSessionData = null; // Store quiz session data for answer sheet function getCsrfToken() { let token = null; const quizContainer = document.getElementById('quiz-container'); if (quizContainer) { const tokenInput = quizContainer.querySelector('input[name="csrfmiddlewaretoken"]'); if (tokenInput) { token = tokenInput.value; } } if (!token) { const tokenInput = document.querySelector('input[name="csrfmiddlewaretoken"]'); if (tokenInput) { token = tokenInput.value; } } if (!token) { const cookieMatch = document.cookie.match(/csrftoken=([^;]+)/); if (cookieMatch) { token = cookieMatch[1]; } } return token; } function startQuiz(topicId) { console.log('Starting quiz for topic:', topicId); // Reset quiz session data quizSessionData = { questions: [], answers: {}, correctAnswers: {}, explanations: {}, startTime: new Date().toISOString() }; // Show loading showSection('quiz-loading'); updateProgress(0, 'Quiz wird initialisiert...', ''); const csrfToken = getCsrfToken(); if (!csrfToken) { console.error('CSRF token not found'); showError('Security token not found. Please refresh the page.'); showSection('quiz-intro'); return; } const formData = new FormData(); formData.append('csrfmiddlewaretoken', csrfToken); const url = `/de/quiz/${topicId}/start/`; fetch(url, { method: 'POST', body: formData, headers: { 'X-Requested-With': 'XMLHttpRequest' } }) .then(response => { if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } return response.json(); }) .then(data => { if (data.success) { currentQuiz = data.quiz; currentQuestionIndex = 0; // Setup timer if quiz has time limit if (currentQuiz.time_limit) { setupTimer(currentQuiz.time_limit); } // Show quiz questions section showSection('quiz-questions'); // Load first question loadQuestion(data.current_question, data.question_number, data.total_questions); } else { console.error('Quiz start failed:', data.error); showError(data.error || 'Failed to start quiz'); showSection('quiz-intro'); } }) .catch(error => { console.error('Fetch error:', error); showError('Quiz konnte nicht gestartet werden. Bitte versuchen Sie es erneut.'); showSection('quiz-intro'); }); } function loadQuestion(question, questionNumber, totalQuestions) { console.log('Loading question:', question); // Store current question data currentQuestionData = question; // Store question in session data quizSessionData.questions[questionNumber - 1] = question; // Update progress const progressPercent = (questionNumber / totalQuestions) * 100; updateProgress(progressPercent, `Frage ${questionNumber}`, `${questionNumber} von ${totalQuestions}`); // Update question number const questionNumberEl = document.getElementById('question-number'); if (questionNumberEl) { questionNumberEl.textContent = `Frage ${questionNumber}`; } // Update question type badge const questionTypeEl = document.getElementById('question-type'); if (questionTypeEl) { const typeIcons = { 'multiple_choice': '📝', 'true_false': '✅', 'fill_code': '💻' }; questionTypeEl.innerHTML = `<span>${typeIcons[question.type] || '📝'}</span>`; } // Reset selected answer selectedAnswer = null; const submitBtn = document.getElementById('submit-answer'); if (submitBtn) { submitBtn.disabled = true; submitBtn.querySelector('.btn-text').textContent = 'Antwort absenden'; } // Generate question HTML let questionHTML = ` <div class="question-text">${escapeHtml(question.text)}</div> `; // Add code template if exists if (question.code_template && question.code_template.trim()) { questionHTML += ` <div class="code-block"> <pre><code>${escapeHtml(question.code_template)}</code></pre> </div> `; } // Add options questionHTML += '<div class="options-container">'; if (question.options && question.options.length > 0) { question.options.forEach((option, index) => { questionHTML += ` <div class="option-item" onclick="selectOption(${option.id}, this)"> <input type="radio" name="quiz-option" value="${option.id}" style="display: none;"> <div class="option-content"> <div class="option-indicator"></div> <div class="option-text">${escapeHtml(option.text)}</div> </div> </div> `; }); } else { questionHTML += '<p class="error-message">No options available for this question.</p>'; } questionHTML += '</div>'; // Insert question content with animation const questionContainer = document.getElementById('current-question'); if (questionContainer) { questionContainer.style.opacity = '0'; questionContainer.innerHTML = questionHTML; // Animate in setTimeout(() => { questionContainer.style.transition = 'opacity 0.3s ease'; questionContainer.style.opacity = '1'; }, 100); } } function selectOption(optionId, element) { console.log('Option selected:', optionId); selectedAnswer = optionId; // Update visual feedback document.querySelectorAll('.option-item').forEach(item => { item.classList.remove('selected'); }); element.classList.add('selected'); // Enable submit button const submitBtn = document.getElementById('submit-answer'); if (submitBtn) { submitBtn.disabled = false; } } function submitAnswer() { if (!selectedAnswer || !currentQuestionData) { console.log('No answer selected or no question data'); return; } console.log('Submitting answer:', selectedAnswer, 'for question:', currentQuestionData.id); // Store user answer in session data quizSessionData.answers[currentQuestionData.id] = { selectedOptionId: selectedAnswer, selectedOptionText: getSelectedOptionText(selectedAnswer) }; const submitBtn = document.getElementById('submit-answer'); if (!submitBtn) return; // Show loading state submitBtn.disabled = true; submitBtn.querySelector('.btn-text').style.opacity = '0'; submitBtn.querySelector('.btn-loader').style.display = 'block'; const csrfToken = getCsrfToken(); if (!csrfToken) { console.error('CSRF token not found for submit'); showError('Security token not found. Please refresh the page.'); resetSubmitButton(submitBtn); return; } const formData = new FormData(); formData.append('question_id', currentQuestionData.id); formData.append('selected_option', selectedAnswer); formData.append('csrfmiddlewaretoken', csrfToken); const url = `/de/quiz/${currentQuiz.id}/submit/`; fetch(url, { method: 'POST', body: formData, headers: { 'X-Requested-With': 'XMLHttpRequest' } }) .then(response => { if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } return response.json(); }) .then(data => { if (data.success) { if (data.completed) { // Quiz completed - load results loadQuizResults(data.redirect_url); } else { // Load next question setTimeout(() => { loadQuestion(data.current_question, data.question_number, data.total_questions); resetSubmitButton(submitBtn); }, 500); } } else { console.error('Submit failed:', data.error); showError(data.error || 'Failed to submit answer'); resetSubmitButton(submitBtn); } }) .catch(error => { console.error('Submit fetch error:', error); showError('Antwort konnte nicht übermittelt werden. Bitte versuchen Sie es erneut.'); resetSubmitButton(submitBtn); }); } function getSelectedOptionText(optionId) { if (!currentQuestionData || !currentQuestionData.options) return ''; const option = currentQuestionData.options.find(opt => opt.id == optionId); return option ? option.text : ''; } function loadQuizResults(resultUrl) { console.log('Loading results from:', resultUrl); // Show loading while fetching results showSection('quiz-loading'); updateProgress(100, 'Ergebnisse werden berechnet...', 'Bitte warten'); fetch(resultUrl, { headers: { 'HX-Request': 'true' } }) .then(response => { if (!response.ok) { throw new Error(`HTTP error! status: ${response.status}`); } return response.text(); }) .then(html => { // Parse the results and extract detailed information const tempDiv = document.createElement('div'); tempDiv.innerHTML = html; // Extract score data from the response const scoreElement = tempDiv.querySelector('.score-percentage') || tempDiv.querySelector('[data-score]'); let scoreValue = 0; if (scoreElement) { const scoreText = scoreElement.textContent || scoreElement.getAttribute('data-score') || '0'; scoreValue = parseInt(scoreText.replace('%', '')) || 0; } const correctElement = tempDiv.querySelector('.correct-answers') || tempDiv.querySelector('[data-correct]'); let correctAnswers = 0; if (correctElement) { const correctText = correctElement.textContent || correctElement.getAttribute('data-correct') || '0'; correctAnswers = parseInt(correctText) || 0; } const totalElement = tempDiv.querySelector('.total-questions') || tempDiv.querySelector('[data-total]'); let totalQuestions = currentQuiz.total_questions || 0; if (totalElement) { const totalText = totalElement.textContent || totalElement.getAttribute('data-total') || '0'; totalQuestions = parseInt(totalText) || totalQuestions; } // Extract detailed question results extractQuestionResults(tempDiv); // Save quiz result for authenticated users if (window.siteConfig && window.siteConfig.isAuthenticated && window.saveQuizResult) { const quizData = { quiz_id: currentQuiz.id, score: correctAnswers, total_questions: totalQuestions, correct_answers: correctAnswers, time_spent: calculateQuizTime(), answers: quizSessionData, passing_score: currentQuiz.passing_score || 70 }; window.saveQuizResult(quizData).catch(error => { console.error('Failed to save quiz result:', error); }); } displayResults(scoreValue, correctAnswers, totalQuestions); // Stop timer if running if (quizTimer) { clearInterval(quizTimer); hideTimer(); } }) .catch(error => { console.error('Results fetch error:', error); showError('Ergebnisse konnten nicht geladen werden. Bitte aktualisieren Sie die Seite.'); showSection('quiz-questions'); }); } function calculateQuizTime() { // Calculate time spent from quiz session start if (quizSessionData && quizSessionData.startTime) { const startTime = new Date(quizSessionData.startTime); const endTime = new Date(); return Math.floor((endTime - startTime) / 1000); // Return seconds } return 0; } function extractQuestionResults(resultContainer) { // Extract detailed results from the Django-generated HTML const questionContainers = resultContainer.querySelectorAll('.border-b, .border'); questionContainers.forEach((container, index) => { try { // Extract question text const questionTextEl = container.querySelector('p.text-gray-700, .text-gray-700'); const questionText = questionTextEl ? questionTextEl.textContent.trim() : `Question ${index + 1}`; // Extract correct/incorrect status const correctSpan = container.querySelector('.bg-green-100'); const incorrectSpan = container.querySelector('.bg-red-100'); const isCorrect = correctSpan !== null; // Extract user's answer let userAnswer = ''; const userAnswerSpans = container.querySelectorAll('.text-red-600, .text-green-600'); for (let span of userAnswerSpans) { const text = span.textContent; if (text.includes('Your answer:')) { userAnswer = text.replace('Your answer:', '').trim(); break; } } // Extract correct answer let correctAnswer = ''; const greenSpans = container.querySelectorAll('.text-green-600'); for (let span of greenSpans) { const text = span.textContent.trim(); const parentText = span.parentElement ? span.parentElement.textContent : ''; // Check if this span contains "Correct answer:" in its parent context if (parentText.includes('Correct answer:') && !text.includes('Your answer:')) { // Extract only the answer part after "Correct answer:" const parts = parentText.split('Correct answer:'); if (parts.length > 1) { correctAnswer = parts[1].split('Explanation:')[0].trim(); break; } } } // Fallback: if still empty, use user answer for correct questions if (!correctAnswer && isCorrect) { correctAnswer = userAnswer; } // Extract explanation let explanation = ''; const explanationEl = container.querySelector('.bg-blue-50 p'); if (explanationEl) { explanation = explanationEl.textContent.replace('Explanation:', '').trim(); } // Store in session data const questionId = quizSessionData.questions[index] ? quizSessionData.questions[index].id : index + 1; quizSessionData.correctAnswers[questionId] = { isCorrect: isCorrect, correctAnswer: correctAnswer, explanation: explanation, questionText: questionText }; } catch (error) { console.error('Error extracting question result:', error); } }); } function displayResults(scoreValue, correctAnswers, totalQuestions) { const passed = scoreValue >= (currentQuiz.passing_score || 70); const resultsSection = document.getElementById('quiz-results'); if (!resultsSection) return; resultsSection.innerHTML = ` <div class="result-header"> <div class="result-status-icon ${passed ? 'passed' : 'failed'}"> ${passed ? '🎉' : '📚'} </div> <h3 class="result-title"> ${passed ? 'Herzlichen Glückwunsch!' : 'Weiter lernen!'} </h3> <p class="result-subtitle"> ${passed ? 'Sie haben das Quiz bestanden!' : 'Sie können es besser. Versuchen Sie es erneut!'} </p> </div> <div class="score-display"> <div class="score-percentage ${passed ? 'passed' : 'failed'}">${scoreValue}%</div> <div class="score-details"> ${correctAnswers} von ${totalQuestions} richtig </div> <div class="score-bar"> <div class="score-fill" style="width: 0%"></div> </div> <div style="margin-top: 1rem; font-size: 0.875rem; opacity: 0.8;"> Bestehensgrenze: ${currentQuiz.passing_score || 70}% </div> </div> <div class="result-actions"> <button class="result-btn primary" onclick="retakeQuiz()"> <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15"/> </svg> Quiz wiederholen </button> <button class="result-btn secondary" onclick="toggleAnswerSheet()" id="view-answers-btn"> <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/> </svg> Antworten anzeigen </button> <button class="result-btn secondary" onclick="closeQuiz()"> <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/> </svg> Schließen </button> </div> <!-- Answer Sheet Section --> <div id="answer-sheet" class="answer-sheet-section" style="display: none;"> <div class="answer-sheet-header"> <h4>📋 Antwortbogen</h4> <button class="close-answer-sheet" onclick="toggleAnswerSheet()">✕</button> </div> <div id="answer-sheet-content" class="answer-sheet-content"> Antworten werden geladen... </div> </div> `; // Show results section showSection('quiz-results'); updateProgress(100, 'Quiz abgeschlossen!', `${scoreValue}% Punktzahl`); // Animate score bar setTimeout(() => { const scoreFill = resultsSection.querySelector('.score-fill'); if (scoreFill) { scoreFill.style.width = `${scoreValue}%`; } }, 500); } // Answer sheet functions function toggleAnswerSheet() { const answerSheet = document.getElementById('answer-sheet'); const btn = document.getElementById('view-answers-btn'); if (answerSheet.style.display === 'none' || answerSheet.style.display === '') { answerSheet.style.display = 'block'; loadAnswerSheet(); btn.innerHTML = ` <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"/> </svg> Antworten verbergen `; } else { answerSheet.style.display = 'none'; btn.innerHTML = ` <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z"/> </svg> Antworten anzeigen `; } } function loadAnswerSheet() { const answerSheetContent = document.getElementById('answer-sheet-content'); if (!answerSheetContent || !quizSessionData) return; let correctCount = 0; let incorrectCount = 0; let answerSheetHTML = ` <div class="answer-summary"> <div class="summary-stat total"> <div class="number">${currentQuiz.total_questions || 0}</div> <div class="label">Gesamte Fragen</div> </div> <div class="summary-stat correct"> <div class="number" id="correct-count">0</div> <div class="label">Richtig</div> </div> <div class="summary-stat incorrect"> <div class="number" id="incorrect-count">0</div> <div class="label">Falsch</div> </div> </div> <div class="answer-grid"> `; // Generate answer sheet for each question quizSessionData.questions.forEach((question, index) => { if (!question) return; const questionId = question.id; const userAnswer = quizSessionData.answers[questionId]; const correctInfo = quizSessionData.correctAnswers[questionId]; if (!userAnswer || !correctInfo) return; const isCorrect = correctInfo.isCorrect; if (isCorrect) { correctCount++; } else { incorrectCount++; } answerSheetHTML += ` <div class="answer-item ${isCorrect ? 'correct' : 'incorrect'}"> <div class="question-number">Q${index + 1}</div> <div class="question-details"> <div class="question-text">${escapeHtml(correctInfo.questionText || question.text)}</div> <div class="answer-comparison"> <div class="user-answer"> <span class="label">Your Answer:</span> <span class="value ${isCorrect ? 'correct' : 'incorrect'}">${escapeHtml(userAnswer.selectedOptionText)}</span> </div> ${!isCorrect ? ` <div class="correct-answer"> <span class="label">Correct Answer:</span> <span class="value correct">${escapeHtml(correctInfo.correctAnswer)}</span> </div> ` : ''} ${correctInfo.explanation ? ` <div class="explanation"> <span class="label">Erklärung:</span> <span class="explanation-text">${escapeHtml(correctInfo.explanation)}</span> </div> ` : ''} </div> </div> <div class="result-icon"> ${isCorrect ? '✅' : '❌'} </div> </div> `; }); answerSheetHTML += '</div>'; answerSheetContent.innerHTML = answerSheetHTML; // Update summary counts document.getElementById('correct-count').textContent = correctCount; document.getElementById('incorrect-count').textContent = incorrectCount; } function retakeQuiz() { // Reset quiz state currentQuiz = null; currentQuestionIndex = 0; selectedAnswer = null; currentQuestionData = null; quizSessionData = null; if (quizTimer) { clearInterval(quizTimer); hideTimer(); } // Show intro section showSection('quiz-intro'); updateProgress(0, 'Bereit zum Start', ''); } function closeQuiz() { // Just reset and hide for now since we're directly displaying retakeQuiz(); } function showSection(sectionId) { const sections = ['quiz-intro', 'quiz-questions', 'quiz-results', 'quiz-loading']; sections.forEach(id => { const element = document.getElementById(id); if (element) { element.style.display = id === sectionId ? 'block' : 'none'; } }); } function updateProgress(percentage, currentText, statsText) { const progressFill = document.getElementById('quiz-progress-fill'); const progressText = document.getElementById('progress-text'); const progressStats = document.getElementById('progress-stats'); if (progressFill) { progressFill.style.width = `${percentage}%`; } if (progressText) { progressText.textContent = currentText; } if (progressStats) { progressStats.textContent = statsText; } } function setupTimer(timeLimit) { const timerWrapper = document.getElementById('quiz-timer-wrapper'); const timerDisplay = document.getElementById('timer-display'); if (!timerWrapper || !timerDisplay) return; timeRemaining = timeLimit * 60; // Convert to seconds timerWrapper.style.display = 'flex'; quizTimer = setInterval(() => { const minutes = Math.floor(timeRemaining / 60); const seconds = timeRemaining % 60; timerDisplay.textContent = `${minutes}:${seconds.toString().padStart(2, '0')}`; // Warning when time is running out if (timeRemaining <= 60) { timerWrapper.style.color = '#ef4444'; timerWrapper.style.animation = 'pulse 1s infinite'; } if (timeRemaining <= 0) { clearInterval(quizTimer); if (selectedAnswer) { submitAnswer(); } else { showError('Zeit ist um! Das Quiz wird automatisch übermittelt.'); } } timeRemaining--; }, 1000); } function hideTimer() { const timerWrapper = document.getElementById('quiz-timer-wrapper'); if (timerWrapper) { timerWrapper.style.display = 'none'; } } function resetSubmitButton(button) { if (!button) return; button.disabled = false; button.querySelector('.btn-text').style.opacity = '1'; button.querySelector('.btn-loader').style.display = 'none'; } function showError(message) { console.log('Showing error:', message); const errorDisplay = document.getElementById('quiz-error'); if (!errorDisplay) return; const errorMessage = errorDisplay.querySelector('.error-message'); if (errorMessage) { errorMessage.textContent = message; } errorDisplay.style.display = 'block'; // Auto-hide after 5 seconds setTimeout(() => { hideError(); }, 5000); } function hideError() { const errorDisplay = document.getElementById('quiz-error'); if (errorDisplay) { errorDisplay.style.display = 'none'; } } function escapeHtml(unsafe) { if (typeof unsafe !== 'string') { return unsafe; } return unsafe .replace(/&/g, "&") .replace(/</g, "<") .replace(/>/g, ">") .replace(/"/g, """) .replace(/'/g, "'"); } // Initialize quiz when page loads document.addEventListener('DOMContentLoaded', function() { // Quiz is now directly visible, no need for showQuiz() function console.log('Quiz components loaded'); }); // HTMX after-swap event document.body.addEventListener('htmx:afterSwap', function() { // Reinitialize quiz if it exists on the swapped content console.log('Quiz components reloaded after HTMX swap'); }); </script> </div> <!-- Enhanced Navigation --> <div class="topic-navigation"> <div class="nav-links"> <div></div> <div class="nav-center"> <div class="text-sm font-semibold">Thema 1 von 1</div> <div class="text-xs mt-1 opacity-75">Html Tutorial</div> </div> <div></div> </div> </div> </div> <script> const sessionKey = `code_session_${codeExampleId}`; // Smart Link Click Tracking document.addEventListener('click', function(event) { const smartLink = event.target.closest('.smart-link'); if (smartLink) { const keywordId = smartLink.getAttribute('data-keyword-id'); if (keywordId) { // Track click asynchronously fetch('/de/api/smart-link-click/', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRFToken': 'yAUJsDGDvtNwY3kgP3UZxNZaxH1GIJvxHZFmSy69ce79sb72CHKwJ30YIAWOcmkh' }, body: JSON.stringify({ keyword_id: keywordId, source_content_type: 'topic', source_content_id: 42, user_agent: navigator.userAgent }) }).catch(error => { console.debug('Smart link tracking failed:', error); }); } } }); function openCodeRunner(language, title, codeExampleId) { const codeElement = document.getElementById('code-' + codeExampleId); const code = codeElement.textContent; const formData = new FormData(); formData.append('language', language); formData.append('title', title); formData.append('code', code); formData.append('source_example_id', codeExampleId); formData.append('csrfmiddlewaretoken', 'yAUJsDGDvtNwY3kgP3UZxNZaxH1GIJvxHZFmSy69ce79sb72CHKwJ30YIAWOcmkh'); fetch('/de/create-code-session/', { method: 'POST', body: formData, headers: { 'X-Requested-With': 'XMLHttpRequest' } }) .then(response => response.json()) .then(data => { if (data.success) { window.open(data.url, '_blank'); } else { console.error('Error creating session:', data.error); window.open('/de/try-it/' + language + '/', '_blank'); } }) .catch(error => { console.error('Error:', error); window.open('/de/try-it/' + language + '/', '_blank'); }); } document.body.addEventListener('htmx:afterSwap', function() { window.scrollTo({ top: 0, behavior: 'smooth' }); if (typeof Prism !== 'undefined') { Prism.highlightAll(); } if (typeof populateQuizStats === 'function') { populateQuizStats(); } if (window.mobileMenu && window.mobileMenu.isMenuOpen && window.mobileMenu.isMenuOpen()) { window.mobileMenu.forceClose(); } initializeEnhancedFeatures(); }); function initializeEnhancedFeatures() { // Initialize topic tracking for authenticated users if (window.siteConfig && window.siteConfig.isAuthenticated) { initializeTopicTracking(); } document.querySelectorAll('.nav-link, .custom-sidebar-item').forEach(link => { link.addEventListener('click', function() { if (this.hasAttribute('hx-get')) { this.classList.add('loading'); setTimeout(() => { this.classList.remove('loading'); }, 1000); } }); }); document.querySelectorAll('.code-block pre').forEach(pre => { const code = pre.querySelector('code'); if (code && code.textContent.split('\n').length > 3) { pre.classList.add('line-numbers'); } }); } function initializeTopicTracking() { // Track topic view for authenticated users const topicId = getTopicIdFromCurrentUrl(); const categorySlug = getCategorySlugFromCurrentUrl(); if (topicId && categorySlug) { // Track initial view trackTopicView({ topic_id: topicId, category_slug: categorySlug }); // Track scroll percentage let maxScrollPercentage = 0; let timeSpent = 0; let startTime = Date.now(); window.addEventListener('scroll', throttle(function() { const scrollPercentage = calculateScrollPercentage(); if (scrollPercentage > maxScrollPercentage) { maxScrollPercentage = scrollPercentage; } }, 1000)); // Track time spent setInterval(() => { if (!document.hidden) { timeSpent += 5; // Add 5 seconds } }, 5000); // Send final data on page unload window.addEventListener('beforeunload', function() { if (maxScrollPercentage > 0 || timeSpent > 0) { trackTopicView({ topic_id: topicId, category_slug: categorySlug, scroll_percentage: maxScrollPercentage, time_spent: timeSpent, completed: maxScrollPercentage >= 80 // Consider 80% as completed }); } }); } } function getTopicIdFromCurrentUrl() { const pathParts = window.location.pathname.split('/').filter(Boolean); const languages = ['en', 'fa', 'ar', 'zh', 'hi', 'fr', 'de', 'ru', 'tr', 'pt', 'es']; let startIndex = 0; if (languages.includes(pathParts[0])) { startIndex = 1; } if (pathParts.length >= startIndex + 2) { return pathParts[startIndex + 1]; // Return topic slug } return null; } function getCategorySlugFromCurrentUrl() { const pathParts = window.location.pathname.split('/').filter(Boolean); const languages = ['en', 'fa', 'ar', 'zh', 'hi', 'fr', 'de', 'ru', 'tr', 'pt', 'es']; let startIndex = 0; if (languages.includes(pathParts[0])) { startIndex = 1; } if (pathParts.length >= startIndex + 1) { return pathParts[startIndex]; // Return category slug } return null; } function trackTopicView(data) { if (!window.siteConfig || !window.siteConfig.isAuthenticated) { return Promise.resolve(); } return fetch('/account/ajax/track-topic-view/', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRFToken': window.siteConfig.csrfToken || getCsrfToken() }, body: JSON.stringify(data) }).catch(error => { console.debug('Topic view tracking failed:', error); }); } function calculateScrollPercentage() { const scrollTop = window.pageYOffset; const docHeight = document.documentElement.scrollHeight - window.innerHeight; return Math.min(100, Math.max(0, (scrollTop / docHeight) * 100)); } function throttle(func, limit) { let inThrottle; return function() { const args = arguments; const context = this; if (!inThrottle) { func.apply(context, args); inThrottle = true; setTimeout(() => inThrottle = false, limit); } }; } function getCsrfToken() { const tokenInput = document.querySelector('input[name="csrfmiddlewaretoken"]'); if (tokenInput) { return tokenInput.value; } const cookieMatch = document.cookie.match(/csrftoken=([^;]+)/); return cookieMatch ? cookieMatch[1] : null; } document.addEventListener('DOMContentLoaded', function() { initializeEnhancedFeatures(); if (typeof Prism !== 'undefined') { Prism.highlightAll(); } document.body.addEventListener('htmx:beforeRequest', function(event) { const target = event.target; if (target.classList.contains('nav-link') || target.classList.contains('custom-sidebar-item')) { target.style.opacity = '0.7'; target.style.pointerEvents = 'none'; } }); document.body.addEventListener('htmx:afterRequest', function(event) { const target = event.target; if (target.classList.contains('nav-link') || target.classList.contains('custom-sidebar-item')) { target.style.opacity = '1'; target.style.pointerEvents = 'auto'; } }); }); window.addEventListener('error', function(event) { console.error('JavaScript error:', event.error); if (window.innerWidth <= 768) { const errorDiv = document.createElement('div'); errorDiv.className = 'fixed top-4 left-4 right-4 bg-red-50 border border-red-200 text-red-700 px-4 py-3 rounded-lg z-50 shadow-lg'; errorDiv.innerHTML = ` <div class="flex items-center justify-between"> <div class="flex items-center"> <span class="text-red-500 mr-2">⚠️</span> <span><strong>Fehler:</strong> Etwas ist schief gelaufen. Bitte aktualisieren Sie die Seite.</span> </div> <button onclick="this.parentElement.parentElement.remove()" class="text-red-500 hover:text-red-700 ml-2">✕</button> </div> `; document.body.appendChild(errorDiv); setTimeout(() => { if (errorDiv.parentElement) { errorDiv.remove(); } }, 5000); } }); const style = document.createElement('style'); style.textContent = ` @keyframes ripple { to { transform: scale(4); opacity: 0; } } .copy-button { position: relative; overflow: hidden; } `; document.head.appendChild(style); </script> </main> </div> <!-- Coming Soon Course Modal --> <div id="coming-soon-modal" class="coming-soon-modal hidden"> <div class="coming-soon-backdrop"></div> <div class="coming-soon-content"> <!-- Modal Header --> <div class="coming-soon-header"> <div class="flex items-center space-x-3 "> <div class="coming-soon-icon"> <svg class="w-6 h-6" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 14l-7 7m0 0l-7-7m7 7V3"></path> </svg> </div> <h3 class="coming-soon-title"> 🚧 Kurs Kommt Bald </h3> </div> <button id="close-coming-soon-modal" class="coming-soon-close"> <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path> </svg> </button> </div> <!-- Modal Body --> <div class="coming-soon-body"> <div class="course-info-section"> <h4 id="course-name" class="course-name">Course Name</h4> <div class="course-status"> <span class="status-badge">In Entwicklung</span> </div> <p class="course-description"> Dieser umfassende Kurs wird derzeit mit den neuesten Industriestandards und bewährten Praktiken entwickelt. Unser Expertenteam erstellt hochwertige Inhalte, um Ihnen die beste Lernerfahrung zu bieten. </p> </div> <div class="estimated-release"> <div class="flex items-center space-x-2 "> <svg class="w-4 h-4 text-blue-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 8v4l3 3m6-3a9 9 0 11-18 0 9 9 0 0118 0z"></path> </svg> <span class="text-sm text-gray-600 dark:text-gray-400"> Geschätzte Veröffentlichung: 2-4 Wochen </span> </div> </div> <!-- Notify Me Section --> <div class="notify-section"> <h5 class="notify-title">Benachrichtigung Bei Verfügbarkeit</h5> <form id="notify-form" class="notify-form"> <div class="email-input-group"> <input type="email" id="notify-email" name="email" placeholder="Geben Sie Ihre E-Mail-Adresse ein" class="notify-email-input" required> <button type="submit" class="notify-submit-btn"> <span class="btn-text">Benachrichtigen Sie Mich</span> <svg class="btn-icon w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M12 19l9 2-9-18-9 18 9-2zm0 0v-8"></path> </svg> </button> </div> <p class="email-disclaimer"> Wir senden Ihnen eine einmalige Benachrichtigung, wenn dieser Kurs verfügbar wird. Kein Spam, versprochen! </p> </form> </div> <!-- Related Courses --> <div class="related-courses"> <h5 class="related-title">Jetzt Verfügbar</h5> <div class="related-links"> <a href="/de/html/" class="related-link"> <i class="fab fa-html5 text-orange-500"></i> <span>HTML Tutorial</span> </a> <a href="/de/css/" class="related-link"> <i class="fab fa-css3-alt text-blue-500"></i> <span>CSS Vollständiger Leitfaden</span> </a> <a href="/de/javascript/" class="related-link"> <i class="fab fa-js-square text-yellow-500"></i> <span>JavaScript Grundlagen</span> </a> </div> </div> </div> </div> </div> <!-- Coming Soon Modal --> <div id="coming-soon-modal" class="coming-soon-modal"> <div class="coming-soon-backdrop"></div> <div class="coming-soon-content"> <div class="coming-soon-header"> <div class="coming-soon-icon"> <i class="fas fa-clock"></i> </div> <h3 class="coming-soon-title">Coming Soon</h3> <button class="coming-soon-close" id="close-coming-soon"> <svg class="w-5 h-5" fill="none" stroke="currentColor" viewBox="0 0 24 24"> <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12"></path> </svg> </button> </div> <div class="coming-soon-body"> <div class="course-info-section"> <h4 class="course-name" id="modal-course-name">Course Name</h4> <div class="course-status"> <span class="status-badge"> <i class="fas fa-hammer mr-1"></i> In Entwicklung </span> </div> <p class="course-description" id="modal-course-description"> This course is currently under development. We're working hard to bring you high-quality content. </p> </div> <div class="estimated-release"> <div class="flex items-center space-x-2 mb-2"> <i class="fas fa-calendar-alt text-blue-600"></i> <span class="font-semibold text-blue-600">Estimated Release</span> </div> <p class="text-sm text-blue-700" id="modal-release-date">Q2 2025</p> </div> </div> </div> </div> <!-- Include Footer --> <footer class="bg-gray-900 text-white"> <div class=""> <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-12 grid grid-cols-2 md:grid-cols-6 gap-8"> <!-- Frontend Development --> <div> <h3 class="text-sm font-semibold text-gray-300 uppercase tracking-wide mb-4">Frontend</h3> <ul class="space-y-1"> <li><a href="/de/html/" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">HTML Tutorial</a></li> <li><a href="/de/css/" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">CSS Complete Guide</a></li> <li><a href="/de/javascript/" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">JavaScript Fundamentals</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="react">React Development</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="vue">Vue.js Framework</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="angular">Angular Framework</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="typescript">TypeScript Guide</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="bootstrap">Bootstrap Framework</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="tailwind">Tailwind CSS</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="sass">Sass & SCSS</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="jquery">jQuery Library</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="webcomponents">Web Components</a></li> </ul> </div> <!-- Backend Development --> <div> <h3 class="text-sm font-semibold text-gray-300 uppercase tracking-wide mb-4">Backend</h3> <ul class="space-y-1"> <li><a href="/de/python/" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">Python Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="django">Django Framework</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="flask">Flask Framework</a></li> <li><a href="/de/nodejs/" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">Node.js Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="express">Express.js Framework</a></li> <li><a href="/de/php/" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">PHP Programming</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="laravel">Laravel Framework</a></li> <li><a href="/de/java/" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">Java Programming</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="spring">Spring Boot</a></li> <li><a href="/de/c-sharp/" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">C# Programming</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="dotnet">ASP.NET Core</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="ruby">Ruby on Rails</a></li> </ul> </div> <!-- Database Programming --> <div> <h3 class="text-sm font-semibold text-gray-300 uppercase tracking-wide mb-4">Datenbank</h3> <ul class="space-y-1"> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="sql">SQL Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="mysql">MySQL Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="postgresql">PostgreSQL Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="mongodb">MongoDB Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="redis">Redis Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="sqlite">SQLite Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="database-design">Database Design</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="sqlserver">SQL Server Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="oracle">Oracle Database</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="mariadb">MariaDB Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="firebase">Firebase Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="elasticsearch">Elasticsearch Tutorial</a></li> </ul> </div> <!-- Mobile Development --> <div> <h3 class="text-sm font-semibold text-gray-300 uppercase tracking-wide mb-4">Mobil</h3> <ul class="space-y-1"> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="react-native">React Native Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="flutter">Flutter Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="dart">Dart Programming</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="swift">iOS Swift Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="swiftui">SwiftUI Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="kotlin">Android Kotlin</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="android-java">Android Java</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="xamarin">Xamarin Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="ionic">Ionic Framework</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="phonegap">PhoneGap Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="pwa">Progressive Web Apps</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="mobile-ui">Mobile UI Design</a></li> </ul> </div> <!-- Advanced Topics --> <div> <h3 class="text-sm font-semibold text-gray-300 uppercase tracking-wide mb-4">Fortgeschritten</h3> <ul class="space-y-1"> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="data-structures">Data Structures</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="algorithms">Algorithms Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="oop">Object Oriented Programming</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="design-patterns">Design Patterns</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="api-development">API Development</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="rest-api">REST API Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="graphql">GraphQL Tutorial</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="microservices">Microservices</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="machine-learning">Machine Learning</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="ai">Artificial Intelligence</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="blockchain">Blockchain Programming</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="game-dev">Game Development</a></li> </ul> </div> <!-- Programming Languages --> <div> <h3 class="text-sm font-semibold text-gray-300 uppercase tracking-wide mb-4">Programmiersprachen</h3> <ul class="space-y-1"> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="c">C Programming</a></li> <li><a href="/de/c-plus-plus/" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">C++ Programming</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="go">Go Programming</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="rust">Rust Programming</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="ruby">Ruby Programming</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="scala">Scala Programming</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="kotlin">Kotlin Programming</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="r">R Programming</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="matlab">MATLAB Programming</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="perl">Perl Programming</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="assembly">Assembly Language</a></li> <li><a href="#" class="coming-soon-link text-xs text-gray-400 hover:text-teal-400 transition-colors" data-course="lua">Lua Programming</a></li> </ul> </div> </div> <!-- Brand Section --> <div class="border-t border-gray-800 mt-12 pt-8"> <div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 flex flex-col md:flex-row justify-between items-center"> <div class="flex flex-col items-center text-center mb-6 md:mb-0"> <img src="/static/images/logo.6fecbe0a2cbf.png" alt="Mrebi Logo" class="h-12 w-auto object-contain mb-2"> <div> <p class="text-sm text-gray-400 mt-1">Lernen, Üben, Meistern</p> </div> </div> <div class="text-center md:text-right"> <div class="flex flex-wrap justify-center md:justify-end gap-6 mb-4"> <a href="#" class="text-sm text-gray-400 hover:text-teal-400 transition-colors">Über uns</a> <a href="#" class="text-sm text-gray-400 hover:text-teal-400 transition-colors">Kontakt</a> <a href="#" class="text-sm text-gray-400 hover:text-teal-400 transition-colors">Datenschutzrichtlinie</a> <a href="#" class="text-sm text-gray-400 hover:text-teal-400 transition-colors">Nutzungsbedingungen</a> <a href="#" class="text-sm text-gray-400 hover:text-teal-400 transition-colors">Blog</a> </div> <div class="text-gray-400"> <p class="text-sm mb-2"> Meistern Sie das Programmieren mit interaktiven Tutorials und praktischen Übungen </p> <p class="text-xs"> © 2025 Mrebi. Alle Rechte vorbehalten. </p> </div> </div> </div> <!-- Social Links --> <div class="mt-8 pt-6 border-t border-gray-800 text-center"> <div class="flex justify-center gap-6 flex-wrap"> <a href="https://www.linkedin.com/in/mr-ebi/" class="text-gray-400 hover:text-teal-400 transition-colors duration-200" aria-label="LinkedIn" target="_blank" rel="noopener noreferrer"> <svg class="w-6 h-6" fill="currentColor" viewBox="0 0 24 24"> <path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"/> </svg> </a> <a href="https://www.youtube.com/@mrebi-com" class="text-gray-400 hover:text-teal-400 transition-colors duration-200" aria-label="YouTube" target="_blank" rel="noopener noreferrer"> <svg class="w-6 h-6" fill="currentColor" viewBox="0 0 24 24"> <path d="M23.498 6.186a3.016 3.016 0 0 0-2.122-2.136C19.505 3.545 12 3.545 12 3.545s-7.505 0-9.377.505A3.017 3.017 0 0 0 .502 6.186C0 8.07 0 12 0 12s0 3.93.502 5.814a3.016 3.016 0 0 0 2.122 2.136c1.871.505 9.376.505 9.376.505s7.505 0 9.377-.505a3.015 3.015 0 0 0 2.122-2.136C24 15.93 24 12 24 12s0-3.93-.502-5.814zM9.545 15.568V8.432L15.818 12l-6.273 3.568z"/> </svg> </a> <a href="https://www.instagram.com/mrebicom/" class="text-gray-400 hover:text-teal-400 transition-colors duration-200" aria-label="Instagram" target="_blank" rel="noopener noreferrer"> <svg class="w-6 h-6" fill="currentColor" viewBox="0 0 24 24"> <path d="M12 2.163c3.204 0 3.584.012 4.85.07 3.252.148 4.771 1.691 4.919 4.919.058 1.265.069 1.645.069 4.849 0 3.205-.012 3.584-.069 4.849-.148 3.227-1.691 4.771-4.919 4.919-1.266.058-1.644.07-4.85.07-3.204 0-3.584-.012-4.849-.07-3.26-.148-4.771-1.691-4.919-4.919-.058-1.265-.069-1.645-.069-4.849 0-3.205.012-3.584.069-4.849.149-3.227 1.691-4.771 4.919-4.919 1.266-.058 1.644-.07 4.849-.07zm0-2.163c-3.259 0-3.667.014-4.947.072-4.358.2-6.78 2.618-6.98 6.98-.059 1.281-.073 1.689-.073 4.948 0 3.259.014 3.667.072 4.947.2 4.36 2.618 6.78 6.98 6.98 1.281.058 1.689.072 4.948.072 3.259 0 3.667-.014 4.947-.072 4.358-.2 6.78-2.618 6.98-6.98.059-1.281.073-1.689.073-4.948 0-3.259-.014-3.667-.072-4.947-.2-4.36-2.618-6.78-6.98-6.98-1.281-.058-1.689-.072-4.948-.072zm0 5.838c-3.403 0-6.162 2.759-6.162 6.162s2.759 6.163 6.162 6.163 6.162-2.759 6.162-6.163c0-3.403-2.759-6.162-6.162-6.162zm0 10.162c-2.209 0-4-1.79-4-4 0-2.209 1.791-4 4-4s4 1.791 4 4c0 2.21-1.791 4-4 4zm6.406-11.845c-.796 0-1.441.645-1.441 1.44s.645 1.44 1.441 1.44c.795 0 1.439-.645 1.439-1.44s-.644-1.44-1.439-1.44z"/> </svg> </a> <a href="#" class="text-gray-400 hover:text-teal-400 transition-colors duration-200" aria-label="TikTok" target="_blank" rel="noopener noreferrer"> <svg class="w-6 h-6" fill="currentColor" viewBox="0 0 24 24"> <path d="M19.59 6.69a4.83 4.83 0 0 1-3.77-4.25V2h-3.45v13.67a2.89 2.89 0 0 1-5.2 1.74 2.89 2.89 0 0 1 2.31-4.55 2.89 2.89 0 0 1 .88.13V9.65a6.34 6.34 0 0 0-1-.09A6.34 6.34 0 0 0 3 16a6.34 6.34 0 0 0 11.13 4.13 6.34 6.34 0 0 0 1.81-4.55V8.52a8.28 8.28 0 0 0 4.85 1.56V6.69z"/> </svg> </a> <a href="https://x.com/mrebicom" class="text-gray-400 hover:text-teal-400 transition-colors duration-200" aria-label="X" target="_blank" rel="noopener noreferrer"> <svg class="w-6 h-6" fill="currentColor" viewBox="0 0 24 24"> <path d="M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z"/> </svg> </a> <a href="https://www.facebook.com/mrebicom/" class="text-gray-400 hover:text-teal-400 transition-colors duration-200" aria-label="Facebook" target="_blank" rel="noopener noreferrer"> <svg class="w-6 h-6" fill="currentColor" viewBox="0 0 24 24"> <path d="M22.675 0H1.325C.593 0 0 .593 0 1.325v21.351C0 23.407.593 24 1.325 24H12.82v-9.294H9.692v-3.622h3.128V8.413c0-3.1 1.893-4.788 4.659-4.788 1.325 0 2.463.099 2.795.143v3.24l-1.918.001c-1.504 0-1.795.715-1.795 1.763v2.313h3.587l-.467 3.622h-3.12V24h6.116c.73 0 1.323-.593 1.323-1.325V1.325C24 .593 23.407 0 22.675 0z"/> </svg> </a> </div> <p class="text-xs text-gray-500 mt-4"> Join our community and start your programming journey today! </p> </div> </div> </div> </footer> <script> // Handle Coming Soon links in footer document.addEventListener('DOMContentLoaded', function() { document.querySelectorAll('.coming-soon-link').forEach(link => { link.addEventListener('click', function(e) { e.preventDefault(); const courseName = this.getAttribute('data-course') || 'default'; if (typeof window.showComingSoonModal === 'function') { window.showComingSoonModal(courseName); } }); }); }); </script> <!-- Prism.js for Syntax Highlighting --> <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/prism.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-html.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-css.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-javascript.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-python.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-php.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/prism/1.29.0/components/prism-sql.min.js"></script> <!-- Theme Switcher --> <script src="/static/js/theme-switcher.6107c7dde403.js"></script> <!-- Custom JavaScript --> <script src="/static/js/code-editor.744452e3251a.js"></script> <script src="/static/js/code-runner.0ff7847dbd6e.js"></script> <script src="/static/js/mobile-menu.b685f211e4ca.js"></script> <script> // Mobile menu toggle function toggleMobileMenu() { const menu = document.getElementById('mobile-menu'); menu.classList.toggle('hidden'); } // Enhanced language switcher function changeLanguage(languageCode) { const changeUrl = `/de/change-language/?language=${languageCode}`; if (typeof htmx !== 'undefined') { htmx.ajax('GET', changeUrl, { headers: { 'HX-Request': 'true' } }).then(function(response) { if (response.redirect) { window.location.href = response.redirect; } }); } else { window.location.href = changeUrl; } } // HTMX event listeners document.body.addEventListener('htmx:beforeRequest', function(evt) { document.getElementById('loading-indicator').style.display = 'block'; }); document.body.addEventListener('htmx:afterRequest', function(evt) { document.getElementById('loading-indicator').style.display = 'none'; }); document.body.addEventListener('htmx:afterSwap', function(evt) { // Reinitialize Prism.js highlighting if (typeof Prism !== 'undefined') { Prism.highlightAll(); } // Close mobile menu const mobileMenu = document.getElementById('mobile-menu'); if (mobileMenu && !mobileMenu.classList.contains('hidden')) { mobileMenu.classList.add('hidden'); } // Scroll to top for new content window.scrollTo({ top: 0, behavior: 'smooth' }); }); // Smooth scroll for anchor links document.addEventListener('click', function(e) { if (e.target.matches('a[href^="#"]')) { const href = e.target.getAttribute('href'); // Skip if just # if (href === '#') { return; } e.preventDefault(); const target = document.querySelector(href); if (target) { target.scrollIntoView({ behavior: 'smooth', block: 'start' }); } } }); // Coming Soon Modal functionality function initComingSoonModal() { const modal = document.getElementById('coming-soon-modal'); const closeBtn = document.getElementById('close-coming-soon-modal'); const backdrop = modal.querySelector('.coming-soon-backdrop'); const notifyForm = document.getElementById('notify-form'); // Course mapping for dynamic content const courseInfo = { 'python': { name: 'Python Programming', description: 'Lernen Sie Python von den Grundlagen bis zu fortgeschrittenen Konzepten einschließlich Webentwicklung, Data Science und Automatisierung.' }, 'java': { name: 'Java Programming', description: 'Beherrschen Sie Java-Programmierung für Unternehmensanwendungen, Android-Entwicklung und serverseitige Programmierung.' }, 'nodejs': { name: 'Node.js Development', description: 'Erstellen Sie skalierbare serverseitige Anwendungen mit Node.js und Express Framework.' }, 'react': { name: 'React Development', description: 'Erstellen Sie moderne Benutzeroberflächen mit React, Hooks und State Management.' }, 'typescript': { name: 'TypeScript Guide', description: 'Schreiben Sie sichereres JavaScript mit statischer Typprüfung und modernen Sprachfeatures.' }, 'vue': { name: 'Vue.js Framework', description: 'Erstellen Sie progressive Webanwendungen mit Vue.js und seinem Ökosystem.' }, 'angular': { name: 'Angular Framework', description: 'Entwickeln Sie unternehmenstaugliche Single-Page-Anwendungen mit Angular.' }, 'tailwind': { name: 'Tailwind CSS', description: 'Erstellen Sie moderne Designs schnell mit einem Utility-First CSS Framework.' }, 'django': { name: 'Django Framework', description: 'Erstellen Sie robuste Webanwendungen mit Djangos batterieinklusive Framework.' }, 'express': { name: 'Express.js Framework', description: 'Erstellen Sie schnelle und minimalistische Webanwendungen mit Express.js.' }, 'spring': { name: 'Spring Boot', description: 'Entwickeln Sie Unternehmens-Java-Anwendungen mit Spring Boot Framework.' }, 'php': { name: 'PHP Programming', description: 'Lernen Sie serverseitige Skripterstellung mit PHP für dynamische Webentwicklung.' }, 'laravel': { name: 'Laravel Framework', description: 'Erstellen Sie elegante Webanwendungen mit Laravels ausdrucksstarker Syntax.' }, 'sql': { name: 'SQL Tutorial', description: 'Beherrschen Sie Datenbankabfragen und Datenmanipulation mit SQL.' }, 'mysql': { name: 'MySQL Tutorial', description: 'Lernen Sie die weltweit beliebteste Open-Source-Relationaldatenbank.' }, 'postgresql': { name: 'PostgreSQL Tutorial', description: 'Beherrschen Sie erweiterte Funktionen des PostgreSQL-Datenbanksystems.' }, 'mongodb': { name: 'MongoDB Tutorial', description: 'Arbeiten Sie mit flexibler NoSQL-Dokumentendatenbank für moderne Anwendungen.' }, 'flutter': { name: 'Flutter Tutorial', description: 'Erstellen Sie schöne native mobile Apps für iOS und Android mit einer einzigen Codebasis.' }, 'react-native': { name: 'React Native Tutorial', description: 'Erstellen Sie native mobile Anwendungen mit React und JavaScript.' }, 'swift': { name: 'iOS Swift Tutorial', description: 'Entwickeln Sie native iOS-Anwendungen mit der Programmiersprache Swift.' }, 'kotlin': { name: 'Android Kotlin', description: 'Erstellen Sie moderne Android-Anwendungen mit der Programmiersprache Kotlin.' }, 'docker': { name: 'Docker', description: 'Containerisieren Sie Anwendungen für konsistente Bereitstellung in verschiedenen Umgebungen.' }, 'git': { name: 'Git', description: 'Beherrschen Sie Versionskontrolle und kollaborative Arbeitsabläufe mit Git.' }, 'aws': { name: 'AWS', description: 'Stellen Sie Anwendungen auf der Amazon Web Services Cloud-Plattform bereit und skalieren Sie sie.' }, 'kubernetes': { name: 'Kubernetes', description: 'Orchestrieren Sie containerisierte Anwendungen im großen Maßstab mit Kubernetes.' }, 'go': { name: 'Go Programming', description: 'Erstellen Sie schnelle, zuverlässige und effiziente Software mit der Go-Sprache.' }, 'rust': { name: 'Rust Programming', description: 'Lernen Sie Systemprogrammierung mit Speichersicherheit und kostenlosen Abstraktionen.' }, 'csharp': { name: 'C# Programming', description: 'Entwickeln Sie moderne Anwendungen mit C# und .NET-Ökosystem.' }, 'cpp': { name: 'C++ Programming', description: 'Beherrschen Sie Systemprogrammierung und Hochleistungsanwendungen mit C++.' }, 'bootstrap': { name: 'Bootstrap Framework', description: 'Erstellen Sie schnell responsive Websites mit Bootstrap CSS Framework.' }, 'jquery': { name: 'jQuery Library', description: 'Vereinfachen Sie JavaScript-Programmierung mit jQuery-Bibliothek für DOM-Manipulation.' }, 'sass': { name: 'Sass & SCSS', description: 'Schreiben Sie wartbareres CSS mit Sass-Präprozessor und erweiterten Funktionen.' }, 'graphql': { name: 'GraphQL Tutorial', description: 'Erstellen Sie effiziente APIs mit GraphQL-Abfragesprache und Schema-Definition.' }, 'nextjs': { name: 'Next.js', description: 'Erstellen Sie Full-Stack-React-Anwendungen mit Next.js Framework.' }, 'nuxtjs': { name: 'Nuxt.js', description: 'Erstellen Sie universelle Vue.js-Anwendungen mit Nuxt.js Framework.' }, 'redis': { name: 'Redis Tutorial', description: 'Lernen Sie In-Memory-Datenstrukturspeicher für Caching und Echtzeitanwendungen.' }, 'firebase': { name: 'Firebase Tutorial', description: 'Erstellen Sie Web- und Mobile-Apps mit Google Firebase Backend-Services.' }, 'elasticsearch': { name: 'Elasticsearch Tutorial', description: 'Implementieren Sie leistungsstarke Suche und Analysen mit Elasticsearch-Engine.' }, 'c': { name: 'C Programming', description: 'Lernen Sie die Grundlagen der Systemprogrammierung mit der C-Sprache.' }, 'ruby': { name: 'Ruby Programming', description: 'Schreiben Sie eleganten Code mit der Ruby-Programmiersprache und Rails Framework.' }, 'scala': { name: 'Scala Programming', description: 'Kombinieren Sie objektorientierte und funktionale Programmierung mit Scala.' }, 'r': { name: 'R Programming', description: 'Führen Sie statistische Berechnungen und Datenanalysen mit der R-Sprache durch.' }, 'matlab': { name: 'MATLAB Programming', description: 'Lösen Sie Ingenieur- und wissenschaftliche Probleme mit MATLAB-Programmierung.' }, 'perl': { name: 'Perl Programming', description: 'Beherrschen Sie Textverarbeitung und Systemadministration mit Perl.' }, 'assembly': { name: 'Assembly Language', description: 'Verstehen Sie Low-Level-Programmierung und Computerarchitektur mit Assembly.' }, 'lua': { name: 'Lua Programming', description: 'Lernen Sie leichte Skriptsprache für eingebettete Systeme und Spiele.' }, 'xamarin': { name: 'Xamarin Tutorial', description: 'Erstellen Sie plattformübergreifende mobile Apps mit Xamarin und C#.' }, 'ionic': { name: 'Ionic Framework', description: 'Erstellen Sie hybride mobile Anwendungen mit Ionic und Webtechnologien.' }, 'phonegap': { name: 'PhoneGap Tutorial', description: 'Erstellen Sie mobile Apps mit Webtechnologien auf der PhoneGap-Plattform.' }, 'pwa': { name: 'Progressive Web Apps', description: 'Erstellen Sie app-ähnliche Erfahrungen im Web mit Progressive Web App-Technologien.' }, 'mobile-ui': { name: 'Mobile UI Design', description: 'Entwerfen Sie schöne und intuitive Benutzeroberflächen für mobile Anwendungen.' }, 'data-structures': { name: 'Data Structures', description: 'Beherrschen Sie grundlegende Datenstrukturen für effiziente Algorithmusimplementierung.' }, 'algorithms': { name: 'Algorithms Tutorial', description: 'Lernen Sie algorithmisches Denken und Problemlösungstechniken.' }, 'oop': { name: 'Object Oriented Programming', description: 'Verstehen Sie objektorientierte Programmierkonzepte und Designprinzipien.' }, 'design-patterns': { name: 'Design Patterns', description: 'Wenden Sie bewährte Software-Designmuster an, um häufige Programmierprobleme zu lösen.' }, 'api-development': { name: 'API Development', description: 'Entwerfen und erstellen Sie robuste APIs für Web- und Mobile-Anwendungen.' }, 'rest-api': { name: 'REST API Tutorial', description: 'Erstellen Sie RESTful-Webservices nach bewährten Praktiken und Standards.' }, 'microservices': { name: 'Microservices', description: 'Entwerfen Sie skalierbare Anwendungen mit Microservices-Designmustern.' }, 'machine-learning': { name: 'Machine Learning', description: 'Erstellen Sie intelligente Systeme mit Machine Learning-Algorithmen und -Techniken.' }, 'ai': { name: 'Artificial Intelligence', description: 'Erkunden Sie KI-Konzepte und erstellen Sie intelligente Anwendungen mit modernen Frameworks.' }, 'blockchain': { name: 'Blockchain Programming', description: 'Entwickeln Sie dezentrale Anwendungen und Smart Contracts auf Blockchain-Plattformen.' }, 'game-dev': { name: 'Game Development', description: 'Erstellen Sie fesselnde Spiele mit modernen Game-Engines und Programmiertechniken.' }, 'webcomponents': { name: 'Web Components', description: 'Erstellen Sie wiederverwendbare benutzerdefinierte Elemente mit Web Components-Standards.' }, 'database-design': { name: 'Database Design', description: 'Entwerfen Sie effiziente und skalierbare Datenbankschemas und Beziehungen.' }, 'sqlserver': { name: 'SQL Server Tutorial', description: 'Arbeiten Sie mit Microsoft SQL Server-Datenbankmanagementsystem.' }, 'oracle': { name: 'Oracle Database', description: 'Beherrschen Sie Oracle-Datenbankadministration und Entwicklungstechniken.' }, 'mariadb': { name: 'MariaDB Tutorial', description: 'Lernen Sie MariaDB-Datenbankfunktionen und -administration.' }, 'dotnet': { name: 'ASP.NET Core', description: 'Erstellen Sie moderne Webanwendungen mit ASP.NET Core Framework.' }, 'flask': { name: 'Flask Framework', description: 'Erstellen Sie leichte Webanwendungen mit Python Flask Microframework.' }, 'android-java': { name: 'Android Java', description: 'Entwickeln Sie Android-Anwendungen mit der Java-Programmiersprache.' }, 'swiftui': { name: 'SwiftUI Tutorial', description: 'Erstellen Sie moderne iOS-Oberflächen mit SwiftUI deklarativem Framework.' }, 'prompt-engineering': { name: 'AI Prompt Engineering', description: 'Beherrschen Sie die Kunst der effektiven Kommunikation mit KI-Systemen und Sprachmodellen.' }, 'default': { name: 'Neuer Kurs', description: 'Dieser umfassende Kurs wird mit den neuesten Industriestandards und bewährten Praktiken entwickelt.' } }; // Show modal function function showModal(courseName = 'default') { const info = courseInfo[courseName] || courseInfo['default']; const courseNameElement = document.getElementById('course-name'); const courseDescElement = modal.querySelector('.course-description'); if (courseNameElement) courseNameElement.textContent = info.name; if (courseDescElement) courseDescElement.textContent = info.description; modal.classList.remove('hidden'); modal.classList.add('active'); document.body.style.overflow = 'hidden'; } // Hide modal function function hideModal() { modal.classList.remove('active'); modal.classList.add('hidden'); document.body.style.overflow = 'auto'; // Reset form if (notifyForm) { notifyForm.reset(); } } // Event listeners if (closeBtn) { closeBtn.addEventListener('click', hideModal); } if (backdrop) { backdrop.addEventListener('click', hideModal); } // Escape key document.addEventListener('keydown', function(e) { if (e.key === 'Escape' && modal.classList.contains('active')) { hideModal(); } }); // Handle notify form submission if (notifyForm) { notifyForm.addEventListener('submit', function(e) { e.preventDefault(); const email = document.getElementById('notify-email').value; if (email) { // Here you would typically send the email to your backend console.log('Notify email:', email); // Show success message alert('Thank you! We will notify you when this course becomes available.'); hideModal(); } }); } // Detect clicks on # links and show modal document.addEventListener('click', function(e) { if (e.target.matches('a[href="#"]') || e.target.closest('a[href="#"]')) { e.preventDefault(); // Try to extract course name from link text or data attribute const link = e.target.matches('a') ? e.target : e.target.closest('a'); const linkText = link.textContent.toLowerCase(); let courseName = 'default'; if (linkText.includes('python')) courseName = 'python'; else if (linkText.includes('java') && !linkText.includes('javascript')) courseName = 'java'; else if (linkText.includes('node')) courseName = 'nodejs'; else if (linkText.includes('react')) courseName = 'react'; else if (linkText.includes('typescript')) courseName = 'typescript'; else if (linkText.includes('vue')) courseName = 'vue'; else if (linkText.includes('angular')) courseName = 'angular'; else if (linkText.includes('tailwind')) courseName = 'tailwind'; else if (linkText.includes('django')) courseName = 'django'; else if (linkText.includes('express')) courseName = 'express'; else if (linkText.includes('spring')) courseName = 'spring'; else if (linkText.includes('php')) courseName = 'php'; else if (linkText.includes('laravel')) courseName = 'laravel'; else if (linkText.includes('sql') && !linkText.includes('mysql') && !linkText.includes('postgresql')) courseName = 'sql'; else if (linkText.includes('mysql')) courseName = 'mysql'; else if (linkText.includes('postgresql')) courseName = 'postgresql'; else if (linkText.includes('mongodb')) courseName = 'mongodb'; else if (linkText.includes('flutter')) courseName = 'flutter'; else if (linkText.includes('react native')) courseName = 'react-native'; else if (linkText.includes('swift')) courseName = 'swift'; else if (linkText.includes('kotlin')) courseName = 'kotlin'; else if (linkText.includes('docker')) courseName = 'docker'; else if (linkText.includes('git')) courseName = 'git'; else if (linkText.includes('aws')) courseName = 'aws'; else if (linkText.includes('kubernetes')) courseName = 'kubernetes'; else if (linkText.includes('go')) courseName = 'go'; else if (linkText.includes('rust')) courseName = 'rust'; else if (linkText.includes('c#')) courseName = 'csharp'; else if (linkText.includes('c++')) courseName = 'cpp'; else if (linkText.includes('bootstrap')) courseName = 'bootstrap'; else if (linkText.includes('jquery')) courseName = 'jquery'; else if (linkText.includes('sass')) courseName = 'sass'; else if (linkText.includes('graphql')) courseName = 'graphql'; else if (linkText.includes('next')) courseName = 'nextjs'; else if (linkText.includes('nuxt')) courseName = 'nuxtjs'; else if (linkText.includes('redis')) courseName = 'redis'; else if (linkText.includes('firebase')) courseName = 'firebase'; else if (linkText.includes('elasticsearch')) courseName = 'elasticsearch'; else if (linkText.includes('c programming')) courseName = 'c'; else if (linkText.includes('ruby')) courseName = 'ruby'; else if (linkText.includes('scala')) courseName = 'scala'; else if (linkText.includes('r programming')) courseName = 'r'; else if (linkText.includes('matlab')) courseName = 'matlab'; else if (linkText.includes('perl')) courseName = 'perl'; else if (linkText.includes('assembly')) courseName = 'assembly'; else if (linkText.includes('lua')) courseName = 'lua'; else if (linkText.includes('xamarin')) courseName = 'xamarin'; else if (linkText.includes('ionic')) courseName = 'ionic'; else if (linkText.includes('phonegap')) courseName = 'phonegap'; else if (linkText.includes('progressive web')) courseName = 'pwa'; else if (linkText.includes('mobile ui')) courseName = 'mobile-ui'; else if (linkText.includes('data structures')) courseName = 'data-structures'; else if (linkText.includes('algorithms')) courseName = 'algorithms'; else if (linkText.includes('object oriented')) courseName = 'oop'; else if (linkText.includes('design patterns')) courseName = 'design-patterns'; else if (linkText.includes('api development')) courseName = 'api-development'; else if (linkText.includes('rest api')) courseName = 'rest-api'; else if (linkText.includes('microservices')) courseName = 'microservices'; else if (linkText.includes('machine learning')) courseName = 'machine-learning'; else if (linkText.includes('artificial intelligence')) courseName = 'ai'; else if (linkText.includes('blockchain')) courseName = 'blockchain'; else if (linkText.includes('game development')) courseName = 'game-dev'; else if (linkText.includes('web components')) courseName = 'webcomponents'; else if (linkText.includes('database design')) courseName = 'database-design'; else if (linkText.includes('sql server')) courseName = 'sqlserver'; else if (linkText.includes('oracle')) courseName = 'oracle'; else if (linkText.includes('mariadb')) courseName = 'mariadb'; else if (linkText.includes('asp.net') || linkText.includes('dotnet')) courseName = 'dotnet'; else if (linkText.includes('flask')) courseName = 'flask'; else if (linkText.includes('android java')) courseName = 'android-java'; else if (linkText.includes('swiftui')) courseName = 'swiftui'; else if (linkText.includes('prompt engineering') || linkText.includes('ai prompt')) courseName = 'prompt-engineering'; showModal(courseName); } }); // Make showModal globally available window.showComingSoonModal = showModal; } // Initialize on page load document.addEventListener('DOMContentLoaded', function() { // Initialize Prism.js if (typeof Prism !== 'undefined') { Prism.highlightAll(); } // Hide loading indicator document.getElementById('loading-indicator').style.display = 'none'; // RTL adjustments if (window.siteConfig.isRTL) { document.body.classList.add('rtl'); } // Initialize Coming Soon Modal initComingSoonModal(); }); </script> <!-- Block for additional JavaScript --> <!-- Analytics (add your tracking code here) --> <!-- Add Google Analytics, Plausible, or other analytics scripts here --> </body> </html>