← 개발일지

Thymeleaf: Show Product Option Next to Name in Cart


How to Display a Product Option Name Next to the Product Name in a Thymeleaf Cart

If you're building a shopping cart with Thymeleaf, showing just the product name often isn't enough. Users need to see what option they selected — size, color, or any other variant — right alongside the product name. Here are three clean patterns for doing that, including proper null handling for products that have no options.


The Starting Point

You probably have markup that looks something like this:

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

All three patterns below build on this base. Pick whichever fits your layout.


Option 1 — Inline Span (Simplest)

<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>

This is the fastest option to implement. The option name appears right after the product link, and you can style .opt-nm however you like in CSS.


Option 2 — Option Name on a New Line

<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>

Use this when you want a clear visual separation between the product name and option — for example, if you're rendering the option in a smaller font or lighter color underneath.


Option 3 — Inline with a Separator (/)

<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>

This produces output like Wireless Mouse / Black / USB-C. The <th:block> tag is a Thymeleaf-only element that renders no actual HTML tag — it just outputs its content. This makes it perfect for injecting inline text conditionally without wrapping it in an extra <span>.


Don't Skip the Null Check

Your cart likely has products with no options at all (standard, single-variant items). If you skip the th:if, Thymeleaf will output null as a literal string — which is not what you want.

Even better, cover both null and empty string in one condition using Thymeleaf's built-in #strings utility:

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

#strings.isEmpty() returns true for both null and "", so you can replace the two-condition check with a single expression.


Which Pattern Should You Use?

| Pattern | Output style | Best for | |---|---|---| | Inline <span> | Side by side | Quick addition, minimal styling | | <br> + <span> | Stacked | Visual separation, distinct styling | | <th:block> with / | Name / Option inline | Compact, separator-based display |

The null check with th:if (or #strings.isEmpty()) applies to all three — don't skip it regardless of which pattern you pick.