ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [김영한 스프링] 09. 타임리프 기본 기능 - 템플릿 조각 & 템플릿 레이아웃
    Spring/스프링 MVC 2편 - 백엔드 웹 개발 활용 기술 2023. 8. 12. 00:45

    템플릿 조각

     

    웹 페이지를 개발할 때는 공통 영역이 많이 있다. 예를 들어서 상단 영역이나 하단 영역, 좌측 카테고리 등등 여러 페이지에서 함께 사용하는 영역들이 있다. 이런 부분을 코드를 복사해서 사용한다면 변경 시 여러 페이지를 다 수정해야 하므로 상당히 비효율 적이다. 타임리프는 이런 문제를 해결하기 위해 템플릿 조각과 레이아웃 기능을 지원한다.

     

     

    TemplateController

    package hello.thymeleaf.basic;
    
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.GetMapping;
    import org.springframework.web.bind.annotation.RequestMapping;
    
    @Controller
    @RequestMapping("/template")
    public class TemplateController {
    
        @GetMapping("/fragment")
        public String template() {
            
            return "template/fragment/fragmentMain";
        }
    }

    main/java/hello/thymeleaf/basic/TemplateController 생성

     

     

    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>

    main/resources/templates/template/fragment/footer.html 생성

     

    th:fragment가 있는 태그는 다른곳에 포함되는 코드 조각으로 이해하면 된다.

     

     

    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:replace="~{template/fragment/footer :: copyParam ('데이터1', '데이터2')}"></div>
    
    </body>
    </html>

    main/resources/templates/template/fragment/fragmentMain.html 생성

     

    • template/fragment/footer :: copy : template/fragment/footer.html 템플릿에 있는 th:fragment="copy"라는 부분을 템플릿 조각으로 가져와서 사용한다는 의미이다.

     

    footer.html의 copy 부분

    <footer th:fragment="copy">
        푸터 자리 입니다.
    </footer>

     

    부분 포함 insert

    <div th:insert="~{template/fragment/footer :: copy}"></div>

    <h2>부분 포함 insert</h2>
    <div>
    <footer>
        푸터 자리 입니다.
    </footer>
    </div>

    th:insert를 사용하면 현재 태그(div) 내부에 추가한다.

     

    부분 포함 replace

    <div th:replace="~{template/fragment/footer :: copy}"></div>

    <h2>부분 포함 replace</h2>
    <footer>
        푸터 자리 입니다.
    </footer>

    th:replace를 사용하면 현재 태그(div)를 대체한다.

     

    부분 포함 단순 표현식

    <div th:replace="template/fragment/footer :: copy"></div>

    <h2>부분 포함 단순 표현식</h2>
    <footer>
        푸터 자리 입니다.
    </footer>

    ~{...}를 사용하는 것이 원칙이지만 템플릿 조각을 사용하는 코드가 단순하면 이 부분을 생략할 수 있다.

     

    파라미터 사용

    다음과 같이 파라미터를 전달해서 동적으로 조각을 렌더링 할 수도 있다.

    <div th:replace="~{template/fragment/footer :: copyParam ('데이터1', '데이터2')}"></div>

    <h1>파라미터 사용</h1>
    <footer>
        <p>파라미터 자리 입니다.</p>
        <p>데이터1</p>
        <p>데이터2</p>
    </footer>

     

    footer.html의 copyParam 부분

    <footer th:fragment="copyParam (param1, param2)">
        <p>파라미터 자리 입니다.</p>
        <p th:text="${param1}"></p>
        <p th:text="${param2}"></p>
    </footer>

     

     

    실행

     

     

    템플릿 레이아웃1

     

    예를 들어서 <head>에 공통으로 사용하는 css, javascript같은 정보들이 있는데, 이러한 공통 정보들을 한 곳에 모아두고, 공통으로 사용하지만, 각 페이지마다 필요한 정보를 더 추가해서 사용하고 싶다면 다음과 같이 사용하면 된다.

     

     

    TemplateController

        @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>

    main/resources/templates/template/layout/base.html 생성

     

     

    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>

    main/resources/templates/template/layout/layoutMain.html 생성

     

    • common_header(~{::title},~{::link})이 부분이 핵심이다.
      • ::title은 현재 페이지의 title 태그들을 전달한다.
      • ::link는 현재 페이지의 link 태그들을 전달한다.

     

     

     

    실행

    • 메인 타이틀이 전달한 부분으로 교체되었다.
    • 공통 부분은 그대로 유지되고, 추가 부분에 전달한 <link>들이 포함된 것을 확인할 수 있다.

     

    이 방식은 사실 앞서 배운 코드 조각을 조금 더 적극적으로 사용하는 방식이다. 쉽게 이야기해서 레이아웃 개념을 두고, 그 레이아웃에 필요한 코드 조각을 전달해서 완성하는 것으로 이해하면 된다.

     

     

    템플릿 레이아웃2

     

    템플릿 레이아웃 확장

    앞서 이야기한 개념을 <head>정도에만 적용하는 것이 아니라 <html>전체에 적용할 수도 있다.

     

     

    TemplateController

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

     

     

    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>

    main/resources/templates/template/layoutExtend/layoutFile.html 생성

     

    기본 레이아웃을 가지고 있는데, <html>에 th:fragment 속성이 정의되어 있다. 이 레이아웃 파일을 기본으로 하고 여기에 필요한 내용을 전달해서 부분부분 변경하는 것으로 이해하면 된다.

     

     

    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>

    main/resources/templates/template/layoutExtend/layoutExtendMain.html 생성

     

    현재 페이지인데, <html> 자체를 th:replace를 사용해서 변경하는 것을 확인할 수 있다. 결국 layoutFile.html에 필요한 내용을 전달하면서 <html> 자체를 layoutFile.html로 변경한다.

     

     

    실행

     

     

    출처 : https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-mvc-2

     

    스프링 MVC 2편 - 백엔드 웹 개발 활용 기술 - 인프런 | 강의

    웹 애플리케이션 개발에 필요한 모든 웹 기술을 기초부터 이해하고, 완성할 수 있습니다. MVC 2편에서는 MVC 1편의 핵심 원리와 구조 위에 실무 웹 개발에 필요한 모든 활용 기술들을 학습할 수 있

    www.inflearn.com

Designed by Tistory.