# Thymeleaf ๊ธฐ๋Šฅ - ํ…œํ”Œ๋ฆฟ ์กฐ๊ฐ, ํ…œํ”Œ๋ฆฟ ๋ ˆ์ด์•„์›ƒ
Study Repository

Thymeleaf ๊ธฐ๋Šฅ - ํ…œํ”Œ๋ฆฟ ์กฐ๊ฐ, ํ…œํ”Œ๋ฆฟ ๋ ˆ์ด์•„์›ƒ

by rlaehddnd0422

์›น ํŽ˜์ด์ง€๋ฅผ ๊ฐœ๋ฐœํ•  ๋•Œ๋Š” ๊ณตํ†ต ์˜์—ญ์ด ๋งŽ์ด ์žˆ์Šต๋‹ˆ๋‹ค. 

์˜ˆ๋ฅผ๋“ค์–ด์„œ ์›นํŽ˜์ด์ง€์˜ ์ƒ๋‹จ ์˜์—ญ์ด๋‚˜ ํ•˜๋‹จ ์˜์—ญ, ์ขŒ์ธก ์นดํ…Œ๊ณ ๋ฆฌ ๋“ฑ๋“ฑ ์—ฌ๋Ÿฌ ํŽ˜์ด์ง€์—์„œ ๊ณตํ†ต์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ์˜์—ญ๋“ค์ด ์žˆ์–ด์š”.

์ด๋Ÿฐ ๋ถ€๋ถ„์„ ์ฝ”๋“œ๋ฅผ ๋ณต์‚ฌํ•ด์„œ ์‚ฌ์šฉํ•œ๋‹ค๋ฉด ๋ณ€๊ฒฝ์‹œ ์—ฌ๋Ÿฌ ํŽ˜์ด์ง€๋ฅผ ๋‹ค ์ˆ˜์ •ํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ƒ๋‹นํžˆ ๋น„ํšจ์œจ์ ์ž…๋‹ˆ๋‹ค. ํƒ€์ž„๋ฆฌํ”„๋Š” ์ด๋Ÿฐ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ํ…œํ”Œ๋ฆฟ ์กฐ๊ฐ๊ณผ ๋ ˆ์ด์•„์›ƒ ๊ธฐ๋Šฅ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

 

ํ…œํ”Œ๋ฆฟ ์กฐ๊ฐ

@Controller
@RequestMapping("/template")
public class TemplateController {

    @GetMapping("/fragment")
    public String template()
    {
        return "template/fragment/fragmentMain";
    }

 

footer.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<body>

<footer th:fragment="copy">
    ํ‘ธํ„ฐ ์ž๋ฆฌ ์ž…๋‹ˆ๋‹ค.
</footer>

<footer th:fragment="copyParam (param1, param2)">
    <p>ํŒŒ๋ผ๋ฏธํ„ฐ ์ž๋ฆฌ ์ž…๋‹ˆ๋‹ค.</p>
    <p th:text="${param1}"></p> <p th:text="${param2}"></p>
</footer>

</body>
</html>

 

fragmentMain.html


<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
  <meta charset="UTF-8">
  <title>Title</title>
</head>
  <body>
  <h1>๋ถ€๋ถ„ ํฌํ•จ</h1>
    <h2>๋ถ€๋ถ„ ํฌํ•จ insert</h2>
    <div th:insert="~{template/fragment/footer :: copy}"></div>
    <h2>๋ถ€๋ถ„ ํฌํ•จ replace</h2>
    <div th:replace="~{template/fragment/footer :: copy}"></div>
    <h2>๋ถ€๋ถ„ ํฌํ•จ ๋‹จ์ˆœ ํ‘œํ˜„์‹</h2>
    <div th:replace="template/fragment/footer :: copy"></div>
    <h1>ํŒŒ๋ผ๋ฏธํ„ฐ ์‚ฌ์šฉ</h1>

    <div th:insert="~{template/fragment/footer :: copyParam ('์นด์นด', '๋ผ๋ชจ์Šค')}">ํ•˜์ด์š”</div>
    <div th:replace="~{template/fragment/footer :: copyParam ('๋ฐ์ดํ„ฐ1', '๋ฐ์ดํ„ฐ 2')}"></div>
  </body>
</html>

 

th:fragment๊ฐ€ ์žˆ๋Š” ํƒœ๊ทธ๋Š” ๋‹ค๋ฅธ ๊ณณ์— ํฌํ•จ๋˜๋Š” ์ฝ”๋“œ ์กฐ๊ฐ์œผ๋กœ ์ดํ•ดํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

 

  • th:insert="~{.../footer :: copy}
    • footer.html์˜ th:fragment="copy" ๋กœ ์ง€์ •๋œ ๋ถ€๋ถ„์„ ํ˜„์žฌ ํƒœ๊ทธ๋ฅผ ํฌํ•จํ•ด์„œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • th.replce = "~{.../footer :: copy}
    • footer.html์˜ th:fragmet="copy" ๋กœ ์ง€์ •๋œ ๋ถ€๋ถ„์„ ํ˜„์žฌ ํƒœ๊ทธ๋ฅผ ๋Œ€์ฒดํ•ด์„œ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ( ์œ„ ๊ฒฝ์šฐ <div> </div> ๊ฐ€  <footer> </footer> ๋กœ ๋Œ€์ฒด )
  • ๋ถ€๋ถ„ ํฌํ•จ ๋‹จ์ˆœ ํ‘œํ˜„์‹
    • <div th:replace="template/fragment/footer :: copy"></div>
      • ~์„ ์‚ฌ์šฉํ•˜๋Š”๊ฒŒ ์›์น™์ด์ง€๋งŒ ํ…œํ”Œ๋ฆฟ ์กฐ๊ฐ์„ ์‚ฌ์šฉํ•˜๋Š” ์ฝ”๋“œ๊ฐ€ ๋‹จ์ˆœํ•˜๋ฉด ~์„ ์ƒ๋žตํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ํŒŒ๋ผ๋ฏธํ„ฐ ์‚ฌ์šฉ
    • <div th:insert(replace) = "~{template/fragment/footer :: copyParam('๋ฐ์ดํ„ฐ1','๋ฐ์ดํ„ฐ2')}"></div>
      • ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํŒŒ๋ผ๋ฏธํ„ฐ ๋˜ํ•œ ๋ Œ๋”๋งํ•ด์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
<footer th:fragment="copyParam (param1, param2)">
    <p>ํŒŒ๋ผ๋ฏธํ„ฐ ์ž๋ฆฌ ์ž…๋‹ˆ๋‹ค.</p>
    <p th:text="${param1}"></p> <p th:text="${param2}"></p>
</footer>

โŒƒ footer.html

 

์ตœ์ข… ๋ทฐ ํ…œํ”Œ๋ฆฟ ์†Œ์Šค์ฝ”๋“œ

๋ทฐํ…œํ”Œ๋ฆฟ ์ฝ”๋“œ


ํ…œํ”Œ๋ฆฟ ๋ ˆ์ด์•„์›ƒ

์ด์ „์—๋Š” ์ผ๋ถ€ ์ฝ”๋“œ ์กฐ๊ฐ์„ ๊ฐ€์ง€๊ณ  ์™€์„œ ์‚ฌ์šฉํ–ˆ๋‹ค๋ฉด, ์ด๋ฒˆ์—๋Š” ๊ฐœ๋…์„ ๋” ํ™•์žฅํ•ด์„œ ์ฝ”๋“œ ์กฐ๊ฐ์„ ๋ ˆ์ด์•„์›ƒ์— ๋„˜๊ฒจ์„œ ์‚ฌ์šฉํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

 

์˜ˆ๋ฅผ ๋“ค์–ด <head> ์— ๊ณตํ†ต์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” css, javascript ๊ฐ™์€ ์ •๋ณด๋“ค์ด ์žˆ๋Š”๋ฐ, ์ด๋Ÿฌํ•œ ๊ณตํ†ต์ •๋ณด๋“ค์„ ํ•œ ๊ณณ์— ๋ชจ์•„๋‘๊ณ  ๊ณตํ†ต์œผ๋กœ ์‚ฌ์šฉํ•˜์ง€๋งŒ, ๊ฐ ํŽ˜์ด์ง€๋งˆ๋‹ค ํ•„์š”ํ•œ ์ •๋ณด๋ฅผ ๋” ์ถ”๊ฐ€ํ•ด์„œ ์‚ฌ์šฉํ•˜๊ณ  ์‹ถ๋‹ค๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์‚ฌ์šฉํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

 

@GetMapping("/layout")
public String layout()
{
    return "template/layout/layoutMain";
}

 

base.html

<html xmlns:th="http://www.thymeleaf.org">
<head th:fragment="common_header(title,links)">

    <title th:replace="${title}">๋ ˆ์ด์•„์›ƒ ํƒ€์ดํ‹€</title>

    <!-- ๊ณตํ†ต -->
    <link rel="stylesheet" type="text/css" media="all" th:href="@{/css/awesomeapp.css}">
    <link rel="shortcut icon" th:href="@{/images/favicon.ico}">
    <script type="text/javascript" th:src="@{/sh/scripts/codebase.js}"></script>

    <!-- ์ถ”๊ฐ€ -->
    <th:block th:replace="${links}" />
</head>

 

layoutMain.html

<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head th:replace="template/layout/base :: common_header(~{::title},~{::link})">
  <title>๋ฉ”์ธ ํƒ€์ดํ‹€</title>
  <link rel="stylesheet" th:href="@{/css/bootstrap.min.css}">
  <link rel="stylesheet" th:href="@{/themes/smoothness/jquery-ui.css}">
</head>
  <body>
  ๋ฉ”์ธ ์ปจํ…์ธ 
  </body>
</html>

common_header(~{::title},~{::link}) ์ด ๋ถ€๋ถ„์ด ํ•ต์‹ฌ์ž…๋‹ˆ๋‹ค.

  • ::title์€ ํ˜„์žฌ ํŽ˜์ด์ง€์˜ title ํƒœ๊ทธ๋“ค์„ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.
  • ::link๋Š” ํ˜„์žฌ ํŽ˜์ด์ง€์˜ link ํƒœ๊ทธ๋“ค์„ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค.

1. layoutMain ๋ทฐ ํ…œํ”Œ๋ฆฟ์— head๋ถ€๋ถ„์ด base.html์˜ common_header์˜ ํƒ€์ดํ‹€๊ณผ ๋งํฌ๋กœ ๋Œ€์ฒด๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

๋”ฐ๋ผ์„œ <title>์ด ๋ถ™์€ ๋ฉ”์ธ ํƒ€์ดํ‹€ ์ž๋ฆฌ์— base์˜ ๋ ˆ์ด์•„์›ƒ ํƒ€์ดํ‹€์ด ๋“ค์–ด๊ฐ€๊ณ  <link> ๊ฐ€ ๋ถ™์€ ๋ถ€๋ถ„์—๋Š” base์˜ ๊ณตํ†ต ์ฃผ์„ ๋งํฌ๊ฐ€ ๋“ค์–ด๊ฐ‘๋‹ˆ๋‹ค.

 

์†Œ์Šค์ฝ”๋“œ๋ฅผ ๋ณด๋ฉด

1. layoutMain์„ ํ˜ธ์ถœํ–ˆ๋”๋‹ˆ template/layout/base ์˜ common_header์˜ title๊ณผ link๋ฅผ ์ „๋‹ฌํ•ด์ฃผ๊ณ  ๋ฆฌํ„ด๋œ ๊ฒฐ๊ณผ๋ฅผ <head> ํƒœ๊ทธ์— ์‚ฌ์šฉํ•œ๋‹ค๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

2. ๋„˜๊ฒจ ์ฃผ๋ฉด "๋ ˆ์ด์•„์›ƒ ํƒ€์ดํ‹€" -> "๋ฉ”์ธ ํƒ€์ดํ‹€" ๋กœ ๋ณ€๊ฒฝ๋˜๊ณ  ์ค‘๊ฐ„์˜ ๊ณตํ†ต ๋ถ€๋ถ„์€ ๊ทธ๋Œ€๋กœ, links๋กœ ์ „๋‹ฌ๋ฐ›์€ ๋ถ€๋ถ„์€ link๋กœ ์ „๋‹ฌ๋œ ๋ถ€๋ถ„์œผ๋กœ ๋Œ€์ฒด๋œ ๊ฒฐ๊ณผ๊ฐ€ layoutMain์˜ head ํƒœ๊ทธ์—์„œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

 

 

์ด๋ฒˆ์—๋Š” <head> ์—์„œ <html>๊นŒ์ง€ ํ™•์žฅํ•ด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค.

@GetMapping("/layoutExtend")
public String layoutExtends()
{
    return "template/layoutExtend/layoutExtendMain";
}

layoutExtendMain.html

<!DOCTYPE html>
<html th:replace="~{template/layoutExtend/layoutFile :: layout(~{::title}, ~{::section})}"
      xmlns:th="http://www.thymeleaf.org">
<head>
    <title>๋ฉ”์ธ ํŽ˜์ด์ง€ ํƒ€์ดํ‹€</title> </head>
<body>
<section>
    <p>๋ฉ”์ธ ํŽ˜์ด์ง€ ์ปจํ…์ธ </p>
    <div>๋ฉ”์ธ ํŽ˜์ด์ง€ ํฌํ•จ ๋‚ด์šฉ</div>
</section>
</body>
</html>

 

layoutFile.html

<!DOCTYPE html>
<html th:fragment="layout (title, content)" xmlns:th="http://www.thymeleaf.org">
<head>
  <title th:replace="${title}">๋ ˆ์ด์•„์›ƒ ํƒ€์ดํ‹€</title> </head>
<body>
<h1>๋ ˆ์ด์•„์›ƒ H1</h1>
<div th:replace="${content}"> <p>๋ ˆ์ด์•„์›ƒ ์ปจํ…์ธ </p>
</div>
<footer>
  ๋ ˆ์ด์•„์›ƒ ํ‘ธํ„ฐ
</footer>
</body>
</html>

 

๋™์ž‘ ์›๋ฆฌ

1. <html> ๋ ˆ๋ฒจ์—์„œ ๋‚ด๋ถ€ title๊ณผ sectionํƒœ๊ทธ๋ฅผ layoutfile์— ์ „๋‹ฌํ•ด์ค๋‹ˆ๋‹ค. 

2. ์ „๋‹ฌ๋ฐ›์€ layoutFile์˜ title, content ํƒœ๊ทธ๋ฅผ ์ „๋‹ฌ๋ฐ›์€ title๊ณผ sectionํƒœ๊ทธ๋กœ ๋ณ€๊ฒฝํ•ด์ค๋‹ˆ๋‹ค.

3. <html> ๋ ˆ๋ฒจ์„ ๋‹ค์‹œ layoutExtendMain์— ์ „๋‹ฌํ•ด์ค๋‹ˆ๋‹ค.

 

๋ทฐํ…œํ”Œ๋ฆฟ ์†Œ์Šค์ฝ”๋“œ

๋ธ”๋กœ๊ทธ์˜ ์ •๋ณด

Study Repository

rlaehddnd0422

ํ™œ๋™ํ•˜๊ธฐ