base.html
β
βββ head μμ β λΈλΌμ°μ μ€μ (λμ μ 보μ)
β
βββ body μμ β μ€μ νλ©΄
β
βββ header β μλ¨ λ€λΉκ²μ΄μ
βββ main β νμ΄μ§λ§λ€ λ€λ₯Έ λ΄μ© (ν΅μ¬)
βββ footer β νλ¨ μ€λͺ
<head>
charset="UTF-8" <!-- νκΈ κΉ¨μ§ λ°©μ§ -->
name="viewport" <!-- λͺ¨λ°μΌ νλ©΄ λμ -->
{% block title %} <!-- ν μ λͺ© (μμμ΄ μ±μλ£μ) -->
곡λΆμκ° κΈ°λ‘κΈ°
{% endblock %}
Google Fonts (Pretendard) <!-- ν°νΈ λΆλ¬μ€κΈ° -->
style.css <!-- μ 체 λμμΈ μ μ© -->
</head>
β header β λͺ¨λ νμ΄μ§ κ³΅ν΅ μλ¨
<header>
<a href="{% url 'study:list' %}">Study Tracker</a> <!-- λ‘κ³ (ν΄λ¦νλ©΄ ν) -->
<nav>
<a href="{% url 'study:list' %}">ν</a> <!-- λ€λΉκ²μ΄μ
-->
</nav>
</header>
β‘ main β νμ΄μ§λ§λ€ λ¬λΌμ§λ ν΅μ¬ μμ
<main>
{% block content %}{% endblock %} <!-- μμ νμΌμ΄ μ±μλ£λ κ³΅κ° -->
</main>
study_list.html, study_form.html, study_detail.html μ΄ μ¬κΈ°λ₯Ό μ±μβ’ footer β λͺ¨λ νμ΄μ§ κ³΅ν΅ νλ¨
<footer>
<p>κΎΈμ€ν κΈ°λ‘μ΄ κ²°κ΅ ν° μ±μ₯μ λ§λλλ€.</p>
<p>Django λ°λ³΅νλ ¨ 1 - 곡λΆμκ° κΈ°λ‘κΈ°</p>
</footer>
μμ νμΌλ€ (study_list, study_form, study_detail)
β
{% extends 'base.html' %} β "λ base μΈκ²"
β
{% block content %} β "main ꡬλ©λ§ λ΄κ° μ±μΈκ²"
β
header, footerλ base.htmlμ΄ μλμΌλ‘ λΆμ¬μ€
| λΆλΆ | κ΄λ¦¬ 주체 | λ³κ²½ μ¬λΆ |
|---|---|---|
| header | base.html | λͺ¨λ νμ΄μ§ λμΌ |
| content | μμ νμΌ | νμ΄μ§λ§λ€ λ€λ¦ |
| footer | base.html | λͺ¨λ νμ΄μ§ λμΌ |
base.html = κ³΅ν΅ λ μ΄μμ ν
ν€λ/νΈν°λ κ³ μ ,{% block content %}ꡬλ©λ§ μμ νμΌμ΄ μ±μλ£λ ꡬ쑰
{% load static %}
<!DOCTYPE html>
<html lang="ko">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{% block title %}곡λΆμκ° κΈ°λ‘κΈ°{% endblock %}</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Pretendard:wght@400;500;600;700;800&display=swap" rel="stylesheet">
<link rel="stylesheet" href="{% static 'css/style.css' %}">
</head>
<body>
<div class="app-shell">
<header class="site-header">
<div class="header-inner container">
<a href="{% url 'study:list' %}" class="brand">Study Tracker</a>
<nav class="main-nav">
<a href="{% url 'study:list' %}">ν</a>
</nav>
</div>
</header>
<main class="site-main">
{% block content %}{% endblock %}
</main>
<footer class="site-footer">
<div class="container footer-inner">
<p>κΎΈμ€ν κΈ°λ‘μ΄ κ²°κ΅ ν° μ±μ₯μ λ§λλλ€.</p>
<p class="footer-sub">Django λ°λ³΅νλ ¨ 1 - 곡λΆμκ° κΈ°λ‘κΈ°</p>
</div>
</footer>
</div>
</body>
</html>
detail.html
## HTML ν
νλ¦Ώ ν° κ·Έλ¦Ό λΆμ
---
### 1. μμ ꡬ쑰
```html
{% extends 'base.html' %}
{% block title %}
{{ study.title }} | 곡λΆμκ° κΈ°λ‘κΈ°
{% endblock %}
{% block content %}
... μ€μ λ΄μ© ...
{% endblock %}
| block | μν |
|---|---|
title | λΈλΌμ°μ ν μ λͺ© |
content | νλ©΄μ 보μ΄λ λ΄μ© μ 체 |
{% block content %}
β
βββ section.hero-card β μλ¨ μκ° μμ
β
βββ section.detail-card β μμΈ λ΄μ© μμ
β
βββ λ°°μ§λ€ (μΉ΄ν
κ³ λ¦¬, λ μ§, μκ°)
βββ νμ΅ λ©λͺ¨
βββ κΈ°λ‘ μ 보 (μμ±μΌ, μμ μΌ)
βββ λͺ©λ‘μΌλ‘ λ²νΌ
<section class="hero-card">
<span>Study Detail</span> <!-- μμ λΌλ²¨ -->
<h1>{{ study.title }}</h1> <!-- κ³΅λΆ μ λͺ© (DBμμ κ°μ Έμ΄) -->
<p>κΈ°λ‘ν κ³΅λΆ λ΄μ©μ...</p> <!-- μ€λͺ
κΈ -->
</section>
{{ study.title }} = views.pyμμ λκ²¨μ€ study κ°μ²΄μ μ λͺ©β λ°°μ§ λ¬Άμ
<div class="record-meta">
{{ study.get_category_display }} <!-- μΉ΄ν
κ³ λ¦¬ μ΄λ¦ -->
{{ study.study_date }} <!-- κ³΅λΆ λ μ§ -->
{{ study.hours }}μκ° {{ study.minutes }}λΆ <!-- κ³΅λΆ μκ° -->
{{ study.total_minutes }}λΆ <!-- μ΄ λΆ -->
</div>
β‘ νμ΅ λ©λͺ¨
{% if study.memo %}
{{ study.memo|linebreaksbr }} <!-- λ©λͺ¨ μμΌλ©΄ μΆλ ₯ -->
{% else %}
μμ±λ λ©λͺ¨κ° μμ΅λλ€. <!-- μμΌλ©΄ λ체 ν
μ€νΈ -->
{% endif %}
|linebreaksbr = λ©λͺ¨μμ μ€λ°κΏμ <br>νκ·Έλ‘ λ³νν΄μ£Όλ νν°β’ κΈ°λ‘ μ 보
<p>μμ±μΌ: {{ study.created_at }}</p>
<p>μμ μΌ: {{ study.updated_at }}</p>
β£ λ²νΌ
<a href="{% url 'study:list' %}">λͺ©λ‘μΌλ‘</a>
## HTML ν
νλ¦Ώ ν° κ·Έλ¦Ό λΆμ
---
### 1. μμ ꡬ쑰
```html
{% extends 'base.html' %}
{% block title %}
{{ study.title }} | 곡λΆμκ° κΈ°λ‘κΈ°
{% endblock %}
{% block content %}
... μ€μ λ΄μ© ...
{% endblock %}
| block | μν |
|---|---|
title | λΈλΌμ°μ ν μ λͺ© |
content | νλ©΄μ 보μ΄λ λ΄μ© μ 체 |
{% block content %}
β
βββ section.hero-card β μλ¨ μκ° μμ
β
βββ section.detail-card β μμΈ λ΄μ© μμ
β
βββ λ°°μ§λ€ (μΉ΄ν
κ³ λ¦¬, λ μ§, μκ°)
βββ νμ΅ λ©λͺ¨
βββ κΈ°λ‘ μ 보 (μμ±μΌ, μμ μΌ)
βββ λͺ©λ‘μΌλ‘ λ²νΌ
<section class="hero-card">
<span>Study Detail</span> <!-- μμ λΌλ²¨ -->
<h1>{{ study.title }}</h1> <!-- κ³΅λΆ μ λͺ© (DBμμ κ°μ Έμ΄) -->
<p>κΈ°λ‘ν κ³΅λΆ λ΄μ©μ...</p> <!-- μ€λͺ
κΈ -->
</section>
{{ study.title }} = views.pyμμ λκ²¨μ€ study κ°μ²΄μ μ λͺ©β λ°°μ§ λ¬Άμ
<div class="record-meta">
{{ study.get_category_display }} <!-- μΉ΄ν
κ³ λ¦¬ μ΄λ¦ -->
{{ study.study_date }} <!-- κ³΅λΆ λ μ§ -->
{{ study.hours }}μκ° {{ study.minutes }}λΆ <!-- κ³΅λΆ μκ° -->
{{ study.total_minutes }}λΆ <!-- μ΄ λΆ -->
</div>
β‘ νμ΅ λ©λͺ¨
{% if study.memo %}
{{ study.memo|linebreaksbr }} <!-- λ©λͺ¨ μμΌλ©΄ μΆλ ₯ -->
{% else %}
μμ±λ λ©λͺ¨κ° μμ΅λλ€. <!-- μμΌλ©΄ λ체 ν
μ€νΈ -->
{% endif %}
|linebreaksbr = λ©λͺ¨μμ μ€λ°κΏμ <br>νκ·Έλ‘ λ³νν΄μ£Όλ νν°β’ κΈ°λ‘ μ 보
<p>μμ±μΌ: {{ study.created_at }}</p>
<p>μμ μΌ: {{ study.updated_at }}</p>
β£ λ²νΌ
<a href="{% url 'study:list' %}">λͺ©λ‘μΌλ‘</a>
base.html λ μ΄μμ μμ
β hero-card : μ λͺ© + μ€λͺ
β detail-card
β λ°°μ§ : μΉ΄ν
κ³ λ¦¬, λ μ§, μκ° μμ½
β λ©λͺ¨ : μμΌλ©΄ μΆλ ₯, μμΌλ©΄ λ체 ν
μ€νΈ
β κΈ°λ‘ μ 보 : μμ±μΌ, μμ μΌ
β λͺ©λ‘μΌλ‘ λ²νΌ
div (ν° λ°μ€)
β
βββ section (μλ―Έμλ ꡬμ)
β β
β βββ span (μΈλΌμΈ ν
μ€νΈ)
β βββ h1 (κ°μ₯ ν° μ λͺ©)
β βββ p (λ¬Έλ¨ ν
μ€νΈ)
β
βββ section (μλ―Έμλ ꡬμ)
β
βββ div (κ·Έλ₯ λ°μ€)
β βββ span (μΈλΌμΈ ν
μ€νΈ)
β
βββ div (κ·Έλ₯ λ°μ€)
βββ h2 (λλ²μ§Έ μ λͺ©)
βββ p (λ¬Έλ¨ ν
μ€νΈ)
div β κ·Έλ₯ λ°μ€ (μλ―Έ μμ)
<div class="container"> <!-- μ 체λ₯Ό κ°μΈλ ν -->
<div class="record-meta"> <!-- λ°°μ§λ€ λ¬Άλ ν -->
<div style="margin-top"> <!-- κ°κ²©μ© ν -->
section β μλ―Έμλ ꡬμ
<section class="hero-card"> <!-- μκ° κ΅¬μ -->
<section class="detail-card"> <!-- μμΈ λ΄μ© ꡬμ -->
divμ λΉμ·νμ§λ§ "μ΄κ±΄ νλμ λ
립λ ꡬμμ΄μΌ" λΌλ μλ―Έ ν¬ν¨h1, h2 β μ λͺ© (μ«μκ° ν΄μλ‘ μμ μ λͺ©)
<h1>{{ study.title }}</h1> <!-- νμ΄μ§ λν μ λͺ© (κ°μ₯ νΌ) -->
<h2>νμ΅ λ©λͺ¨</h2> <!-- μΉμ
μ λͺ© (λλ²μ§Έ) -->
<h2>κΈ°λ‘ μ 보</h2> <!-- μΉμ
μ λͺ© (λλ²μ§Έ) -->
| νκ·Έ | ν¬κΈ° | μ©λ |
|---|---|---|
| h1 | κ°μ₯ νΌ | νμ΄μ§ λν μ λͺ© (νμ΄μ§λΉ 1κ°) |
| h2 | λλ²μ§Έ | μΉμ μ λͺ© |
| h3~h6 | μ μ μμμ§ | νμ μ λͺ© |
p β λ¬Έλ¨ ν
μ€νΈ
<p class="hero-desc">κΈ°λ‘ν κ³΅λΆ λ΄μ©μ...</p> <!-- μ€λͺ
λ¬Έλ¨ -->
<p class="record-memo">{{ study.memo }}</p> <!-- λ©λͺ¨ λ΄μ© -->
<p>μμ±μΌ: {{ study.created_at }}</p> <!-- μ 보 ν
μ€νΈ -->
span β μΈλΌμΈ ν
μ€νΈ μ‘°κ°
<span class="hero-eyebrow">Study Detail</span> <!-- μμ λΌλ²¨ -->
<span class="badge">{{ study.get_category_display }}</span> <!-- λ°°μ§ -->
<span class="badge gray">{{ study.study_date }}</span> <!-- λ°°μ§ -->
pλ divμ λ¬λ¦¬ μ€λ°κΏ μμ΄ μμΌλ‘ λλν λΆμ| νκ·Έ | μ€λ°κΏ | μλ―Έ | μ£Ό μ©λ |
|---|---|---|---|
div | O | μμ | λ μ΄μμ λ°μ€ |
section | O | μμ | λ 립λ ꡬμ |
p | O | μμ | λ¬Έλ¨ ν μ€νΈ |
span | X | μμ | μΈλΌμΈ ν μ€νΈ |
div β κ·Έλ₯ λ¬Άλ λ°μ€
section β μλ―Έμλ ꡬμ λ°μ€
h1/h2 β μ λͺ© (μ«μ μμμλ‘ νΌ)
p β λ¬Έλ¨ ν
μ€νΈ
span β μ€λ°κΏ μλ ν
μ€νΈ μ‘°κ°
μ½λμμ λΉ¨κ°μμΌλ‘ 보μ΄λ λΆλΆμ ν¬κ² 2κ°μ§ μ’ λ₯μ λλ€
{% %} β ν
νλ¦Ώ νκ·Έ (λͺ
λ Ήμ΄){% extends 'base.html' %} <!-- μμν΄ -->
{% block content %} <!-- μ¬κΈ°μλΆν° μ±μΈκ² -->
{% endblock %} <!-- μ¬κΈ°κΉμ§ -->
{% if study.memo %} <!-- 쑰건문 -->
{% else %}
{% endif %}
{% url 'study:list' %} <!-- URL μμ± -->
if / else / endif, block, url λ± λμμ μν{{ }} β ν
νλ¦Ώ λ³μ (κ° μΆλ ₯){{ study.title }} <!-- μ λͺ© μΆλ ₯ -->
{{ study.get_category_display }} <!-- μΉ΄ν
κ³ λ¦¬ μΆλ ₯ -->
{{ study.study_date }} <!-- λ μ§ μΆλ ₯ -->
{{ study.hours }} <!-- μκ° μΆλ ₯ -->
{{ study.memo|linebreaksbr }} <!-- λ©λͺ¨ μΆλ ₯ -->
{{ study.created_at }} <!-- μμ±μΌ μΆλ ₯ -->
|linebreaksbr λ νν° β μ€λ°κΏμ <br>λ‘ λ³ν| λ¬Έλ² | μκΉμ | μν |
|---|---|---|
| ν νλ¦Ώ νκ·Έ | {% %} | λͺ λ Ή μ€ν (if, for, url...) |
| ν νλ¦Ώ λ³μ | {{ }} | κ° μΆλ ₯ |
{% %} β νΌμΌνΈ(%) μμ β λͺ
λ Ήμ΄ (λκ° ν΄!)
{{ }} β νΌμΌνΈ μμ β λ³μ μΆλ ₯ (κ° λ³΄μ¬μ€!)
λΈλ‘ νκ·Έ (div, p, section) β ν μ€ μ 체λ₯Ό μ°¨μ§
βββββββββββββββββββββββββββ
β div (ν μ€ μ 체 μ°¨μ§) β
βββββββββββββββββββββββββββ
βββββββββββββββββββββββββββ
β p (λ ν μ€ μ 체 μ°¨μ§) β
βββββββββββββββββββββββββββ
μΈλΌμΈ νκ·Έ (span) β λ΄μ©λ§νΌλ§ μ°¨μ§
ββββββββββββββββββββββββ
βspan ββspan ββspan β β μμΌλ‘ λλν λΆμ
ββββββββββββββββββββββββ
<!-- p νκ·Έ β μ€λ°κΏ λ¨ -->
<p>Django</p>
<p>Python</p>
<!-- κ²°κ³Ό -->
Django
Python β κ°κ° λ€λ₯Έ μ€
<!-- span νκ·Έ β μ€λ°κΏ μλ¨ -->
<span>Django</span>
<span>Python</span>
<!-- κ²°κ³Ό -->
Django Python β κ°μ μ€μ λΆμ
<span class="badge">μΉ΄ν
κ³ λ¦¬</span>
<span class="badge gray">λ μ§</span>
<span class="badge gray">μκ°</span>
κ²°κ³Ό νλ©΄:
[ μΉ΄ν
κ³ λ¦¬ ] [ λ μ§ ] [ μκ° ] β λ°°μ§λ€μ΄ κ°λ‘λ‘ λλν
divλpλ₯Ό μΌλ€λ©΄ λ°°μ§κ° μΈλ‘λ‘ μμμ κ²
λΈλ‘(div, p) β μ€ μ 체 μ°¨μ§ β μΈλ‘λ‘ μμ
μΈλΌμΈ(span) β λ΄μ©λ§νΌλ§ β κ°λ‘λ‘ λλν