در حال بارگذاری...

راه‌اندازی محیط HTML

راه‌اندازی HTML (Html-Setup) مانند پایه‌گذاری خانه‌ای است که می‌خواهید بسازید. این فرآیند ایجاد ساختار اولیه سند HTML (HTML document) است که به مرورگر (browser) می‌گوید چگونه محتوای شما را نمایش دهد. راه‌اندازی HTML شامل اعلان نوع سند (DOCTYPE declaration)، برچسب HTML، بخش سر (head section) و بخش بدنه (body section) می‌شود. این مرحله برای هر پروژه وبی ضروری است - چه در حال ساخت فروشگاه آنلاین باشید، وب‌سایت خبری طراحی کنید، وبلاگ شخصی راه‌اندازی کنید یا پورتال دولتی توسعه دهید. بدون راه‌اندازی مناسب HTML، وب‌سایت شما مانند کتابخانه‌ای بدون نظم خواهد بود. در این آموزش یاد خواهید گرفت که چگونه ساختار تمیز و حرفه‌ای سند HTML ایجاد کنید، عناصر اساسی را به درستی استفاده کنید و از اشتباهات رایج دوری کنید. این پایه به شما کمک می‌کند تا بعداً استایل‌دهی CSS و قابلیت‌های JavaScript اضافه کنید.

مثال اولیه راه‌اندازی Html

html
HTML Code
<!DOCTYPE html>
<html lang="fa">
<head>
<meta charset="UTF-8">
<title>وب‌سایت من</title> <!-- عنوان صفحه برای تب مرورگر -->
</head>
<body>
<h1>به وب‌سایت من خوش آمدید</h1> <!-- عنوان اصلی -->
<p>این اولین صفحه وب من است!</p> <!-- متن پاراگراف -->
</body>
</html>

کد بالا ساختار اساسی یک سند HTML کامل را نشان می‌دهد. برچسب <!DOCTYPE html> به مرورگر می‌گوید که این سند HTML5 است. برچسب کل سند را در بر می‌گیرد و ویژگی lang زبان فارسی را مشخص می‌کند. بخش حاوی اطلاعات فراداده (metadata) است که در صفحه قابل مشاهده نیست اما برای مرورگر مهم است. برچسب کدگذاری مناسب کاراکتر را تضمین می‌کند تا متن فارسی و زبان‌های دیگر به درستی نمایش داده شوند. برچسب متنی را که در تب مرورگر نمایش داده می‌شود تعریف می‌کند. بخش <body> شامل محتوای واقعی است که کاربران مشاهده می‌کنند. برچسب <h1> برای عنوان اصلی استفاده می‌شود و <p> برای متن پاراگراف. این ساختار پایه هر صفحه HTML است، چه در حال نوشتن پست وبلاگ ساده باشید یا ساخت سایت فروشگاهی پیچیده. بدون راه‌اندازی مناسب، محتوای شما در مرورگرها به درستی رندر نمی‌شود.</p> </div> <!-- Enhanced Code Block --> <div class="code-editor-container"> <div class="code-editor-header"> <h3 class="code-title">مثال عملی راه‌اندازی Html</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-36', this)"> 📋 کپی </button> <button type="button" class="copy-button bg-green-600 hover:bg-green-700 text-white" onclick="openCodeRunner('html', 'مثال عملی راه‌اندازی Html', 36)"> 🚀 اجرای زنده </button> </div> </div> <div class="code-block"> <pre><code id="code-36" class="language-html"><!DOCTYPE html> <html lang="fa" dir="rtl"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="description" content="فروشگاه آنلاین کتاب - بهترین کتاب‌ها"> <title>کتابخانه آنلاین | فروش کتاب</title> </head> <body> <header> <h1>کتابخانه آنلاین</h1> <nav> <a href="#about">درباره ما</a> <a href="#books">کتاب‌ها</a> <a href="#contact">تماس با ما</a> </nav> </header> <main> <section id="about"> <h2>درباره فروشگاه</h2> <p>ما بهترین کتاب‌های فارسی و انگلیسی را ارائه می‌دهیم.</p> </section> </main> </body> </html></code></pre> </div> </div> </div> <!-- Enhanced Text Block with Smart Links --> <div class="prose prose-lg max-w-none"> <p>بهترین روش‌ها شامل استفاده از HTML معنایی (semantic HTML) است - از برچسب‌های معنادار مانند header، nav، main، section استفاده کنید. برچسب meta viewport برای واکنش‌پذیری موبایل (mobile responsiveness) ضروری است. ویژگی dir="rtl" برای زبان‌های راست به چپ مانند فارسی مهم است. همیشه ساختار مناسب سند را حفظ کنید - اطلاعات فراداده در head و محتوا در body. اشتباهات رایج شامل فراموش کردن اعلان DOCTYPE است که باعث می‌شود مرورگرها در حالت quirks کار کنند. عدم تعیین meta charset باعث نمایش نادرست کاراکترهای خاص می‌شود. تودرتوسازی نادرست مانند قرار دادن <div> درون <p> نامعتبر است. فراموش کردن برچسب title برای سئو (SEO) مضر است. برای اشکال‌زدایی (debugging) از ابزارهای توسعه‌دهنده مرورگر استفاده کنید. با فشردن F12 می‌توانید ساختار HTML را بررسی کنید. از ابزارهای اعتبارسنجی مانند W3C Markup Validator استفاده کنید. همیشه تورفتگی (indentation) را برای خوانایی حفظ کنید.</p> </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">📊 مرجع سریع راه‌اندازی Html</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">عنصر</th> <th class="border border-gray-300 px-4 py-3 text-left font-semibold text-gray-700">توضیح</th> <th class="border border-gray-300 px-4 py-3 text-left font-semibold text-gray-700">مثال</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 html></td> <td class="border border-gray-300 px-4 py-3 text-gray-600">اعلان نوع سند HTML5</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"><html lang="fa" dir="rtl"></td> <td class="border border-gray-300 px-4 py-3 text-gray-600">عنصر ریشه با زبان و جهت</td> <td class="border border-gray-300 px-4 py-3 text-gray-600"><html lang="fa" dir="rtl"></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="UTF-8"></td> <td class="border border-gray-300 px-4 py-3 text-gray-600">کدگذاری کاراکتر برای متن</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"><title></td> <td class="border border-gray-300 px-4 py-3 text-gray-600">عنوان صفحه برای تب مرورگر</td> <td class="border border-gray-300 px-4 py-3 text-gray-600"><title>وب‌سایت من</title></td> </tr> <tr class="hover:bg-gray-50 transition-colors"> <td class="border border-gray-300 px-4 py-3 text-gray-600"><meta name="viewport"></td> <td class="border border-gray-300 px-4 py-3 text-gray-600">برچسب meta واکنش‌پذیر موبایل</td> <td class="border border-gray-300 px-4 py-3 text-gray-600"><meta name="viewport" content="width=device-width, initial-scale=1.0"></td> </tr> <tr class="hover:bg-gray-50 transition-colors"> <td class="border border-gray-300 px-4 py-3 text-gray-600"><meta name="description"></td> <td class="border border-gray-300 px-4 py-3 text-gray-600">توضیح صفحه برای موتورهای جستجو</td> <td class="border border-gray-300 px-4 py-3 text-gray-600"><meta name="description" content="توضیح صفحه"></td> </tr> </tbody> </table> </div> </div> </div> <!-- Enhanced Text Block with Smart Links --> <div class="prose prose-lg max-w-none"> <p>از این آموزش ساختار مناسب سند HTML را آموختید. نکات کلیدی شامل این است که هر صفحه HTML باید عناصر DOCTYPE، html، head و body داشته باشد. برچسب‌های meta برای سئو و دسترسی‌پذیری مهم هستند. ساختار HTML معنایی کد تمیز ایجاد می‌کند. این پایه به شما کمک می‌کند تا استایل‌دهی CSS اضافه کنید که در آن رنگ‌ها، فونت‌ها و طرح‌بندی‌ها را تعریف خواهید کرد. برای تعامل‌های JavaScript نیز ساختار HTML مناسب ضروری است. موضوعات بعدی که باید بیاموزید شامل مبانی CSS، طراحی واکنش‌پذیر و عناصر فرم است. برای تمرین، ساختار اساسی انواع مختلف وب‌سایت‌ها را بسازید. همیشه از ابزارهای اعتبارسنجی استفاده کنید و سازگاری مرورگر را بررسی کنید. با تمرین منظم می‌توانید وب‌سایت‌هایی با کیفیت حرفه‌ای بسازید.</p> </div> </div> <!-- Enhanced Quiz Section --> <div class="mb-8"> <h2 class="text-2xl md:text-3xl font-bold mb-6 bg-clip-text"> 🧠 دانش خود را بیازمایید </h2> <!-- Modern Quiz Container - Direct Display --> <div id="quiz-container" class="quiz-modern-container"> <!-- Hidden CSRF Token --> <input type="hidden" name="csrfmiddlewaretoken" value="bVasGFFfpHcVMnr4duA9e5QcFC4ZCTyAYLw9Ea1zCJxfCCZF8UbhPOQ9b0tHkY9m"> <!-- 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">آماده شروع</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">دانش راه‌اندازی Html خود را بیازمایید</h3> <p class="quiz-intro-subtitle">Challenge yourself with this interactive quiz and see how well you understand the topic</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">4</div> <div class="stat-label">سوالات</div> </div> <div class="quiz-stat-card"> <span class="stat-icon">🎯</span> <div class="stat-value">70%</div> <div class="stat-label">برای قبولی</div> </div> <div class="quiz-stat-card"> <span class="stat-icon">♾️</span> <div class="stat-value">∞</div> <div class="stat-label">زمان</div> </div> <div class="quiz-stat-card"> <span class="stat-icon">🔄</span> <div class="stat-value">∞</div> <div class="stat-label">تلاش‌ها</div> </div> </div> <!-- Quiz Instructions --> <div class="quiz-instructions"> <h4 class="instructions-title">📝 دستورالعمل‌ها</h4> <ul class="instructions-list"> <li>هر سوال را با دقت بخوانید</li> <li>بهترین پاسخ را برای هر سوال انتخاب کنید</li> <li>می‌توانید آزمون را هر چند بار که می‌خواهید تکرار کنید</li> <li>پیشرفت شما در بالا نمایش داده می‌شود</li> </ul> </div> <button id="start-quiz-btn" class="quiz-start-button" onclick="startQuiz(2)"> <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> شروع آزمون </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">سوال 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">ارسال پاسخ</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">بارگذاری آزمون شما...</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: {} }; // Show loading showSection('quiz-loading'); updateProgress(0, 'راه‌اندازی آزمون...', ''); 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 = `/fa/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('شروع آزمون ناموفق بود. لطفاً دوباره تلاش کنید.'); 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, `سوال ${questionNumber}`, `${questionNumber} از ${totalQuestions}`); // Update question number const questionNumberEl = document.getElementById('question-number'); if (questionNumberEl) { questionNumberEl.textContent = `سوال ${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 = 'ارسال پاسخ'; } // 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 = `/fa/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('ارسال پاسخ ناموفق بود. لطفاً دوباره تلاش کنید.'); 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, 'Calculating Results...', 'لطفاً منتظر بمانید'); 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); displayResults(scoreValue, correctAnswers, totalQuestions); // Stop timer if running if (quizTimer) { clearInterval(quizTimer); hideTimer(); } }) .catch(error => { console.error('Results fetch error:', error); showError('بارگذاری نتایج ناموفق بود. لطفاً صفحه را تازه‌سازی کنید.'); showSection('quiz-questions'); }); } 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 ? 'تبریک!' : 'به یادگیری ادامه دهید!'} </h3> <p class="result-subtitle"> ${passed ? 'در آزمون قبول شدید!' : 'می‌توانید بهتر عمل کنید. دوباره تلاش کنید!'} </p> </div> <div class="score-display"> <div class="score-percentage ${passed ? 'passed' : 'failed'}">${scoreValue}%</div> <div class="score-details"> ${correctAnswers} از ${totalQuestions} صحیح </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;"> نمره قبولی: ${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> تکرار آزمون </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> مشاهده پاسخ‌ها </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> بستن </button> </div> <!-- Answer Sheet Section --> <div id="answer-sheet" class="answer-sheet-section" style="display: none;"> <div class="answer-sheet-header"> <h4>📋 برگه پاسخ‌ها</h4> <button class="close-answer-sheet" onclick="toggleAnswerSheet()">✕</button> </div> <div id="answer-sheet-content" class="answer-sheet-content"> بارگذاری پاسخ‌ها... </div> </div> `; // Show results section showSection('quiz-results'); updateProgress(100, 'آزمون تکمیل شد!', `${scoreValue}% امتیاز`); // 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> مخفی کردن پاسخ‌ها `; } 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> مشاهده پاسخ‌ها `; } } 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">کل سوالات</div> </div> <div class="summary-stat correct"> <div class="number" id="correct-count">0</div> <div class="label">صحیح</div> </div> <div class="summary-stat incorrect"> <div class="number" id="incorrect-count">0</div> <div class="label">نادرست</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">توضیح:</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, 'آماده شروع', ''); } 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('زمان تمام شد! آزمون به صورت خودکار ارسال می‌شود.'); } } 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"> <a href="/fa/html/html-introduction/" class="nav-link prev" hx-get="/fa/html/html-introduction/" hx-target="#topic-content" hx-push-url="true" aria-label="رفتن به موضوع قبلی"> → قبلی </a> <div class="nav-center"> <div class="text-sm font-semibold">موضوع 2 از 51</div> <div class="text-xs mt-1 opacity-75">Html آموزش</div> </div> <a href="/fa/html/html-syntax/" class="nav-link next" hx-get="/fa/html/html-syntax/" hx-target="#topic-content" hx-push-url="true" aria-label="رفتن به موضوع بعدی"> بعدی ← </a> </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('/fa/api/smart-link-click/', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-CSRFToken': 'bVasGFFfpHcVMnr4duA9e5QcFC4ZCTyAYLw9Ea1zCJxfCCZF8UbhPOQ9b0tHkY9m' }, body: JSON.stringify({ keyword_id: keywordId, source_content_type: 'topic', source_content_id: 2, 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', 'bVasGFFfpHcVMnr4duA9e5QcFC4ZCTyAYLw9Ea1zCJxfCCZF8UbhPOQ9b0tHkY9m'); fetch('/fa/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('/fa/try-it/' + language + '/', '_blank'); } }) .catch(error => { console.error('Error:', error); window.open('/fa/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() { 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'); } }); } 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>خطا:</strong> مشکلی پیش آمد. لطفاً صفحه را تازه‌سازی کنید.</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> <!-- 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">فرانت‌اند</h3> <ul class="space-y-1"> <li><a href="/fa/html/" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">HTML Tutorial</a></li> <li><a href="/fa/css/" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">CSS Complete Guide</a></li> <li><a href="/fa/javascript/" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">JavaScript Fundamentals</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">React Development</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">Vue.js Framework</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">Angular Framework</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">TypeScript Guide</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">Bootstrap Framework</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">Tailwind CSS</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">Sass & SCSS</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">jQuery Library</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">Web Components</a></li> </ul> </div> <!-- Backend Development --> <div> <h3 class="text-sm font-semibold text-gray-300 uppercase tracking-wide mb-4">بک‌اند</h3> <ul class="space-y-1"> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">Python Tutorial</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">Django Framework</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">Flask Framework</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">Node.js Tutorial</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">Express.js Framework</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">PHP Programming</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">Laravel Framework</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">Java Programming</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">Spring Boot</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">C# Programming</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">ASP.NET Core</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">Ruby on Rails</a></li> </ul> </div> <!-- Database Programming --> <div> <h3 class="text-sm font-semibold text-gray-300 uppercase tracking-wide mb-4">پایگاه داده</h3> <ul class="space-y-1"> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">SQL Tutorial</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">MySQL Tutorial</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">PostgreSQL Tutorial</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">MongoDB Tutorial</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">Redis Tutorial</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">SQLite Tutorial</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">Database Design</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">SQL Server Tutorial</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">Oracle Database</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">MariaDB Tutorial</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">Firebase Tutorial</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">Elasticsearch Tutorial</a></li> </ul> </div> <!-- Mobile Development --> <div> <h3 class="text-sm font-semibold text-gray-300 uppercase tracking-wide mb-4">موبایل</h3> <ul class="space-y-1"> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">React Native Tutorial</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">Flutter Tutorial</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">Dart Programming</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">iOS Swift Tutorial</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">SwiftUI Tutorial</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">Android Kotlin</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">Android Java</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">Xamarin Tutorial</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">Ionic Framework</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">PhoneGap Tutorial</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">Progressive Web Apps</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">Mobile UI Design</a></li> </ul> </div> <!-- Advanced Topics --> <div> <h3 class="text-sm font-semibold text-gray-300 uppercase tracking-wide mb-4">پیشرفته</h3> <ul class="space-y-1"> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">Data Structures</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">Algorithms Tutorial</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">Object Oriented Programming</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">Design Patterns</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">API Development</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">REST API Tutorial</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">GraphQL Tutorial</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">Microservices</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">Machine Learning</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">Artificial Intelligence</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">Blockchain Programming</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">Game Development</a></li> </ul> </div> <!-- Programming Languages --> <div> <h3 class="text-sm font-semibold text-gray-300 uppercase tracking-wide mb-4">زبان‌های برنامه‌نویسی</h3> <ul class="space-y-1"> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">C Programming</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">C++ Programming</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">Go Programming</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">Rust Programming</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">Ruby Programming</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">Scala Programming</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">Kotlin Programming</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">R Programming</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">MATLAB Programming</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">Perl Programming</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">Assembly Language</a></li> <li><a href="#" class="text-xs text-gray-400 hover:text-teal-400 transition-colors">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">یاد بگیرید، تمرین کنید، تسلط پیدا کنید</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">درباره ما</a> <a href="#" class="text-sm text-gray-400 hover:text-teal-400 transition-colors">تماس</a> <a href="#" class="text-sm text-gray-400 hover:text-teal-400 transition-colors">سیاست حفظ حریم خصوصی</a> <a href="#" class="text-sm text-gray-400 hover:text-teal-400 transition-colors">شرایط خدمات</a> <a href="#" class="text-sm text-gray-400 hover:text-teal-400 transition-colors">بلاگ</a> </div> <div class="text-gray-400"> <p class="text-sm mb-2"> برنامه‌نویسی را با آموزش‌های تعاملی و تمرین عملی تسلط پیدا کنید </p> <p class="text-xs"> © 2025 Mrebi. تمام حقوق محفوظ است. </p> </div> </div> </div> <!-- Social Links --> <div class="mt-8 pt-6 border-t border-gray-800 text-center"> <div class="flex justify-center space-x-6 space-x-reverse"> <a href="#" class="text-gray-400 hover:text-teal-400 transition-colors" aria-label="GitHub"> <svg class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24"> <path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/> </svg> </a> <a href="#" class="text-gray-400 hover:text-teal-400 transition-colors" aria-label="Twitter"> <svg class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24"> <path d="M23.953 4.57a10 10 0 01-2.825.775 4.958 4.958 0 002.163-2.723c-.951.555-2.005.959-3.127 1.184a4.92 4.92 0 00-8.384 4.482C7.69 8.095 4.067 6.13 1.64 3.162a4.822 4.822 0 00-.666 2.475c0 1.71.87 3.213 2.188 4.096a4.904 4.904 0 01-2.228-.616v.06a4.923 4.923 0 003.946 4.827 4.996 4.996 0 01-2.212.085 4.936 4.936 0 004.604 3.417 9.867 9.867 0 01-6.102 2.105c-.39 0-.779-.023-1.17-.067a13.995 13.995 0 007.557 2.209c9.053 0 13.998-7.496 13.998-13.985 0-.21 0-.42-.015-.63A9.935 9.935 0 0024 4.59z"/> </svg> </a> <a href="#" class="text-gray-400 hover:text-teal-400 transition-colors" aria-label="Discord"> <svg class="w-5 h-5" fill="currentColor" viewBox="0 0 24 24"> <path d="M20.317 4.37a19.791 19.791 0 0 0-4.885-1.515.074.074 0 0 0-.079.037c-.21.375-.444.864-.608 1.25a18.27 18.27 0 0 0-5.487 0 12.64 12.64 0 0 0-.617-1.25.077.077 0 0 0-.079-.037A19.736 19.736 0 0 0 3.677 4.37a.07.07 0 0 0-.032.027C.533 9.046-.32 13.58.099 18.057a.082.082 0 0 0 .031.057 19.9 19.9 0 0 0 5.993 3.03.078.078 0 0 0 .084-.028c.462-.63.874-1.295 1.226-1.994a.076.076 0 0 0-.041-.106 13.107 13.107 0 0 1-1.872-.892.077.077 0 0 1-.008-.128 10.2 10.2 0 0 0 .372-.292.074.074 0 0 1 .077-.01c3.928 1.793 8.18 1.793 12.062 0a.074.074 0 0 1 .078.01c.12.098.246.198.373.292a.077.077 0 0 1-.006.127 12.299 12.299 0 0 1-1.873.892.077.077 0 0 0-.041.107c.36.698.772 1.362 1.225 1.993a.076.076 0 0 0 .084.028 19.839 19.839 0 0 0 6.002-3.03.077.077 0 0 0 .032-.054c.5-5.177-.838-9.674-3.549-13.66a.061.061 0 0 0-.031-.03zM8.02 15.33c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.956-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.956 2.418-2.157 2.418zm7.975 0c-1.183 0-2.157-1.085-2.157-2.419 0-1.333.955-2.419 2.157-2.419 1.21 0 2.176 1.096 2.157 2.42 0 1.333-.946 2.418-2.157 2.418z"/> </svg> </a> <a href="#" class="text-gray-400 hover:text-teal-400 transition-colors" aria-label="YouTube"> <svg class="w-5 h-5" 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="#" class="text-gray-400 hover:text-teal-400 transition-colors" aria-label="LinkedIn"> <svg class="w-5 h-5" 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> </div> <p class="text-xs text-gray-500 mt-4"> به جامعه ما بپیوندید و سفر برنامه‌نویسی خود را امروز شروع کنید! </p> </div> </div> </div> </footer> <!-- 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.b9d4d05ba1fb.js"></script> <!-- Custom JavaScript --> <script src="/static/js/code-editor.7d90db52a977.js"></script> <script src="/static/js/code-runner.9349a2537311.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 = `/fa/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^="#"]')) { e.preventDefault(); const target = document.querySelector(e.target.getAttribute('href')); if (target) { target.scrollIntoView({ behavior: 'smooth', block: 'start' }); } } }); // 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'); } }); </script> <!-- Block for additional JavaScript --> <!-- Analytics (add your tracking code here) --> <!-- Add Google Analytics, Plausible, or other analytics scripts here --> </body> </html>