Search

νƒ€μž„λ¦¬ν”„ λ ˆμ΄μ•„μ›ƒ λ‹€μ΄μ–Όλ ‰νŠΈ

νƒ€μž„λ¦¬ν”„ λ ˆμ΄μ•„μ›ƒ λ‹€μ΄μ–Όλ ‰νŠΈ

β€’
νƒ€μž„λ¦¬ν”„ λ ˆμ΄μ•„μ›ƒ λ‹€μ΄μ–Όλ ‰νŠΈ μ˜μ‘΄μ„±
β—¦
build.gradle
β€’
ν”„λž˜κ·Έλ¨ΌνŠΈ
β€’
λ ˆμ΄μ•„μ›ƒ

νƒ€μž„λ¦¬ν”„ λ ˆμ΄μ•„μ›ƒ λ‹€μ΄μ–Όλ ‰νŠΈ μ˜μ‘΄μ„±

// νƒ€μž„λ¦¬ν”„ λ‹€μ΄μ–Όλ ‰νŠΈ λ ˆμ΄μ•„μ›ƒ implementation 'nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect'
Java
볡사

build.gradle

plugins { id 'java' id 'war' id 'org.springframework.boot' version '3.2.5' id 'io.spring.dependency-management' version '1.1.4' } group = 'com.aloha' version = '0.0.1-SNAPSHOT' java { sourceCompatibility = '17' } configurations { compileOnly { extendsFrom annotationProcessor } } repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-thymeleaf' implementation 'org.springframework.boot:spring-boot-starter-web' compileOnly 'org.projectlombok:lombok' developmentOnly 'org.springframework.boot:spring-boot-devtools' annotationProcessor 'org.projectlombok:lombok' providedRuntime 'org.springframework.boot:spring-boot-starter-tomcat' testImplementation 'org.springframework.boot:spring-boot-starter-test' // νƒ€μž„λ¦¬ν”„ λ‹€μ΄μ–Όλ ‰νŠΈ λ ˆμ΄μ•„μ›ƒ implementation 'nz.net.ultraq.thymeleaf:thymeleaf-layout-dialect' } tasks.named('test') { useJUnitPlatform() }
Java
볡사

ν”„λž˜κ·Έλ¨ΌνŠΈ (Fragment)

νƒ€μž„λ¦¬ν”„ λ ˆμ΄μ•„μ›ƒμ˜ κ³΅ν†΅μ μœΌλ‘œ μ‚¬μš©ν•  λΆ€λΆ„
UI μ—μ„œ κ³΅ν†΅μ μœΌλ‘œ μ‚¬μš©λ˜λŠ” ꡬ성 μš”μ†Œλ“€μ„ λ³„λ„μ˜ HTML 파일둜 λ§Œλ“ λ‹€. 주둜 헀더, ν‘Έν„°, μ‚¬μ΄λ“œλ°” 등을 관리할 수 μžˆμŠ΅λ‹ˆλ‹€.

ν”„λž˜κ·Έλ¨ΌνŠΈ μ‹€μŠ΅νŒŒμΌ

β€’
~/fragment/header.html
β€’
~/fragment/footer.html
β€’
~/fragment/link.html
β€’
~/fragment/script.html

~/fragment/header.html

<!-- ν”„λž˜κ·Έλ¨ΌνŠΈ : λ ˆμ΄μ•„μ›ƒμ—μ„œ κ³΅ν†΅μ μœΌλ‘œ μ‚¬μš©ν•  UI --> <!-- th:fragment="ν”„λž˜κ·Έλ¨ΌνŠΈ λͺ…" --> <th:block th:fragment="header"> <header> <ul> <li><a href="/user">μ‚¬μš©μž</a></li> <li><a href="/admin">κ΄€λ¦¬μž</a></li> </ul> <ul> <li><a href="/login">둜그인</a></li> <li><a href="/join">νšŒμ›κ°€μž…</a></li> </ul> </header> </th:block>
HTML
볡사

~/fragment/footer.html

<th:block th:fragment="footer"> <footer> <p>copyright ALL RIGHT RESERVED</p> </footer> </th:block>
HTML
볡사

~/fragment/link.html

<th:block th:fragment="link"> <link rel="stylesheet" href="/css/style.css"> </th:block>
HTML
볡사

~/fragment/script.html

<th:block th:fragment="script"> <!-- js κ°€μ Έμ˜€λŠ” μˆœμ„œ--> <!-- jQuery --> <!-- jQuery 기반 라이브러리 --> <!-- μžλ°”μŠ€ν¬λ¦½νŠΈ 라이브러리 --> <!-- μ‚¬μš©μž μ •μ˜ μžλ°”μŠ€ν¬λ¦½νŠΈ --> <script src="/js/script.js" ></script> </th:block>
HTML
볡사

λ ˆμ΄μ•„μ›ƒ (Layout)

νŠΉμ • νŽ˜μ΄μ§€μ— UIλ₯Ό ν•˜λ‚˜μ˜ ν…œν”Œλ¦ΏμœΌλ‘œ 미리 ꡬ성 해놓은 μ˜μ—­
λ ˆμ΄μ•„μ›ƒ ν…œν”Œλ¦Ώμ„ ν”„λž˜κ·Έλ¨ΌνŠΈλ‘œ κ΅¬μ„±ν•˜κ³ , 각 νŽ˜μ΄μ§€λ§ˆλ‹€ λ‹€λ₯΄κ²Œ 보여쀄 컨텐츠 μ˜μ—­μ„ μ§€μ •ν•΄μ„œ 미리 μ§œμ—¬μ§„ λ ˆμ΄μ•„μ›ƒμ„ λ§Œλ“€κΈ° μœ„ν•΄ μ‚¬μš©ν•˜λŠ” μš”μ†Œ

~/layout/main_layout.html

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <!-- link --> <th:block th:replace="~{fragment/link::link}"></th:block> </head> <body> <!-- header --> <th:block th:replace="~{fragment/header::header}"></th:block> <!-- ⭐ content --> <!-- layout:fragment="λ ˆμ΄μ•„μ›ƒμ˜ ν”„λ ˆκ·Έλ¨ΌνŠΈ μ˜μ—­ 이름" --> <th:block layout:fragment="content"></th:block> <!-- footer --> <th:block th:replace="~{fragment/footer::footer}"></th:block> <!-- script --> <th:block th:replace="~{fragment/script::script}"></th:block> </body> </html>
HTML
볡사

index.html

μ—¬κΈ°μ„œλŠ” ν”„λž˜κ·Έλ¨ΌνŠΈλ₯Ό κ°€μ Έμ™€μ„œ 곡톡 λ ˆμ΄μ•„μ›ƒμ„ μ μš©ν•©λ‹ˆλ‹€.
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <th:block th:replace="~{fragment/link::link}"></th:block> </head> <body> <!-- th:replace : ν”„λž˜κ·Έλ¨ΌνŠΈλ₯Ό κ°€μ Έμ˜€λŠ” 속성 --> <!-- th:replace="~{폴더λͺ…/파일λͺ…::ν”„λž˜κ·Έλ¨ΌνŠΈλͺ…}" --> <th:block th:replace="~{fragment/header::header}"></th:block> <div class="container"> <h3>CONTENT</h3> </div> <th:block th:replace="~{fragment/footer::footer}"></th:block> <th:block th:replace="~{fragment/script::script}"></th:block> </body> </html>
HTML
볡사

main.html

<!DOCTYPE html> <html xmlns:th="http://www.thymeleaf.org" xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout" layout:decorate="~{/layout/main_layout}" > <!-- ⭐ layout:decorate="~{/λ ˆμ΄μ•„μ›ƒ 경둜/λ ˆμ΄μ•„μ›ƒ 파일λͺ…}" --> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>메인 ν™”λ©΄</title> </head> <!-- ⭐ layout:fragment="λ ˆμ΄μ•„μ›ƒ ν”„λ ˆκ·Έλ¨ΌνŠΈ 이름" --> <body layout:fragment="content"> <div class="container"> <h3>CONTENT</h3> </div> </body> </html>
HTML
볡사

style.css

* { margin: 0; padding: 0; box-sizing: border-box; } a { color: black; text-decoration: none; } ul { list-style-type: none; } header { height: 80px; background-color: lightslategray; display: flex; justify-content: space-between; align-items: center; } header ul { display: flex; height: 100%; padding: 0 20px; } header ul li { min-width: 100px; } header ul li a { display: inline-block; min-width: 120px; line-height: 80px; text-align: center; color: white; } header ul li a:hover { font-weight: bold; } .container { border: 1px solid black; max-width: 1024px; min-height: 300px; margin: 0 auto; padding: 12px; } footer { background-color: black; color: white; min-height: 100px; text-align: center; } footer p { line-height: 100px; }
CSS
볡사