← 개발일지

Thymeleaf 장바구니 상품명 옆에 옵션명 추가하는 3가지 방법


Thymeleaf 장바구니에서 상품명 옆에 옵션명 추가하기

장바구니 목록을 만들다 보면 상품명만 단독으로 보여주는 것보다, 선택한 옵션(색상, 사이즈 등)도 함께 표시해야 할 때가 있습니다. Thymeleaf에서 이를 처리하는 방법은 레이아웃 요구에 따라 여러 가지가 있는데, 패턴별로 정리해 봤습니다.


기본 구조

시작점은 이런 형태의 마크업입니다.

<p class="tit">
    <a th:href="@{/product/detail(prodNo=${cartProduct.prodNo},dispCatNo=${cartProduct.dispCatNo})}">
        [[${cartProduct.productBase.prodNm}]]
    </a>
</p>

여기에 옵션명을 추가하는 방식은 크게 3가지입니다.


방법 1 — 같은 줄에 span으로 추가 (가장 단순)

<p class="tit">
    <a th:href="@{/product/detail(prodNo=${cartProduct.prodNo},dispCatNo=${cartProduct.dispCatNo})}">
        [[${cartProduct.productBase.prodNm}]]
    </a>
    <!-- Render option name only when present -->
    <span class="opt-nm"
          th:if="${cartProduct.optNm != null}"
          th:text="${cartProduct.optNm}"></span>
</p>

상품명 링크 바로 옆에 옵션명을 붙이는 형태입니다. CSS로 스타일만 잡아주면 되니 빠르게 적용하기 좋습니다.


방법 2 — 줄 바꿔서 아래에 표시

<p class="tit">
    <a th:href="@{/product/detail(prodNo=${cartProduct.prodNo},dispCatNo=${cartProduct.dispCatNo})}">
        [[${cartProduct.productBase.prodNm}]]
    </a>
    <br>
    <!-- Option name on a new line -->
    <span class="opt-nm"
          th:if="${cartProduct.optNm != null}"
          th:text="${cartProduct.optNm}"></span>
</p>

상품명과 옵션명을 시각적으로 분리하고 싶을 때 사용합니다. 옵션명에 별도의 폰트 사이즈나 색상을 입히는 경우에 적합합니다.


방법 3 — 구분자(/)로 인라인 연결

<a th:href="@{/product/detail(prodNo=${cartProduct.prodNo},dispCatNo=${cartProduct.dispCatNo})}">
    [[${cartProduct.productBase.prodNm}]]
    <!-- Append option name with separator inline -->
    <th:block th:if="${cartProduct.optNm != null}"> / [[${cartProduct.optNm}]]</th:block>
</a>

무선 마우스 / 블랙 / USB-C 처럼 구분자로 이어붙이는 스타일입니다. 링크 안에 옵션명까지 포함시키고 싶을 때도 <th:block>을 활용하면 깔끔하게 처리됩니다.


null 처리, 꼭 챙겨야 하는 이유

옵션이 없는 단일 상품도 장바구니에 담길 수 있습니다. th:if 없이 th:text="${cartProduct.optNm}"만 쓰면 null 그대로 렌더링될 수 있어서 반드시 조건 체크가 필요합니다.

null과 빈 문자열을 동시에 방어하려면 Thymeleaf의 #strings 유틸리티를 쓰는 것이 가장 깔끔합니다.

th:if="${not #strings.isEmpty(cartProduct.optNm)}"

#strings.isEmpty()는 null과 빈 문자열 모두 true를 반환하므로, 두 조건을 하나로 처리할 수 있습니다.


정리

| 방법 | 특징 | 선택 기준 | |---|---|---| | <span> 우측 추가 | 가장 단순 | 인라인으로 바로 붙여도 되는 경우 | | <br> + <span> | 줄 분리 | 상품명/옵션 구분이 시각적으로 필요한 경우 | | <th:block> 구분자 | 인라인, 구분자 포함 | 상품명 / 옵션명 형식으로 표시할 경우 |

세 방법 모두 null 처리를 위한 th:if 조건은 공통입니다. 빈 문자열까지 고려한다면 #strings.isEmpty()를 쓰는 것을 권장합니다.