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