> ## Documentation Index
> Fetch the complete documentation index at: https://docs.omni.co/llms.txt
> Use this file to discover all available pages before exploring further.

<AgentInstructions>

## Submitting Feedback

If you encounter incorrect, outdated, or confusing documentation on this page, submit feedback:

POST https://docs.omni.co/feedback

```json
{
  "path": "/modeling/models/custom-formats",
  "feedback": "Description of the issue"
}
```

Only submit feedback when you have something specific and actionable to report.

</AgentInstructions>

# custom_formats

> Define reusable format objects that can be referenced in dimension and measure format parameters.

Custom formats are format objects that can be defined once in a [model file](/modeling/models) and referenced throughout your model. Unlike [constants](/modeling/models/constants), which hold string values, custom formats are complete format objects that can include conditional logic, named formats, Excel-style strings, and other [format features](/modeling/models/format-values).

Custom formats are resolved when formatting values in queries and visualizations, making them ideal for format patterns that need to be centrally managed and consistently applied across multiple fields. For example:

* Complex conditional formats that vary based on field values
* Format patterns that include named formats or custom strings
* Formats that need to be maintained in a single location and used across multiple dimensions or measures

Custom formats are also inherited by [shared extension models](/modeling/develop/shared-extensions).

## Syntax

`custom_formats` accepts either a string or a conditional object:

<Tabs>
  <Tab title="String">
    ```yaml theme={null}
    custom_formats:
      <format_name>: <format_string>
    ```
  </Tab>

  <Tab title="Conditional">
    ```yaml theme={null}
    custom_formats:
      <format_name>:
        depends_on:
          <field|user_attribute|filter>: <field_name|user_attribute_reference|filter_name>
          conditions:
            - condition:
                <filter_expression>
              value: <format_string>
        else: <fallback_format_string>
    ```
  </Tab>
</Tabs>

## Properties

`custom_formats` is a map of format definitions where each key is the format name. Names must be unique within the model.

<Tabs>
  <Tab title="String" id="string-properties">
    <ParamField path="format_name" type="string" required>
      The format definition. This can be any valid [format type](/modeling/models/format-values#choosing-a-format-type):

      * A named format (e.g., `currency_2`, `percent_1`)
      * An Excel-style string (e.g., `'#,##0.00 "kg"'`)
      * A [reference](#reference-custom-format) to another custom format
    </ParamField>
  </Tab>

  <Tab title="Conditional" id="conditional-properties">
    <ParamField path="depends_on" type="object" required>
      Defines the source value to evaluate conditions against. Set exactly one of `field`, `user_attribute`, or `filter`.

      These options resolve as follows:

      | Source           | Resolution timing         | Behavior                                                                                                         |
      | ---------------- | ------------------------- | ---------------------------------------------------------------------------------------------------------------- |
      | `field`          | At display time (per row) | Evaluated against each row's value after query results are returned. Each row can resolve to a different format. |
      | `user_attribute` | At query preparation time | The user attribute value is evaluated once. The entire field uses the single resolved format.                    |
      | `filter`         | At query preparation time | The filter value is evaluated once. The entire field uses the single resolved format.                            |

      <Expandable title="depends_on properties" defaultOpen="true">
        <ParamField path="field" type="string">
          The name of a field in the same view.
        </ParamField>

        <ParamField path="user_attribute" type="string">
          The reference of a [user attribute](/administration/users/attributes).
        </ParamField>

        <ParamField path="filter" type="string">
          The name of a filter applied to the query.
        </ParamField>

        <ParamField path="conditions" type="object[]" required>
          An ordered list of condition entries. Each entry contains a `condition` using [Omni filter syntax](/modeling/filters) and a `value` specifying the format string to apply when the condition matches.

          <Expandable title="conditions properties" defaultOpen="true">
            <ParamField path="condition" type="object" required>
              An Omni filter expression. Supported condition types:

              | Condition                  | Description                    | Example                            |
              | -------------------------- | ------------------------------ | ---------------------------------- |
              | `is`                       | Exact match                    | `is: "USD"`                        |
              | `not`                      | Not equal                      | `not: "USD"`                       |
              | `greater_than`             | Greater than                   | `greater_than: "1000"`             |
              | `greater_than_or_equal_to` | Greater than or equal to       | `greater_than_or_equal_to: "1000"` |
              | `less_than`                | Less than                      | `less_than: "0"`                   |
              | `less_than_or_equal_to`    | Less than or equal to          | `less_than_or_equal_to: "100"`     |
              | `between`                  | Between two values (inclusive) | `between: [10, 100]`               |
              | `not_between`              | Outside a range                | `not_between: [10, 100]`           |
              | `starts_with`              | String starts with             | `starts_with: "US"`                |
              | `ends_with`                | String ends with               | `ends_with: "Corp"`                |
              | `contains`                 | String contains                | `contains: "special"`              |
              | `not_starts_with`          | String does not start with     | `not_starts_with: "US"`            |
              | `not_ends_with`            | String does not end with       | `not_ends_with: "Corp"`            |
              | `not_contains`             | String does not contain        | `not_contains: "special"`          |

              Additional conditions follow the same structure as [filters](/modeling/filters).
            </ParamField>

            <ParamField path="value" type="string" required>
              The format string to apply when the condition matches. Can be a named format or an Excel-style string.
            </ParamField>
          </Expandable>
        </ParamField>
      </Expandable>
    </ParamField>

    <ParamField path="else" type="string">
      Fallback format string used when no condition matches.
    </ParamField>
  </Tab>
</Tabs>

## Difference from constants

While both `custom_formats` and [`constants`](/modeling/models/constants) enable reusability, they serve different purposes:

* Use `custom_formats` when you need to define a complete format object that will be used across multiple fields
* Use `constants` when you need a reusable string value that might be used in format strings or other contexts

<h2 id="reference-custom-format">
  Referencing custom formats
</h2>

Once defined in the model file, custom formats can be referenced in [dimension](/modeling/dimensions/parameters/format) and [measure](/modeling/measures/parameters/format) `format` parameters using either a plain string or explicit object syntax:

**Plain string syntax** (recommended):

```yaml theme={null}
format: <format_name>
```

**Explicit object syntax**:

```yaml theme={null}
format:
  custom_format: <format_name>
```

The plain string syntax is the recommended approach — it's cleaner and more concise.

## Examples

### Named format reference

Define custom formats that reference built-in named formats:

```yaml title="Model file" theme={null}
custom_formats:
  standard_currency: currency_2
  high_precision: number_4
  compact_number: big_1
```

```yaml title="View file" theme={null}
dimensions:
  price:
    sql: '"price"'
    format: standard_currency
measures:
  total_revenue:
    sql: '"amount"'
    aggregate_type: sum
    format: standard_currency
```

### Excel-style strings

Define custom formats with Excel-style strings:

```yaml title="Model file" theme={null}
custom_formats:
  weight_display: '#,##0.00 "kg"'
  margin_bps: '#,##0.00 "bps"'
  compact_time: 'm:ss "min"'
```

```yaml title="View file" theme={null}
dimensions:
  product_weight:
    sql: '"weight"'
    format: weight_display
measures:
  avg_margin:
    sql: '"margin"'
    aggregate_type: avg
    format: margin_bps
```

### Conditional formats

Define custom formats with conditional logic that selects different formats based on field values:

```yaml title="Model file" theme={null}
custom_formats:
  dynamic_currency:
    depends_on:
      field: orders.currency_code
      conditions:
        - condition:
            equals: USD
          value: usdcurrency_2
        - condition:
            equals: GBP
          value: gbpcurrency_2
        - condition:
            equals: EUR
          value: eurcurrency_2
    else: currency_2
  
  performance_indicator:
    depends_on:
      field: metrics.status
      conditions:
        - condition:
            equals: excellent
          value: '"🚀 "0.0'
        - condition:
            equals: poor
          value: '"📉 "-0.0'
    else: number_2
```

```yaml title="View file" theme={null}
dimensions:
  total_amount:
    sql: '"amount"'
    format: dynamic_currency
measures:
  performance_score:
    sql: '"score"'
    aggregate_type: avg
    format: performance_indicator
```

### Combining custom formats with model constants

Custom formats can reference [model constants](/modeling/models/constants) to create even more flexible formatting patterns.

<Tabs>
  <Tab title="Use constants to add a unit suffix">
    ```yaml title="Model file" theme={null}
    constants:
      unit_suffix:
        value: "units"

    custom_formats:
      quantity_format: '#,##0 "@{unit_suffix}"'
    ```

    ```yaml title="View file" theme={null}
    measures:
      total_quantity:
        sql: '"quantity"'
        aggregate_type: sum
        format: quantity_format
    ```
  </Tab>

  <Tab title="Use contstants to specify time and numeric formats with suffixes">
    ```yaml title="Model file" theme={null}
    constants:
      compact_time:
        value: 'm:ss "min"'
      margin_display:
        value: '#,##0.00 "bps"'
    ```

    ```yaml title="View file" theme={null}
    measures:
      avg_duration:
        sql: '"duration_secs"'
        aggregate_type: avg
        format: "@{compact_time}"
      margin:
        sql: '"margin_bps"'
        aggregate_type: avg
        format: "@{margin_display}"
    ```
  </Tab>
</Tabs>
