Conditionals

JWeb provides fluent conditional rendering utilities. Control what renders based on conditions, iterate over collections, and handle multiple cases cleanly.

Overview

Use when() for optional content, cond() for either/or choices, and each() for list iteration.

// Show if true
when(condition, () -> element())

// Either/or
cond(condition, trueElement(), falseElement())

// Iterate
each(list, item -> renderItem(item))

when() - Conditional Display

Show elements only when a condition is true.

// Basic when
when(isLoggedIn, () -> span("Welcome back!"))

// With complex element
when(user != null, () ->
    div(
        img(attrs().src(user.getAvatar())),
        span(user.getName())
    )
)

// Check property
when(cart.hasItems(), () ->
    div(
        span("Items: " + cart.getItemCount()),
        button("Checkout")
    )
)

unless() - Inverse Conditional

Show elements only when a condition is false.

// Show login link when NOT logged in
unless(isLoggedIn, () ->
    a(attrs().href("/login"), text("Please log in"))
)

// Show empty state
unless(items.isEmpty(), () -> itemList(items))
unless(!items.isEmpty(), () -> emptyState())

// Combine with when
div(
    when(isLoggedIn, () -> userMenu()),
    unless(isLoggedIn, () -> loginButton())
)

cond() - Either/Or

Choose between two elements based on a condition.

// Basic ternary: condition ? ifTrue : ifFalse
cond(isAdmin, adminDashboard(), userDashboard())

// Status display
cond(user.isActive(),
    span(attrs().class_("text-green"), text("Active")),
    span(attrs().class_("text-red"), text("Inactive"))
)

// Toggle button text
button(
    cond(isExpanded,
        text("Show Less"),
        text("Show More")
    )
)

// Nested conditions
cond(isPremium,
    premiumContent(),
    cond(isRegistered,
        basicContent(),
        guestContent()
    )
)

Using Java Ternary

Standard Java ternary works too.

// Java ternary with elements
div(
    isLoggedIn ? userPanel() : loginPrompt()
)

// For simple text
span(isActive ? "Active" : "Inactive")

// Choose class
div(attrs().class_(isError ? "error" : "success"),
    text(message)
)

If-Elif-Else Chains

Handle multiple conditions with fluent chain.

// Role-based content
when(isAdmin)
    .then(adminPanel())
    .elif(isModerator, moderatorPanel())
    .elif(isEditor, editorPanel())
    .elif(isUser, userPanel())
    .otherwise(guestPanel())

// Status-based styling
when(status.equals("success"))
    .then(successMessage())
    .elif(status.equals("warning"), warningMessage())
    .elif(status.equals("error"), errorMessage())
    .otherwise(infoMessage())

match() - Pattern Matching

Match against multiple conditions, first match wins.

// Status badge
match(
    cond(status.equals("active"), greenBadge("Active")),
    cond(status.equals("pending"), yellowBadge("Pending")),
    cond(status.equals("suspended"), redBadge("Suspended")),
    cond(status.equals("archived"), grayBadge("Archived")),
    otherwise(grayBadge("Unknown"))
)

// HTTP status
match(
    cond(code >= 500, serverError()),
    cond(code >= 400, clientError()),
    cond(code >= 300, redirect()),
    cond(code >= 200, success()),
    otherwise(unknown())
)

each() - List Iteration

Render elements for each item in a collection.

// Simple list
List<String> items = List.of("Apple", "Banana", "Cherry");
ul(each(items, item -> li(item)))

// Complex items
List<User> users = userService.findAll();
div(each(users, user ->
    div(attrs().class_("user-card"),
        h3(user.getName()),
        p(user.getEmail()),
        when(user.isAdmin(), () -> badge("Admin"))
    )
))

eachWithIndex() - With Index

Access the index while iterating.

// Numbered list
ol(eachWithIndex(items, (item, index) ->
    li((index + 1) + ". " + item)
))

// Alternating rows
table(tbody(eachWithIndex(users, (user, i) ->
    tr(attrs().class_(i % 2 == 0 ? "even" : "odd"),
        td(user.getName()),
        td(user.getEmail())
    )
)))

// First/last handling
div(eachWithIndex(items, (item, i) ->
    span(
        text(item),
        when(i < items.size() - 1, () -> text(", "))
    )
))

Empty State

// Show empty state when list is empty
cond(items.isEmpty(),
    div(attrs().class_("empty"), text("No items found")),
    ul(each(items, item -> li(item)))
)