본문 바로가기

웹 프로그래밍/프론트 엔드

Thymeleaf(타임리프) 기본

텍스트 출력- th:text, th:utext

컨텐츠 안에서 직접 출력하기 = [[${data}]]

 

HTML 엔티티

'<' 나 '>' 같은것을 그대로 표현하기위함

HTML 엔티티로 변경하는것을 이스케이프라 하고 타임리프의 th:text나 [[...]] 은 디폴트로 제공

이스케이프 하지 않는법(unescape)

th:text -> th:utext

[[...]] -> [(...)]

 

변수-SpringEL

 

-Object 접근

${user.username} = userA

${user['username']} = userA

${user.getUsername()} = userA

 

-List

${users[0].username} = userA

${users[0]['username']} = userA

${users[0].getUsername()} = userA

 

-Map

${userMap['userA'].username} =userA

${userMap['userA']['username']} = userA

${userMap['userA'].getUsername()} = userA

 

지역변수 선언-th:with

<div th:with="first=${users[0]}">
    <p>처음 사람의 이름은 <span th:text="${first.username}"></span></p>
</div>

변수를 객체처럼 사용이 가능

선언한 태그 스코프 안에서만 유효

 

기본 객체들

th:text="${#request}"
th:text="${#response}"
th:text="${#session}"
th:text="${#servletContext}"
th:text="${#locale}"

 

편의 객체

요청 파라미터 접근 -> th:text="${param.paramData}"
HTTP 세선 접근 -> th:text="${session.sessionData}"
스프링 빈 접근(메서드 사용 가능) -> th:text="${@helloBean.hello('Spring!')}"

 

타임리프 유틸리티 객체

#message: 메시지, 국제화 처리

#uris: URI 이스케이프 지원

#dates: java.util.Date 서식 지원

#calenders: java.util.Calendar 서식 지원

#temporals: 자바8 날짜 서식 지원

th:text="${#temporals.format(localDateTime,'yyyy-MM-dd HH:mm:ss')}"

 

#numbers: 숫자 서식 지원

#strings: 문자 관련 기능 제공

#objects: 객체 관련 기능 제공

#bool: boolean 관련 기능 제공

#arrays: 배열 관련 기능 제공

#list, #sets, #maps: 컬렉션 관련 기능 제공

#ids: 아이디 처리 관련 기능 제공

기타 등등 홈페이지에서 예제로 찾아 볼것

 

URL 링크

    <li><a th:href="@{/hello}">basic url</a></li>
    <li><a th:href="@{/hello(param1=${param1}, param2=${param2})}">hello query param</a></li>
    <li><a th:href="@{/hello/{param1}/{param2}(param1=${param1}, param2=${param2})}">path variable</a></li>
    <li><a th:href="@{/hello/{param1}(param1=${param1}, param2=${param2})}">path variable + query parameter</a>

 

위 차이를 설명할수 있어야함

 

리터럴

소스코드상에서 고정된 값(문자, 숫자)

문자 리터럴은 항상 작은 따옴표를 써야한다

이어져 있으면 의미있는 토큰으로 인지를 하나 hello world 같이 공백이 있으면 작은따옴표로 감싸야 한다

 

연산

             <li>1 > 10 = <span th:text="1 &gt; 10"></span></li>
            <li>1 gt 10 = <span th:text="1 gt 10"></span></li>
            <li>1 >= 10 = <span th:text="1 >= 10"></span></li>
            <li>1 ge 10 = <span th:text="1 ge 10"></span></li>
            <li>1 == 10 = <span th:text="1 == 10"></span></li>
            <li>1 != 10 = <span th:text="1 != 10"></span></li>

-> true or false 반환(HTTP 엔티티만 조심 -> gt,lt)

 

 th:text="(10 % 2 == 0)?'짝수':'홀수'"

-> 삼항 연산

th:text="${data}?: '데이터가없습니다.'"

-> 엘비스 연산(삼항연산 축약 데이터 있으면 데이터 그대로 출력)

<span th:text="${data}?: _">

-> No Operation 연산(데이터 있으면 출력 없으면 이 태그 타임리프 아예 동작 안하게끔)

 

속성값 설정

th:* 로 속성을 적용하면 기존속성을 대체함, 기존 속성이 없으면 새로 만든다.

- th:classappend = <input type="text" class="text" th:classappend="large" /><br/>

-> 렌더링 될때 클래스 이름이 text large 이렇게 바뀜

th:checked="false" -> 체크 박스 체크 표시해제 해줌(원래 HTML는 checked면 무조건 체크 됨)

 

반복(th:each)

th:each="user : ${users}"

-> 리스트 users의 객체가 하나씩 user에 담기고 반복

th:each="user, userStat : ${users}"

-> 첫번째는 반복 두번째에 타임리프 변수가 오면 각종 상태를 담은 객체로 만들어줌

userStat.index: 0부터 숫자셈

userStat.count: 1부터 숫자셈

userStat.size: 전체 사이즈

userStat.even, userStat.odd: 홀짝 여부(boolean)

userStat.first, userStat.last: 처음 마지막 여부(boolean)

userStat.current: 현재 객체

 

조건문 평가(th:if, th:unless, th:switch)

조건에 맞으면 태그 실행 안맞으면 태그 무시

<span th:text="'미성년자'" th:if="${user.age lt 20}"></span>

        

switch 구문에서 th:case="*" 은 디폴트로 아무것도 걸리지 않았을때 걸린다.

        <td th:switch="${user.age}">
            <span th:case="10">10살</span>
            <span th:case="20">20살</span>
            <span th:case="*">기타</span>
        </td>

 

주석

1.표준 html 주석

<!--
<span th:text="${data}">html data</span>
-->

 

2.타임리프 파서 주석

<!--/* [[${data}]] */-->

 

<!--/*-->
<span th:text="${data}">html data</span>
<!--*/-->

 

블록(th:block): 거의 유일하게 속성대체가 아니라 태그처럼 사용됨

<th:block th:each="user : ${users}">
    <div>
        사용자 이름1 <span th:text="${user.username}"></span>
        사용자 나이1 <span th:text="${user.age}"></span>
    </div>
    <div>
        요약 <span th:text="${user.username} + ' / ' + ${user.age}"></span>
    </div>
</th:block>

-> div 두개를 묶어서 반복을 하고 싶을때(렌더링시 제거)

 

자바스크립트 인라인(th:inline)

자바스크립트 안에서 타임리프가 기능을 지원

 

<script th:inline="javascript">

    var username = [[${user.username}]];

    -> " "(문자열) 처리 알아서 해줌
    var age = [[${user.age}]];
    //자바스크립트 내추럴 템플릿
    var username2 = /*[[${user.username}]]*/ "test username";

    -> 주석 부분이 렌더링시 대입됨
    //객체
    var user = [[${user}]];

    -> json형식으로 바껴서 대입됨

</script>

 

each 문법 지원

 

<script th:inline="javascript">
    추가[# th:each="user, stat : ${users}"]
    var user[[${stat.count}]] = [[${user}]];
    [/]
</script>

 

템플릿 조각(~{...})

내가 만든 공통영역(상단, 하단)을 재사용할수 있는 템플릿 조각 지원

 

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

-> insert는 원래(div) 태그 속에 넣음


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

-> replace는 태그(div) 갈아 끼움

 

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

-> 파라미터 사용 가능

 

템플릿 레이아웃

코드조각을 불러오는것만이 아니라 전체 큰그림인 레인아웃에 코드조각을 레이아웃에 넘겨서 사용하는 방법

<head th:replace="template/layout/base :: common_header(~{::title},~{::link})"> (보내는 쪽)

 

<head th:fragment="common_header(title,links)"> (받는 쪽)

 

-> ::title 현재 페이지의 title 태그들을 전달함

    ::link 현재 페이지의 모든 link 태그들을 전달함

-> 헤더 부분을 가라끼는 방식

 

<html th:replace="~{template/layoutExtend/layoutFile :: layout(~{::title},~{::section})}"
      xmlns:th="http://www.thymeleaf.org">

 

<html th:fragment="layout (title, content)" xmlns:th="http://www.thymeleaf.org">

 

-> ::section 현재 페이지의 section 태그를 전달함

-> html 전체를 가라끼는 방식

 

레이아웃 쓰는 이유? footer만 바꾸는데 페이지가 100개라면? 노가다 줄여줌

 

'웹 프로그래밍 > 프론트 엔드' 카테고리의 다른 글

타임리프(스프링 통합과 폼)  (0) 2023.04.13
Thymeleaf(타임리프) 기초  (0) 2023.04.11
JavaScript 기초  (0) 2023.04.02
CSS 기초  (0) 2023.04.02
HTML 기초  (0) 2023.04.01