본문 바로가기

국비필기노트/Spring

spring_thymleaf[3](block, 자바스크립트-inline,fragment)

블록

 

 

*BasicContainer.java

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package com.koreait.thymeleaf;
 
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
import javax.servlet.http.HttpSession;
 
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
 
import com.koreait.thymeleaf.data.User;
 
@Controller
@RequestMapping("/basic")
public class BasicController {
 
    @GetMapping("/block")
    public String block(Model model){
        
        addUsers(model);    
        
        return "basic/block";
    }
    
    
}
 
cs

 

 

 

*block.html

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
    <th:block th:each="user : ${users}">
        <div>
            사용자 이름 <span th:text="${user.username}"></span>
            사용자 나이 <span th:text="${user.age}"></span>
        </div>
        <div>
            요약 <span th:text="${user.username} + '/' + ${user.age}"></span>
        </div>
    </th:block>    
</body>
</html>
cs

 

 

타임리프는 태그 안에서만 작동하는데 html 태그로 이를 묶어주기 애매한 경우가 있다. 이 때 <th:block>을 사용한다.  

<th:block>은 HTML태그가 아닌 타임리프 자체 태그로서 HTML에선 인식되지않는다.

 

 

 

자바스크립트 인라인

 

 

*javascript.html

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
    <script>
    let username = "[[${user.username}]]";
    let username = [[${user.username}]];
    let age = [[${user.age}]];
    
    //자바스크립트 내추럴 탬플릿
    let username2 = /* [[${user.username}]]*/ "test username";
    
    //객체
    //let user = [[${user}]];
    
    </script>
    
    <script th:inline="javascript">
    let username_th = [[${user.username}]];
    let age_th = [[${user.age}]];
    
    //자바스크립트 내추럴 탬플릿
    let username2_th = /* [[${user.username}]]*/ "test username";
    
    //객체
    let user = [[${user}]];
    </script>
    
    
    <script th:inline="javascript">
       [# th:each="user, stat : ${users}"]
          let user[[${stat.count}]] = [[${user}]];
       [/]
   </script>
   
</body>
</html>
cs

 

 

*BasicController.java

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package com.koreait.thymeleaf;
 
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
import javax.servlet.http.HttpSession;
 
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
 
import com.koreait.thymeleaf.data.User;
 
@Controller
@RequestMapping("/basic")
public class BasicController {
    
    
    @GetMapping("/javascript")
    public String javascript(Model model){
        
        
        model.addAttribute("user",new User("userA",20));
        addUsers(model);
        
        return "basic/javascript";
    }
    
    
}
 
cs

 

 

타임리프는 자바스크립트에서 타임리프를 편리하게 사용할 수 있는 자바스크립트 인라인 기능을 제공한다.

 

 

  • 초록박스: script구문과 출력문을 구분시켜줌
  • 빨간박스: 일반 script에서는 " "를 넣고 출력해야만 데이터에 "userA"라는 값이 담기지만 inline태그안에서는 " "없이도 "userA"라는 값이 정상출력됨
  • 파란박스: 일반 script구문에서는 객체를 출력하면 객체의 주소값이 나오지만 inline 태그 안에서는 list안의 객체가 가독성있게 출력됨
  • 마지막 초록색박스: javascript inline태그를 활용한 반복문

 

 

fragment

 

 

*TemplateController.java

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
package com.koreait.thymeleaf.basic;
 
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
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";
    }
    
    @GetMapping("/layout")
    public String layout(){
        
 
        return "template/layout/layoutMain";
    }
}
 
cs



*fragmentMain.html

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</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>
    
    <hr>
    
    <h1>파라미터 사용</h1>
    <div th:replace="~{template/fragment/footer :: copyParam('파람1','파람2')}"></div>
 
</html>
cs

 

 

*footer.html

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
</head>
<body>
    <footer th:fragment="copy">
        footer자리입니다.
    </footer>
    
    <footer th:fragment="copyParam(param1,param2)">
        <p>파라미터 자리입니다</p>
        <p th:text="${param1}"></p>
        <p th:text="${param2}"></p>
    </footer>
</body>
</html>    
        
cs

 

 

*layoutMain.html

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head th:replace="template/layout/base :: common_header( ~{::title},~{::link})"> 
    
    <meta charset="UTF-8">
    <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>
cs

 

 

*base.html

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<!DOCTYPE html>
<html xmlns:th="http://www.thymeleaf.org">
<head th:fragment="common_header(title, links)">
    <meta charset="UTF-8">
    <!-- title을 바꿀수 있도록 허용 -->
    <title th:replace="${title}">레이아웃 타이틀</title>
    
    <!-- 공통 -->
    <link rel="stylesheet" type="text/css" th:href="@{/css/wesomapp.css}">
    <link rel="shortcut icon" th:href="@{/imges/favicon.icon}">
    <script type="text/javascript" th:src="@{/sh/scripts/codebase.js}"></script>
    
    <!-- 추가 -->
    <!-- 추가 link를 바꿀수 있도록 허용 -->
    <th:block th:replace="${links}"/>
    
</head>
<body>
 
</body>
</html>
cs

 

point1. fragment의 일반 사용법

 

 

빨간색은 부분포함 파트 하늘색은 파라미터 사용 파트이다. 

fragment에서 중점으로 봐야할 것은 출력문이 아니라 크롬에서나타나는 소스코드인데  부분포함부터 보자면 insert, replace, 단순표현식 이렇게 나누어질 수 있다.

 

insert는 소스코드를 보면 <footer>태그가 <div> 태그 안에  들어가는 것을 확인할 수 있다. 즉, 현재 태그 내부에 추가하는 것이고 replace는 <div> 태그가 없어지고 <footer>로 완전 교체(대체) 됨으로서 현재 태그를 대체한다는 의미이다.

부붐표현 단순표현식을 이용하면 ~{}를 삭제하고 단순 " "로만 경로를 나타낼 수 도 있다. 

 

파란색 파라미터 사용 파트를 보면 fragMain.hml에서 footer.html로 파라미터를 넘겨주었으며 이를 repalce로 대체하여 copyParam을 사용함으로서 소스코드에는 넘겨준 파라미터값이 정상적으로 출력되게된다.

 

point2. 공통 코드 묶기

 

 

 

 

base.html은 공통적으로 들어가는 여러코드들을 모아두는 html이지만 어떤 클래스는 공통 클래스뿐만아니라 추가해야할 link가 있을 수도 있고 타이틀이 변경될 수도 있다. 

 

초록박스

base.html의 타이틀은 레이아웃 타이틀이다. 그러나 layoutMain.html로 들어가게되면 레아이웃이 아닌 메인타이틀로 타이틀명이 변경되어야하며 이를 위해 layoutMain.html위에 layoutMain의 타이틀을 common_header로 넘겨주는 코드를 작성하였다. base.html역시 이를 <head fragment="common_header(title,links)>로 받아 base.html의 타이틀인 메인 타이틀이 정상 출력 되는 것이다. 

 

분홍박스

공통으로 입력되는 link들로서 layoutMain.html에 재입력하지않아도 소스코드에선 출력되어있는 것을 확인할 수 있다.

 

보라색박스

공통link뿐만아니라 layoutMain.html만의 추가link를 base.html에 더해 소스코드에 출력시켜준다.

 

 

 link가 넘어가는 원리는 초록박스인 base.html과 동일하며 layout.html에 넘겨준 link를 base.html에서 받고 이를 <!--추가-->부분의 links에서 받아 추가링크가 소스코드에 정상적으로 출력되는 것이다.