티스토리 뷰

반응형
Template Layout

이전 글에서 작은 개념인 Template Fragments(템플릿 조각)에 대하여 살펴보았다

이번 글에서는 이를 확장한 개념인 템플릿 레이아웃에 대하여 살펴보고자 한다

템플릿 레이아웃은 단순히 하나하나의 조각이 아니라 <head> 같은 한 파트를 통째로 가져와 사용할 수 있게 해 준다

더 나아가서는 html 전체를 하나의 규격화된 템플릿으로 사용할 수 있게 해 준다

 

Flexible Layouts : beyond mere fragment insertion (유연한 레이아웃 템플릿)

레이아웃의 틀이 될 html 파일부터 만들어보자

<!-- /resources/templates/template/layout/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>

레이아웃을 적용시킬 html 파일을 살펴보자

<!--  /resources/templates/template/layout/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>

위와 같이 레이아웃을 적용시키게 되면 아래와 같은 결과가 나온다

<!DOCTYPE html>
<html>
<head>
    <title>메인 타이틀</title>
    <!-- 공통 -->
    <link rel="stylesheet" type="text/css" media="all" href="/css/awesomeapp.css">
    <link rel="shortcut icon" href="/images/favicon.ico">
    <script type="text/javascript" src="/sh/scripts/codebase.js"></script>
    
    <!-- 추가 -->
    <link rel="stylesheet" href="/css/bootstrap.min.css">
    <link rel="stylesheet" href="/themes/smoothness/jquery-ui.css">
</head>
<body> 
메인 컨텐츠
</body>
</html>

기존 레이아웃 틀에서 th:replace라고 작성했던 부분은 common_header(~{::title},~{::link})에 따라서 레이아웃이 적용되는 html에 있던 title과 links가 th:replace로 선언한 부분만 대체되지 않고 유지되었다

<!-- Layout Inheritance -->

<!-- 기존 레이아웃 틀 -->
<head th:fragment="common_header(title,links)"> 

    <title th:replace="${title}">레이아웃 타이틀</title>
    <!-- 레이아웃 적용 후에도 유지 -->
    <title>메인 타이틀</title>

    <th:block th:replace="${links}" />
    <!-- 레이아웃 적용 후에도 유지 -->
    <link rel="stylesheet" th:href="@{/css/bootstrap.min.css}">
    <link rel="stylesheet" th:href="@{/themes/smoothness/jquery-ui.css}">

<!-- 레이아웃 적용하는 html -->
<head th:replace="template/layout/base :: common_header(~{::title},~{::link})">

즉 공통부분은 그대로 유지되고, 추가 부분에 전달한 <link>들이 포함된 것을 확인할 수 있다, 공식 문서에는 상속이 된다고 표현한다

 

<head>만 적용했던 위의 예시에서 더 나아가 <html> 전체에 적용할 수도 있다

<!-- /resources/templates/template/layoutExtend/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>

위의 레이아웃을 아래의 html에 적용(공식 문서 표현은 Inheritence)시켜보겠다

<!-- /resources/templates/template/layoutExtend/layoutExtendMain.html -->
<!-- 레이아웃을 적용시킬 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>

레이아웃 틀의 th:fragment로 정의되었던 title과 content를 유지하고 레이아웃 틀의 내용으로 바뀐 것을 아래와 같이 확인할 수 있다

<!-- 결과 -->

<!DOCTYPE html>
<html>
<head>
    <title>메인 페이지 타이틀</title>
</head>
<body>
    <h1>레이아웃 H1</h1>
    <section>
    <p>메인 페이지 컨텐츠</p>
    <div>메인 페이지 포함 내용</div>
    </section>
<footer>
레이아웃 푸터
</footer>
</body>
</html>

즉 레이아웃 틀로 적용하되 상속받는 html 파일의 필요한 요소들만 가져다가 레이아웃에 적용된 것이다

 

핵심정리

템플릿 레이아웃을 사용하여 공통된 부분뿐만 아니라 전체 html을 규격화하여 필요한 부분들만 적용시킬 수 있다

 

더보기

개인 학습을 위해 작성되는 글입니다.

제가 잘못 알고 있는 점에 대한 지적 / 더 나은 방향에 대한 댓글을 환영합니다.

 

참조 링크:

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

https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html

 

반응형
댓글