Ласкаво просимо на ще одну лекцію, де ми не будемо боятися ні HTML, ні Django. Сьогодні ми поговоримо про наслідування шаблонів у Django. Якщо у вас вже починають спливати в голові асоціації з наслідуванням класів у Python, то ви не так вже й далекі від істини. Тут теж використовується схожий принцип "навіщо писати одне й те саме десять разів, якщо можна написати це один раз і перевикористати". Н у що, готові зануритися у світ base.html і шаблонів?
Навіщо потрібне наслідування шаблонів?
Ви коли-небудь повторювали одні й ті самі рядки коду на кількох сторінках? Наприклад, копіювали блок <header> з однієї HTML-сторінки в іншу? Якщо так, то ви точно знаєте, що це не тільки нудно, а й загрожує помилками. А щойно у вас з'явиться необхідність змінити щось, скажімо, у футері вашого проєкту, доведеться оновлювати кожен HTML-файл вручну. Біль, страждання, сльози...
Django пропонує елегантне рішення через наслідування шаблонів. Суть у тому, щоб створити один базовий шаблон — щось на кшталт скелета, що містить загальний каркас для всіх сторінок, а потім розширювати його за допомогою більш специфічних елементів. Це повністю відповідає DRY-принципу (Don't Repeat Yourself).
Концепція наслідування шаблонів
Уявіть багатоповерхову будівлю. Основа будівлі — це ваш базовий шаблон. Він включає такі спільні елементи, як шапка (header), навігація, футер, а також всю структуру, яка однаково виглядає на всіх сторінках сайту. Кожен поверх будівлі — це дочірній шаблон, який наслідує основний каркас, але додає свої унікальні особливості.
Для реалізації цього в Django ми використовуємо два ключові елементи:
{% block %}— визначає області, які можна перевизначити в дочірніх шаблонах.{% extends %}— дозволяє дочірньому шаблону наслідувати базовий.
Створюємо базовий шаблон: base.html
Для початку створимо базовий шаблон, який буде загальною основою всіх сторінок нашого сайту. Нехай це буде простий скелет сайту з шапкою, навігацією та футером:
<!-- templates/base.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}My Website{% endblock %}</title>
<link rel="stylesheet" href="{% static 'styles.css' %}">
</head>
<body>
<header>
<h1>My Site</h1>
<nav>
<ul>
<li><a href="/">Home</a></li>
<li><a href="/about/">About</a></li>
<li><a href="/contact/">Contact</a></li>
</ul>
</nav>
</header>
<main>
{% block content %}
<p>Welcome to my website!</p>
{% endblock %}
</main>
<footer>
<p>© 2023 My Website</p>
</footer>
</body>
</html>
Що тут відбувається:
- Ми задали загальний каркас для сайту.
- У блоці
{% block title %}міститься заголовок сторінки, який може бути змінений у дочірніх шаблонах. - У блоці
{% block content %}ми зарезервували місце для унікального контенту кожної сторінки. - CSS-файли підключені з використанням тега
{% static %}, який ви вже бачили у попередніх лекціях.
На цьому етапі, base.html поки що не робить багато магії, але це основа всієї магії наслідування.
Наслідування базового шаблону
Тепер створимо дочірній шаблон для конкретної сторінки, наприклад, для "Про нас" (About):
<!-- templates/about.html -->
{% extends 'base.html' %}
{% block title %}About Us | My Website{% endblock %}
{% block content %}
<h2>Про нас</h2>
<p>Ми — невелика компанія, яка прагне зробити світ кращим.</p>
{% endblock %}
Що тут відбувається:
{% extends 'base.html' %}вказує, що цей шаблон наслідуєbase.html.- У блоці
{% block title %}ми перевизначаємо заголовок сторінки. - У блоці
{% block content %}додаємо унікальний контент для цієї конкретної сторінки.
Результат? Django збирає обидва шаблони: base.html та about.html, створюючи повноцінний HTML-документ. Оновлення у base.html автоматично застосовуються до всіх дочірніх шаблонів. Зручно? Ще й як!
Крок за кроком: додаємо новий шаблон з наслідуванням
- Створіть базовий шаблон (наприклад,
base.html), що містить загальні елементи сторінки. - Визначте блоки за допомогою
{% block %}, які можуть бути перевизначені. - Підключіть дочірній шаблон до базового за допомогою
{% extends %}. - Перевизначте блоки у дочірніх шаблонах для додавання унікального контенту.
Використання множинних блоків
Ви можете додавати скільки завгодно блоків, якщо це необхідно. Наприклад:
<!-- templates/base.html -->
<!DOCTYPE html>
<html>
<head>
<title>{% block title %}My Website{% endblock %}</title>
</head>
<body>
<header>
{% block header %}
<h1>Default Header</h1>
{% endblock %}
</header>
<main>
{% block content %}{% endblock %}
</main>
<footer>
{% block footer %}
<p>© 2023 My Website</p>
{% endblock %}
</footer>
</body>
</html>
У дочірніх шаблонах ви зможете перевизначити будь-який із блоків: title, header, content або footer.
Практика: створюємо сторінку "Контакти"
У рамках практики створіть шаблон contact.html, який наслідує base.html. Нехай він містить унікальний заголовок та форму для відправлення повідомлень. Ось підказка:
<!-- templates/contact.html -->
{% extends 'base.html' %}
{% block title %}Contact Us | My Website{% endblock %}
{% block content %}
<h2>Contact Us</h2>
<form action="/submit-contact/" method="post">
<label for="name">Ім'я:</label>
<input type="text" id="name" name="name">
<label for="message">Повідомлення:</label>
<textarea id="message" name="message"></textarea>
<button type="submit">Відправити</button>
</form>
{% endblock %}
Типові помилки (і як їх уникнути)
Одна з найчастіших помилок — забути вказати {% extends 'base.html' %} у дочірньому шаблоні. У цьому випадку Django просто проігнорує базовий шаблон. Якщо ви отримуєте порожню або несподівано дивну сторінку, перевірте цей момент.
Ще одна проблема — неправильно вказаний блок. Наприклад, якщо ви назвете блок у base.html як content, а в дочірньому шаблоні будете намагатися перевизначити contents, нічого не станеться. Django суворо стежить за збігом імен блоків.
Якщо ви отримуєте помилку "TemplateDoesNotExist", переконайтеся, що Django правильно налаштований для пошуку шаблонів. Перевірте налаштування DIRS у параметрі TEMPLATES вашого файлу settings.py.
Навіщо це потрібно в реальному житті?
У реальних веб-застосунках ви часто маєте кілька сторінок з однаковим оформленням, але різним вмістом: головна сторінка, блог, сторінка "Про нас", "Контакти" і так далі. Наслідування шаблонів спрощує їх управління та робить ваш код більш читабельним.
Крім того, використання базового шаблону дозволяє легко додавати нові елементи на всіх сторінках сайту. Наприклад, якщо ви додасте новий пункт у меню base.html, він з'явиться автоматично на всіх сторінках.
Тепер, коли ви освоїли наслідування шаблонів, ваш HTML-код став на порядок більш елегантним. Використовуйте цей інструмент з розумом, і ваш проєкт буде радувати не тільки користувачів, але й ваших колег!
ПЕРЕЙДІТЬ В ПОВНУ ВЕРСІЮ