Card Fields

A card is a single-instance deck. It renders the properties of another schema as inline sub-fields and stores the collected values as a nested object on the parent. Use it to group related settings (sitemap config, auth options, integration credentials, etc.) without the deck UX of add/remove/duplicate.

The card's shape is defined by a separate schema, referenced via schemaref. This keeps the nested structure reusable across collections and makes the parent schema easy to read.

How It Differs From a Deck

Deck Card
Cardinality Many items Exactly one
UI Modal dialog with add/remove/duplicate Inline sub-fields, no buttons
Stored as Object keyed by item IDs Single nested object keyed by property name
Schema schemaref defines item shape schemaref defines the card's shape

If you want a single named-object grouping, use a card. If you want a list of named objects, use a deck.

Basic Usage

{
    "sitemap": {
        "$ref"      : "https://www.totalcms.co/schemas/properties/card.json",
        "field"     : "card",
        "label"     : "Sitemap Settings",
        "schemaref" : "https://www.totalcms.co/schemas/sitemap-meta.json"
    }
}

The referenced schema (sitemap-meta.json here) defines the sub-fields the card will render. Its properties become the card's properties at save time.

Storage Format

A card stores as a single nested object keyed by sub-property name:

{
    "sitemap": {
        "enabled"   : true,
        "frequency" : "weekly",
        "priority"  : 0.7
    }
}

In Twig, access values with dot notation:

{% if object.sitemap.enabled %}
    <priority>{{ object.sitemap.priority }}</priority>
{% endif %}

Settings

schemaref

Required. URL of the schema that defines the card's sub-fields.

{
    "schemaref" : "https://www.totalcms.co/schemas/sitemap-meta.json"
}

Legacy alias: deckref is still accepted as an alias for schemaref and will continue to work indefinitely. New schemas should use schemaref.

Sub-Field Behavior

Sub-fields are rendered using the referenced schema's properties, required, and formgrid. A few rules apply:

  • The referenced schema's id field is skipped — a card is a single object with no meaningful identifier of its own.
  • Sub-field default values are applied when the card has no value for that property.
  • Sub-field settings are run through the same preset pipeline as top-level fields, including named presets and type-default presets.
  • The referenced schema's formgrid is honored for sub-field layout. Any sub-field not listed in formgrid is appended automatically.

Property Restrictions

Card values must be basic types or simple property schemas. The following are not allowed inside a card:

  • gallery, depot, folder (plurality models that don't fit the single-value-per-child shape)
  • Other decks (cards inside decks are fine; decks inside cards are not)

Allowed property types include string, number, boolean, card (nested), color, date, email, file, image, list, password, phone, slug, svg, time, and url.

Referencing nested images and files in Twig

Images and files stored inside a card are addressed by dot-notation in the property option of the standard media/render macros:

{# URL only #}
{{ cms.media.imagePath('post-1', {w: 800}, {property: 'mycard.image'}) }}

{# Full <img> tag #}
{{ cms.render.image('post-1', {w: 800}, {property: 'mycard.image'}) }}

{# File download URL #}
{{ cms.media.download('post-1', {property: 'mycard.attachment'}) }}

The first segment is the card field's name on the parent object; subsequent segments walk down into the card. The Image Builder dialog (opened from the admin form) emits the correct dotted-property macro automatically. See cms.media → Nested images for full reference.

Complete Example

A card that groups sitemap configuration into a single nested object:

Parent schema:

{
    "sitemap": {
        "$ref"      : "https://www.totalcms.co/schemas/properties/card.json",
        "field"     : "card",
        "label"     : "Sitemap Settings",
        "schemaref" : "https://www.totalcms.co/schemas/sitemap-meta.json"
    }
}

Referenced schema (sitemap-meta.json):

{
    "properties": {
        "enabled": {
            "type"    : "boolean",
            "field"   : "checkbox",
            "label"   : "Include in Sitemap",
            "default" : true
        },
        "frequency": {
            "type"    : "string",
            "field"   : "select",
            "label"   : "Change Frequency",
            "options" : ["always", "hourly", "daily", "weekly", "monthly", "yearly", "never"],
            "default" : "weekly"
        },
        "priority": {
            "type"    : "number",
            "field"   : "number",
            "label"   : "Priority",
            "default" : 0.5
        }
    }
}

Resulting object value:

{
    "sitemap": {
        "enabled"   : true,
        "frequency" : "weekly",
        "priority"  : 0.7
    }
}

Reusing a Card Schema

Because a card's shape is defined by a separate schema, the same schema can back multiple card fields on the same parent. This is the most common real-world pattern: one reusable building block, dropped in wherever it's needed.

The classic example is an address. An order needs both a billing address and a shipping address — same shape, same fields, two distinct values. Define the address shape once, then reference it from both cards.

Address schema (address.json):

{
    "properties": {
        "street1": {
            "type"  : "string",
            "field" : "input",
            "label" : "Street Address"
        },
        "street2": {
            "type"  : "string",
            "field" : "input",
            "label" : "Apt / Suite"
        },
        "city": {
            "type"  : "string",
            "field" : "input",
            "label" : "City"
        },
        "state": {
            "type"  : "string",
            "field" : "input",
            "label" : "State / Region"
        },
        "zip": {
            "type"  : "string",
            "field" : "input",
            "label" : "Postal Code"
        },
        "country": {
            "type"    : "string",
            "field"   : "select",
            "label"   : "Country",
            "options" : ["US", "CA", "GB", "DE", "FR"],
            "default" : "US"
        }
    }
}

Order schema — two cards, one referenced shape:

{
    "id": {
        "$ref"  : "https://www.totalcms.co/schemas/properties/id.json",
        "field" : "input",
        "label" : "Order ID"
    },
    "billing_address": {
        "$ref"      : "https://www.totalcms.co/schemas/properties/card.json",
        "field"     : "card",
        "label"     : "Billing Address",
        "schemaref" : "https://example.com/schemas/address.json"
    },
    "shipping_address": {
        "$ref"      : "https://www.totalcms.co/schemas/properties/card.json",
        "field"     : "card",
        "label"     : "Shipping Address",
        "schemaref" : "https://example.com/schemas/address.json"
    }
}

Resulting order object:

{
    "id": "ord-1042",
    "billing_address": {
        "street1" : "123 Main St",
        "street2" : "Suite 400",
        "city"    : "Austin",
        "state"   : "TX",
        "zip"     : "78701",
        "country" : "US"
    },
    "shipping_address": {
        "street1" : "456 Oak Ave",
        "street2" : "",
        "city"    : "Portland",
        "state"   : "OR",
        "zip"     : "97201",
        "country" : "US"
    }
}

In Twig:

<h3>Ship to</h3>
<address>
    {{ order.shipping_address.street1 }}<br>
    {% if order.shipping_address.street2 %}
        {{ order.shipping_address.street2 }}<br>
    {% endif %}
    {{ order.shipping_address.city }}, {{ order.shipping_address.state }} {{ order.shipping_address.zip }}<br>
    {{ order.shipping_address.country }}
</address>

The same pattern applies anywhere you'd otherwise duplicate field definitions — author bios, contact blocks, geographic coordinates, social-link sets. Define the shape once, reference it as many times as you need.

Common Use Cases

  • Grouped settings — sitemap, SEO, OpenGraph, schema.org metadata
  • Integration credentials — paired API keys and endpoints (combine with secret fields for the sensitive parts)
  • Feature toggles — a single features card with checkbox sub-fields
  • Reusable address blocks — billing/shipping/mailing addresses sharing one address schema (see Reusing a Card Schema)