Skip to content

All Field Settings

These settings can be applied to any field type. They control universal behaviors like hiding fields and conditional visibility.

The autogen setting automatically generates a field’s value from other fields using template variables. This works on any text-based field type (text, textarea, hidden, email, url, etc.).

When used on an ID field, the result is automatically slugified (lowercased, hyphens for spaces). When used on any other field, the result is kept as-is with no transformation.

{
"autogen": "${firstname} ${lastname}"
}

The value updates automatically whenever a referenced field changes.

Use ${fieldname} to reference any other property in the same form. There are also special built-in variables:

  • now - Current timestamp in milliseconds
  • timestamp - Current date/time in compact ISO format (e.g., 20230815T143056)
  • uuid - UUID v4 (e.g., 550e8400-e29b-41d4-a716-446655440000)
  • uid - Short random 7-character alphanumeric string
  • oid - Object ID counter (increments per object in collection)
  • oid-00000 - Zero-padded Object ID
  • currentyear - Full 4-digit year
  • currentyear2 - 2-digit year
  • currentmonth - Zero-padded month (01-12)
  • currentday - Zero-padded day (01-31)

Full name from first and last:

{
"fullname": {
"type": "string",
"field": "text",
"label": "Full Name",
"settings": {
"autogen": "${firstname} ${lastname}"
}
}
}

Generates: John Smith (not slugified since it’s a text field)

Display title with date:

{
"displayTitle": {
"type": "string",
"field": "text",
"label": "Display Title",
"settings": {
"autogen": "${title} (${currentyear})"
}
}
}

Generates: My Article (2025)

Hidden computed field:

{
"slug": {
"type": "string",
"field": "text",
"label": "URL Slug",
"settings": {
"autogen": "${title}",
"hide": true
}
}
}

For ID-specific autogen features (slugification, uniqueness checking, OID padding), see the ID Settings documentation.

The calc setting evaluates a math expression to compute a field’s value from other number fields. The field becomes read-only automatically since its value is derived.

{
"calc": "${price} * ${quantity}"
}

The value recalculates in real time whenever a referenced field changes.

Use ${fieldname} to reference any other property in the same form. For referencing fields inside deck items from the parent object, use dot notation: ${deckProperty.fieldName}.

  • + Addition
  • - Subtraction
  • * Multiplication
  • / Division (division by zero returns 0)
  • % Modulo
  • () Parentheses for grouping
  • Unary - for negative numbers

Math functions:

  • round(x) - Round to nearest integer
  • round(x, precision) - Round to N decimal places (e.g., round(${total}, 2) for cents)
  • floor(x) - Round down
  • ceil(x) - Round up
  • abs(x) - Absolute value
  • min(a, b, …) - Minimum value
  • max(a, b, …) - Maximum value

Aggregate functions (for deck item fields):

  • sum(${deck.field}) - Sum all values
  • avg(${deck.field}) - Average of all values
  • count(${deck.field}) - Number of items
  • min(${deck.field}) - Minimum value
  • max(${deck.field}) - Maximum value

Use min and max settings alongside calc to clamp the computed result:

{
"settings": {
"calc": "${subtotal} - ${discount}",
"min": 0
}
}

This ensures the result never drops below 0, even if the discount exceeds the subtotal.

Line item total (within a deck item):

{
"lineTotal": {
"type": "number",
"field": "price",
"label": "Line Total",
"settings": {
"calc": "${unitPrice} * ${quantity}"
}
}
}

Subtotal from deck items:

{
"subtotal": {
"type": "number",
"field": "price",
"label": "Subtotal",
"settings": {
"calc": "sum(${items.lineTotal})"
}
}
}

Sums the lineTotal field from every item in the items deck property.

Tax calculation:

{
"tax": {
"type": "number",
"field": "price",
"label": "Tax",
"settings": {
"calc": "round(sum(${items.lineTotal}) * ${taxRate} / 100, 2)"
}
}
}

Grand total with discount and tax:

{
"grandTotal": {
"type": "number",
"field": "price",
"label": "Grand Total",
"settings": {
"min": 0,
"calc": "sum(${items.lineTotal}) - ${discount} + round((sum(${items.lineTotal}) - ${discount}) * ${taxRate} / 100)"
}
}
}

Average rating from reviews:

{
"avgRating": {
"type": "number",
"field": "number",
"label": "Average Rating",
"settings": {
"calc": "round(avg(${reviews.rating}))"
}
}
}

Item count:

{
"totalItems": {
"type": "number",
"field": "number",
"label": "Total Items",
"settings": {
"calc": "count(${items.id})"
}
}
}

When an object has both deck-item-level and object-level calc fields, they are processed in order:

  1. Deck item calcs first - e.g., lineTotal = ${unitPrice} * ${quantity} within each item
  2. Object-level calcs second - e.g., grandTotal = sum(${items.lineTotal}) using already-computed values

On the frontend, this happens naturally through the event system. On the backend (API saves, imports), the same ordering is enforced explicitly.

  • Read-only: Calc fields are automatically set to read-only on the frontend. Users cannot manually override computed values.
  • Number fields: Calc is designed for number fields (number, price). While it can be applied to other field types, the result is always numeric.
  • Missing fields: Any referenced field that is missing or non-numeric is treated as 0.
  • Backend evaluation: Calc expressions are re-evaluated server-side on every object save, ensuring consistency even for API-driven updates.

The hide setting allows you to completely hide a field from the admin form while still storing its data. This is useful for fields that should be managed programmatically or set via defaults rather than through the admin interface.

{
"hide": true
}

When hide is set to true, the field will have the cms-hide CSS class added, which hides it from view.

System-managed fields:

{
"processedAt": {
"type": "string",
"field": "datetime",
"label": "Processed At",
"settings": {
"hide": true
}
}
}

Fields with autogen values that shouldn’t be edited:

{
"slug": {
"type": "string",
"field": "text",
"label": "URL Slug",
"settings": {
"autogen": "${title}",
"hide": true
}
}
}

Metadata fields:

{
"version": {
"type": "number",
"field": "number",
"label": "Version",
"default": 1,
"settings": {
"hide": true
}
}
}
  • Data Storage: Hidden fields still store data in the object. They are just not visible in the admin form.
  • Default Values: Hidden fields typically should have a default value or be populated programmatically.
  • CSS Class: The field receives the cms-hide class. You can customize visibility with CSS if needed.

The visibility setting controls when a field is displayed in forms based on the value of another field.

{
"visibility": {
"watch": "fieldName",
"value": "expectedValue",
"operator": "=="
}
}

Properties:

  • watch (required) - The name of the field to watch for changes
  • value (required) - The value(s) to compare against. Can be a single value or an array of values
  • operator (optional) - The comparison operator to use (default: ==)

Equality Operators:

  • == - Equals (default)
  • != - Not equals

Numeric Operators:

  • > - Greater than
  • < - Less than
  • >= - Greater than or equal
  • <= - Less than or equal

Array Operators:

  • in - Current value is in the expected value array
  • not_in - Current value is not in the expected value array

Special Operators (for array fields like checkbox, multiselect):

  • empty - Field array is empty
  • not_empty - Field array has at least one value

Show field when another field has a specific value:

{
"visibility": {
"watch": "linkType",
"value": "custom",
"operator": "=="
}
}

Hide field when another field is checked:

{
"visibility": {
"watch": "useDefaultDescription",
"value": "1",
"operator": "!="
}
}

Show field when value is NOT in a list:

{
"visibility": {
"watch": "userRole",
"value": ["guest", "basic"],
"operator": "not_in"
}
}

Show field when multiselect contains a value:

{
"visibility": {
"watch": "contentTypes",
"value": "gallery",
"operator": "in"
}
}

Show field based on numeric comparison:

{
"visibility": {
"watch": "orderTotal",
"value": "100",
"operator": ">="
}
}

Show field when array field is not empty:

{
"visibility": {
"watch": "categories",
"value": null,
"operator": "not_empty"
}
}

Match multiple values (OR logic):

{
"visibility": {
"watch": "deliveryMethod",
"value": ["standard", "express", "overnight"],
"operator": "=="
}
}

Field is visible if deliveryMethod matches ANY value in the array.

Fields with a visibility setting are hidden by default until the condition is met. This ensures fields appear only when they should, even on initial form load.

The required setting marks a field as required in the form only, separately from the schema’s top-level required array. Pair it with visibility to make a field required only when another field has a particular value.

{
"required": true
}

Total CMS has two distinct ways to mark a field as required, and they are intentionally separate:

WhereWhat it doesWhen it fires
Schema’s top-level required: ["foo"] arrayHard data invariant — the object cannot be saved without a valueServer-side on every save (form, API, CLI, import)
Field’s settings.required: trueAdds the required HTML attribute to the inputClient-side HTML5 validation when the form is submitted

Use the schema’s top-level required when a value must always exist on every record. Use settings.required when the requirement is conditional — typically driven by another field’s value via visibility.

Important: If a field is listed in the schema’s required array AND has settings.required: true, the schema-level rule still wins on save. For a truly conditional field, leave it out of the schema’s required array entirely — otherwise saves will be rejected when the field has no value, defeating the conditional behavior.

The common use case is “this field is only required when a toggle is set.” Combine settings.required with settings.visibility:

{
"enableNotifications": {
"type": "boolean",
"field": "toggle",
"label": "Send Email Notifications"
},
"notificationEmail": {
"type": "string",
"field": "email",
"label": "Notification Email",
"settings": {
"required": true,
"visibility": {
"watch": "enableNotifications",
"value": "1",
"operator": "=="
}
}
}
}

When enableNotifications is on, the email field is visible and the browser enforces the required attribute on submit. When the toggle is off, the field is hidden and the form’s visibility system strips the required attribute so an empty value doesn’t block submission. Because notificationEmail is not listed in the schema’s required array, saves succeed regardless of toggle state.

When a field has both required and visibility, the form automatically:

  • Strips the required HTML attribute when the field is hidden
  • Restores it when the field becomes visible
  • Skips client-side validation entirely for hidden fields

This works transparently — no extra configuration beyond setting both required and visibility on the field.

All fields support validation rules like pattern, minLength, maxLength, minimum, maximum, enum, and more. These are added in the Extra Schema Definitions section of a property, not in Settings.

For full details and examples, see Schema Validation.