[스프링] 메시지, 국제화
·
스프링
악덕(?) 기획자가 갑자기 “상품명이라는 단어가 마음에 들지 않으니 전부 상품이름으로 고쳐라”라고 요구한다고 가정해보자.이 경우 화면에 보이는 HTML 파일을 하나하나 열어 모두 수정해야 한다. 화면 수가 몇 개 안 되면 그럭저럭 할 수 있겠지만, 수십 개 이상이라면 일일이 찾아 바꾸는 일은 불편하고 버그의 원인이 되기 쉽다. 이러한 문제를 해결하기 위해 메시지와 국제화(i18n) 기능이 존재한다.오늘은 이 기능을 어떻게 활용해 화면 문구를 효율적으로 관리할 수 있는지 살펴본다. 1. 메시지 관리란 무엇인가메시지 관리는 화면에 표시되는 텍스트를 한 곳에서 정의하고, 필요할 때 불러서 사용하는 방식이다.예를 들어 messages.properties 파일을 두고 다음과 같이 정의한다.item=상품item.i..
[타임리프] 체크박스
·
타임리프
오늘은 HTML 체크박스의 동작 방식과 타임리프(Thymeleaf)에서 제공하는 편리한 기능에 대해 알아보려고 한다. 체크박스는 "판매 여부", "약관 동의", "활성화 여부"처럼 Boolean 값을 표현할 때 자주 사용된다. 하지만 체크박스에는 중요한 특징이 있다. 체크하지 않으면 값 자체가 서버로 넘어가지 않는다는 점이다. 단순 등록 화면에서는 크게 문제되지 않지만, 수정 화면에서는 심각한 문제로 이어질 수 있다. 예를 들어 원래 체크되어 있던 값을 사용자가 해제했는데, 서버로 아무 값도 넘어오지 않으니 데이터가 갱신되지 않는 상황이 생기는 것이다.이 글에서는단순 HTML 체크박스가 동작하는 방식체크 해제를 인식하기 위한 히든 필드(hidden field) 기법타임리프가 제공하는 자동 처리 기능을 차..
[Thymeleaf] 템플릿 레이아웃
·
타임리프
웹 화면을 개발할 때, 여러 페이지에 공통으로 들어가는 부분이 많다. 예를 들어, 모든 페이지의 여기서 th:fragment="common_header(title, links)"는 "title과 links를 받아서 렌더링할 수 있는 조각(fragment)"이라는 뜻이다. 실제 페이지 (layoutMain.html) 메인 컨텐츠여기서 ~{::title} 은 현재 페이지의 태그를, ~{::link} 는 현재 페이지의 태그들을 그대로 전달한다. 렌더링 결과공통 레이아웃 H1 레이아웃 컨텐츠 레이아웃 푸터여기서 layout (title, content)는 두 개의 영역을 받는다: 제목(title)과 본문(content). 실제 페이지 (layoutExtendM..
[Thymeleaf] 템플릿 조각
·
타임리프
웹 화면을 개발하다 보면 여러 페이지에서 반복해서 사용하는 공통 영역이 많다.예를 들어 사이트의 상단 메뉴(헤더), 하단 푸터, 좌측 카테고리 메뉴 같은 부분이 그렇다.이런 코드를 매번 페이지마다 복사해서 붙여넣는다면, 나중에 디자인을 조금만 수정해도 모든 페이지를 다 고쳐야 하는 비효율적인 상황이 발생한다. 유지보수성이 떨어지고, 실수할 가능성도 높다. 이러한 문제를 해결하기 위해 Thymeleaf는 템플릿 조각(fragment)과 레이아웃 기능을 제공한다.템플릿 조각은 한 번 만들어 두면 여러 화면에서 불러와서 사용할 수 있으므로 재사용성과 유지보수성이 크게 좋아진다.오늘은 템플릿 조각 정의하기, 불러오기, 파라미터 전달하기 방법을 차례대로 알아보자. 1. 컨트롤러 준비하기@Controller@Re..
[Thymeleaf] 자바스크립트 인라인
·
타임리프
웹 애플리케이션을 개발하다 보면 서버에서 내려온 데이터를 자바스크립트 코드 안에서 그대로 사용해야 할 때가 많다. 하지만 단순히 값을 출력하는 것만으로는 문자열에 따옴표가 빠진다거나, 객체가 단순한 toString() 결과로 표시되는 등 문제가 생기기 쉽다. 이번 글에서는 이런 문제를 해결하기 위해 Thymeleaf가 제공하는 자바스크립트 인라인 기능을 살펴본다. 문자열 처리, 내추럴 템플릿, 객체 JSON 변환, 그리고 리스트 데이터를 반복 처리하는 방법까지 실제 예제를 통해 알아보자 1. 컨트롤러에서 데이터 준비@GetMapping("/javascript")public String javascript(Model model) { model.addAttribute("user", new User("..
[Thymeleaf] 블록
·
타임리프
웹 화면을 만들다 보면 데이터를 반복 출력하거나 조건부로 보여줘야 할 때가 많다. 보통은 나 같은 HTML 태그에 타임리프 속성을 붙여 처리한다. 하지만 어떤 경우에는 굳이 의미 없는 태그를 추가해야 하는 상황이 생긴다.오늘은 이런 상황을 해결하기 위해 타임리프에서 제공하는 유일한 자체 태그 에 대해 알아본다. 은 화면에는 출력되지 않지만, 반복문이나 조건문을 묶는 용도로 활용할 수 있어 매우 유용하다. 1. 컨트롤러에서 데이터 준비하기예제를 위해 컨트롤러에서 사용자 리스트를 모델에 담아 뷰로 넘긴다.@GetMapping("/block")public String block(Model model) { addUsers(model); return "basic/block";}private void ..