# Enums with wording

An enum has no label for people of its own
([Enums](enums.md)). To show one, give each of its
values a wording in its domain's language files. It is checked like a
message with one enum field. Then `{{ order.status }}` in a template writes
the wording, and code reads it with
`translations.<domain>.<enum>(value, locale: ...)`. In a template, writing
out an enum that has no wording is an error that says to add it.

A value's own fields are placeholders in that value's wording, both in the
enum's wording and in a message that has the enum as its field. Another
value's fields aren't available.

An enum is worded in every supported locale as soon as any language file
words it. One that no file words needs no wording.

```jadpo
use shipping/types { HoldReason }

type OrderStatus = Enum {
    pending
    on_hold: {
        reason: HoldReason
    }
    shipped
}
```

```jadpo
use shipping/types { OrderStatus, StatusText }

/// An order's status, in the customer's language.
action describe_status(status: OrderStatus, reader_locale: Locale) -> StatusText {
    return StatusText {
        status: translations.shipping.order_status(status, locale: reader_locale)
    }
}
```

```jadpo
translations {
    order_status: {
        pending: "Waiting to be packed"
        on_hold: "Held: {reason}"
        shipped: "On its way"
    }
}
```

```jadpo
use shipping/types { OrderStatus }

test "an enum is worded by its value, with the value's fields" {
    assert translations.shipping.order_status(
        OrderStatus.pending,
        locale: Locale.fr_fr
    ) == "En attente d'emballage"
    assert translations.shipping.order_status(
        OrderStatus.on_hold {
            reason: "no stock"
        },
        locale: Locale.en_gb
    ) == "Held: no stock"
}
```
