Field Formatting

Field Formatting

Field formatting controls how values appear in your tools. You can format numbers as currencies, add colours to status badges, mask sensitive data, and create consistent displays across all your tools.

Formatting is configured in the _fields.json file, which applies formatting globally. When you format a field like Order.totalAmount as currency, that formatting appears everywhere the field is displayed: in tables, record views, and embedded lists.

The _fields.json file

Create a _fields.json file in your tools/ directory to define field formatting:

your-project/
├── schema.keel
└── tools/
    └── _fields.json

The file contains an array of field configurations:

tools/_fields.json
[
  {
    "id": "Order.totalAmount",
    "format": {
      "number_config": {
        "mode": "CURRENCY",
        "currency_code": "GBP"
      }
    }
  },
  {
    "id": "OrderStatus",
    "format": {
      "enum_config": {
        "values": [
          { "value": "Pending", "colour": "#f59e0b" },
          { "value": "Shipped", "colour": "#3b82f6" },
          { "value": "Delivered", "colour": "#22c55e" }
        ]
      }
    }
  }
]

Field identifiers

The id field uses one of two formats:

FormatUse caseExample
ModelName.fieldNameModel fieldsOrder.totalAmount, StockItem.quantity
EnumNameEnum typesOrderStatus, PaymentMethod

Enum formatting applies to all fields that use that enum, regardless of which model they belong to.

Number formatting

Number fields support five display modes, plus options for colours, prefixes, and sensitive data handling.

Format modes

ModeDescriptionInputOutput
DECIMALStandard decimal with locale formatting (default)1234.561,234.56
RAWNo formatting applied1234.561234.56
CURRENCYCurrency with symbol from currency_code1234.56£1,234.56
PERCENTAGEPercentage display0.12512.5%
UNITDisplay with unit from unit_code150150 kg

Currency formatting

Display monetary values with the appropriate currency symbol and formatting:

tools/_fields.json
[
  {
    "id": "Order.totalAmount",
    "format": {
      "number_config": {
        "mode": "CURRENCY",
        "currency_code": "GBP"
      }
    }
  },
  {
    "id": "Order.shippingCost",
    "format": {
      "number_config": {
        "mode": "CURRENCY",
        "currency_code": "USD",
        "locale": "en-US"
      }
    }
  }
]

The currency_code uses ISO 4217 (opens in a new tab) codes. Common codes include:

CodeCurrency
GBPBritish Pound
USDUS Dollar
EUREuro
JPYJapanese Yen
CADCanadian Dollar
AUDAustralian Dollar

Currency formatting uses the browser's locale by default. Set locale explicitly if you need consistent formatting regardless of user location.

Percentage formatting

Display decimal values as percentages:

tools/_fields.json
[
  {
    "id": "Product.discountRate",
    "format": {
      "number_config": {
        "mode": "PERCENTAGE"
      }
    }
  },
  {
    "id": "Order.taxRate",
    "format": {
      "number_config": {
        "mode": "PERCENTAGE"
      }
    }
  }
]

A value of 0.15 displays as 15%.

Unit formatting

Display quantities with measurement units:

tools/_fields.json
[
  {
    "id": "StockItem.weight",
    "format": {
      "number_config": {
        "mode": "UNIT",
        "unit_code": "kilogram"
      }
    }
  },
  {
    "id": "Shipment.distance",
    "format": {
      "number_config": {
        "mode": "UNIT",
        "unit_code": "kilometer"
      }
    }
  }
]

The unit_code supports compound units like meter-per-second for derived measurements.

Conditional colouring

Colour numbers based on whether they're positive or negative. This is useful for financial data where gains and losses need visual distinction:

tools/_fields.json
[
  {
    "id": "Order.profitMargin",
    "format": {
      "number_config": {
        "mode": "CURRENCY",
        "currency_code": "GBP",
        "colourise": "NORMAL"
      }
    }
  },
  {
    "id": "StockItem.quantityVariance",
    "format": {
      "number_config": {
        "mode": "DECIMAL",
        "colourise": "INVERTED"
      }
    }
  }
]
ModePositive valuesNegative values
NONENo colour (default)No colour
NORMALGreenRed
INVERTEDRedGreen

Use INVERTED when negative values are good (like cost reductions) and positive values indicate problems.

Prefix and suffix

Add text before or after the formatted number:

tools/_fields.json
[
  {
    "id": "Order.reference",
    "format": {
      "number_config": {
        "prefix": "ORD-",
        "mode": "RAW"
      }
    }
  },
  {
    "id": "Product.leadTime",
    "format": {
      "number_config": {
        "suffix": " days",
        "mode": "DECIMAL"
      }
    }
  }
]

Sensitive number data

Mask financial or confidential numeric values:

tools/_fields.json
[
  {
    "id": "Supplier.creditLimit",
    "format": {
      "number_config": {
        "mode": "CURRENCY",
        "currency_code": "GBP",
        "sensitive": true
      }
    }
  }
]

Sensitive fields display as masked content until the user hovers over them.

Number formatting options

OptionTypeDescription
modestringDECIMAL, RAW, CURRENCY, PERCENTAGE, or UNIT
currency_codestringISO 4217 currency code (required for CURRENCY mode)
unit_codestringUnit identifier (required for UNIT mode)
localestringLocale code for formatting (auto-detected by default)
prefixstringText prepended to the value
suffixstringText appended to the value
sensitivebooleanMasks the value until hovered
colourisestringColour mode: NONE, NORMAL, or INVERTED

A CUSTOM colourise mode exists in the schema but is not yet implemented.

Enum formatting

Enum fields can display custom labels and colours for each value. This is particularly useful for status fields where visual distinction helps users scan data quickly.

Basic enum colours

tools/_fields.json
[
  {
    "id": "OrderStatus",
    "format": {
      "enum_config": {
        "values": [
          { "value": "Pending", "colour": "#f59e0b" },
          { "value": "Processing", "colour": "#3b82f6" },
          { "value": "Shipped", "colour": "#8b5cf6" },
          { "value": "Delivered", "colour": "#22c55e" },
          { "value": "Cancelled", "colour": "#ef4444" }
        ]
      }
    }
  }
]

Colours display as coloured badges in tables and record views.

Custom display labels

Show user-friendly labels instead of the schema enum values:

tools/_fields.json
[
  {
    "id": "PaymentStatus",
    "format": {
      "enum_config": {
        "values": [
          {
            "value": "AwaitingPayment",
            "display_value": "Awaiting Payment",
            "colour": "#f59e0b"
          },
          {
            "value": "PaymentReceived",
            "display_value": "Payment Received",
            "colour": "#22c55e"
          },
          {
            "value": "PaymentFailed",
            "display_value": "Payment Failed",
            "colour": "#ef4444"
          },
          {
            "value": "Refunded",
            "display_value": "Refunded",
            "colour": "#6b7280"
          }
        ]
      }
    }
  }
]

Ordering enum values

Control the order of enum values in dropdowns and filters:

tools/_fields.json
[
  {
    "id": "Priority",
    "format": {
      "enum_config": {
        "values": [
          { "value": "Critical", "colour": "#ef4444", "display_order": 1 },
          { "value": "High", "colour": "#f59e0b", "display_order": 2 },
          { "value": "Medium", "colour": "#3b82f6", "display_order": 3 },
          { "value": "Low", "colour": "#6b7280", "display_order": 4 }
        ]
      }
    }
  }
]

Enum value options

OptionTypeDescription
valuestringThe actual enum value in your schema
display_valuestringLabel shown in the UI (defaults to value)
colourstringHex colour code for the badge
display_ordernumberOrder in dropdowns and filters

Use colours with good contrast and consider accessibility. Avoid relying solely on colour to convey meaning. The display label should also indicate the status.

Boolean formatting

Boolean fields can display custom labels and colours for true and false states:

tools/_fields.json
[
  {
    "id": "StockItem.inStock",
    "format": {
      "bool_config": {
        "positive_value": "In Stock",
        "positive_colour": "#22c55e",
        "negative_value": "Out of Stock",
        "negative_colour": "#ef4444"
      }
    }
  },
  {
    "id": "Order.isPriority",
    "format": {
      "bool_config": {
        "positive_value": "Priority",
        "positive_colour": "#ef4444",
        "negative_value": "Standard",
        "negative_colour": "#6b7280"
      }
    }
  }
]

Boolean formatting options

OptionTypeDescription
positive_valuestringLabel when value is true
positive_colourstringHex colour when value is true
negative_valuestringLabel when value is false
negative_colourstringHex colour when value is false

String formatting

String fields support prefixes, suffixes, text colours, URL previews, and sensitive data masking.

Prefix and suffix

Add consistent formatting to text values:

tools/_fields.json
[
  {
    "id": "Order.reference",
    "format": {
      "string_config": {
        "prefix": "ORD-"
      }
    }
  },
  {
    "id": "Product.sku",
    "format": {
      "string_config": {
        "prefix": "SKU-"
      }
    }
  }
]

Text colour

Apply a consistent colour to text values:

tools/_fields.json
[
  {
    "id": "Order.internalNotes",
    "format": {
      "string_config": {
        "text_colour": "#6b7280"
      }
    }
  }
]

URL previews

Render string fields containing URLs as clickable links:

tools/_fields.json
[
  {
    "id": "Product.websiteUrl",
    "format": {
      "string_config": {
        "show_url_preview": true
      }
    }
  },
  {
    "id": "Shipment.trackingUrl",
    "format": {
      "string_config": {
        "show_url_preview": true
      }
    }
  }
]

Sensitive string data

Mask confidential text values:

tools/_fields.json
[
  {
    "id": "Customer.apiKey",
    "format": {
      "string_config": {
        "sensitive": true
      }
    }
  },
  {
    "id": "Supplier.accountNumber",
    "format": {
      "string_config": {
        "sensitive": true
      }
    }
  }
]

Sensitive fields show masked content until the user hovers over them.

String formatting options

OptionTypeDescription
prefixstringText prepended to the value
suffixstringText appended to the value
text_colourstringHex colour for the text
show_url_previewbooleanRenders URLs as clickable links
sensitivebooleanMasks the value until hovered

Date and time display

Date and time fields (Date, Timestamp) are automatically formatted based on the user's browser locale. Keel handles timezone conversions and displays dates in a human-readable format appropriate for the user's region.

Date and time formatting is automatic and locale-aware. There's no configuration needed. Fields display appropriately based on each user's browser settings.

Additional field options

Beyond formatting, _fields.json also supports these display options that apply globally:

tools/_fields.json
[
  {
    "id": "Order.internalCode",
    "visible": false
  },
  {
    "id": "Product.thumbnail",
    "image_preview": true
  },
  {
    "id": "StockItem.location",
    "display_name": "Storage Location",
    "help_text": "The warehouse location where this item is stored"
  }
]
OptionTypeDescription
visiblebooleanWhether the field is shown by default
display_namestringLabel shown instead of the field name
help_textstringExplanatory text shown with the field
image_previewbooleanFor file fields, shows inline image previews

Complete ERP example

Here's a comprehensive example for an order management system:

tools/_fields.json
[
  {
    "id": "Order.reference",
    "format": {
      "string_config": {
        "prefix": "ORD-"
      }
    }
  },
  {
    "id": "Order.totalAmount",
    "format": {
      "number_config": {
        "mode": "CURRENCY",
        "currency_code": "GBP"
      }
    }
  },
  {
    "id": "Order.discountAmount",
    "format": {
      "number_config": {
        "mode": "CURRENCY",
        "currency_code": "GBP",
        "colourise": "INVERTED"
      }
    }
  },
  {
    "id": "Order.taxRate",
    "format": {
      "number_config": {
        "mode": "PERCENTAGE"
      }
    }
  },
  {
    "id": "Order.isPriority",
    "format": {
      "bool_config": {
        "positive_value": "Priority",
        "positive_colour": "#ef4444",
        "negative_value": "Standard",
        "negative_colour": "#6b7280"
      }
    }
  },
  {
    "id": "OrderStatus",
    "format": {
      "enum_config": {
        "values": [
          { "value": "Draft", "colour": "#9ca3af", "display_order": 1 },
          { "value": "Pending", "colour": "#f59e0b", "display_order": 2 },
          { "value": "Confirmed", "colour": "#3b82f6", "display_order": 3 },
          { "value": "Processing", "colour": "#8b5cf6", "display_order": 4 },
          { "value": "Shipped", "colour": "#06b6d4", "display_order": 5 },
          { "value": "Delivered", "colour": "#22c55e", "display_order": 6 },
          { "value": "Cancelled", "colour": "#ef4444", "display_order": 7 }
        ]
      }
    }
  },
  {
    "id": "StockItem.sku",
    "format": {
      "string_config": {
        "prefix": "SKU-"
      }
    }
  },
  {
    "id": "StockItem.quantity",
    "format": {
      "number_config": {
        "mode": "DECIMAL",
        "colourise": "NORMAL"
      }
    }
  },
  {
    "id": "StockItem.unitCost",
    "format": {
      "number_config": {
        "mode": "CURRENCY",
        "currency_code": "GBP"
      }
    }
  },
  {
    "id": "StockItem.weight",
    "format": {
      "number_config": {
        "mode": "UNIT",
        "unit_code": "kilogram"
      }
    }
  },
  {
    "id": "StockItem.inStock",
    "format": {
      "bool_config": {
        "positive_value": "In Stock",
        "positive_colour": "#22c55e",
        "negative_value": "Out of Stock",
        "negative_colour": "#ef4444"
      }
    }
  },
  {
    "id": "Shipment.trackingUrl",
    "format": {
      "string_config": {
        "show_url_preview": true
      }
    }
  },
  {
    "id": "ShipmentStatus",
    "format": {
      "enum_config": {
        "values": [
          { "value": "Preparing", "colour": "#f59e0b" },
          { "value": "AwaitingPickup", "display_value": "Awaiting Pickup", "colour": "#3b82f6" },
          { "value": "InTransit", "display_value": "In Transit", "colour": "#8b5cf6" },
          { "value": "OutForDelivery", "display_value": "Out for Delivery", "colour": "#06b6d4" },
          { "value": "Delivered", "colour": "#22c55e" },
          { "value": "Failed", "colour": "#ef4444" }
        ]
      }
    }
  },
  {
    "id": "PaymentMethod",
    "format": {
      "enum_config": {
        "values": [
          { "value": "Card", "display_value": "Credit/Debit Card" },
          { "value": "BankTransfer", "display_value": "Bank Transfer" },
          { "value": "Invoice", "display_value": "Invoice (Net 30)" },
          { "value": "Cash", "display_value": "Cash on Delivery" }
        ]
      }
    }
  }
]

This configuration:

  • Adds "ORD-" and "SKU-" prefixes to reference numbers
  • Formats all monetary values as British pounds
  • Shows discounts in red (using inverted colouring)
  • Displays tax rates as percentages
  • Colours order and shipment status badges for quick scanning
  • Shows stock availability with clear in/out of stock labels
  • Makes tracking URLs clickable
  • Provides user-friendly labels for payment methods