> For the complete documentation index, see [llms.txt](https://help.checkoutbuilder.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://help.checkoutbuilder.com/widgets-1/conditions-code-editor.md).

# Conditions code editor

## Liquid Template Editor Guide

This guide explains how to write Liquid templates in our editor, including available objects, tags, and best practices.

### Template Structure

Liquid templates support three main types of markup:

#### Output

Display dynamic content using double curly braces:

```liquid
{{ cart.cost.total }}
```

#### Control Tags

Control flow using special tags:

```liquid
{% if customer.loggedIn %}
  Hello, customer!
{% endif %}
```

#### Comments

Document your code:

```liquid
{# Quick inline comment #}
{% comment %}
  Detailed explanation here
{% endcomment %}
```

## Available Objects

### Lines

The `lines` array contains information about each item in the cart. Each line item represents a product variant with its quantity and associated data.

#### Properties

**`id`**

* **Type**: `string`
* **Description**: Unique identifier for the line item
* **Example**: `"gid://shopify/LineItem/12345"`

**`quantity`**

* **Type**: `number`
* **Description**: Number of items of this variant in the cart
* **Example**: `2`

**`cost`**

* **Type**: `object`
* **Description**: Cost information for this line item
* **Properties**:
  * `totalAmount.amount` (`number`): Total cost for this line item including quantity

**`merchandise`**

* **Type**: `object`
* **Description**: Product variant information
* **Properties**:
  * `id` (`string`): Variant identifier
  * `title` (`string`): Product variant title
  * `selectedOptions` (`array`): Selected variant options
    * `name` (`string`): Option name (e.g., "Size")
    * `value` (`string`): Option value (e.g., "Small")
  * `product` (`object`): Parent product information
    * `id` (`string`): Product identifier
    * `vendor` (`string`): Product vendor name
    * `productType` (`string`): Product category/type
  * `requiresShipping` (`boolean`): Whether the item needs shipping
  * `sku` (`string`): Stock keeping unit

**`attributes`**

* **Type**: `array`
* **Description**: Custom attributes attached to the line item
* **Properties**:
  * `key` (`string`): Attribute key
  * `value` (`string`): Attribute value

#### Usage Example

```liquid
{% for line in lines %}
  ID: {{ line.id }}
  Quantity: {{ line.quantity }}
  Total: {{ line.cost.totalAmount.amount }}

  {# Access variant details #}
  {{ line.merchandise.title }}
  SKU: {{ line.merchandise.sku }}

  {# Show selected options #}
  {% for option in line.merchandise.selectedOptions %}
    {{ option.name }}: {{ option.value }}
  {% endfor %}
{% endfor %}
```

### Cart

The `cart` object contains overall information about the shopping cart, including totals and metadata.

#### Properties

**`currency`**

* **Type**: `string`
* **Description**: The currency code for the cart
* **Example**: `"USD"`

**`note`**

* **Type**: `string`
* **Description**: Customer notes attached to the cart
* **Example**: `"Please gift wrap"`

**`attributes`**

* **Type**: `array`
* **Description**: Custom attributes for the entire cart
* **Properties**:
  * `key` (`string`): Attribute key
  * `value` (`string`): Attribute value

**`quantity`**

* **Type**: `number`
* **Description**: Total number of items in the cart
* **Example**: `5`

**`cost`**

* **Type**: `object`
* **Description**: Detailed cost breakdown
* **Properties**:
  * `total` (`number`): Final cart total including all costs
  * `subtotal` (`number`): Sum of line items before tax/shipping
  * `tax` (`number`): Total tax amount
  * `shipping` (`number`): Shipping cost

#### Usage Example

```liquid
Cart Summary:
Total Items: {{ cart.quantity }}
Subtotal: {{ cart.cost.subtotal }}
Tax: {{ cart.cost.tax }}
Shipping: {{ cart.cost.shipping }}
Total: {{ cart.cost.total }}

{% if cart.note != blank %}
  Note: {{ cart.note }}
{% endif %}
```

### Customer

The `customer` object provides information about the current user's status and preferences.

#### Properties

**`loggedIn`**

* **Type**: `boolean`
* **Description**: Whether the customer is currently authenticated
* **Example**: `true`

**`acceptsEmailMarketing`**

* **Type**: `boolean`
* **Description**: Customer's email marketing preference
* **Example**: `true`

**`acceptsSmsMarketing`**

* **Type**: `boolean`
* **Description**: Customer's SMS marketing preference
* **Example**: `false`

#### Usage Example

```liquid
{% if customer.loggedIn %}
  Welcome back!

  Marketing Preferences:
  {% if customer.acceptsEmailMarketing %}
    ✓ Email updates enabled
  {% endif %}
  {% if customer.acceptsSmsMarketing %}
    ✓ SMS updates enabled
  {% endif %}
{% endif %}
```

### Shipping

The `shipping` object contains information about shipping methods and address details.

#### Properties

**`state`**

* **Type**: `string | null`
* **Description**: Shipping destination state/province code
* **Example**: `"AL"`

**`country`**

* **Type**: `string | null`
* **Description**: Shipping destination country code
* **Example**: `"US"`

**`selected`**

* **Type**: `object`
* **Description**: Currently selected shipping method
* **Properties**:
  * `label` (`string | null`): Display name of the shipping method
  * `type` (`'shipping' | 'local' | 'pickup' | 'pickupPoint' | null`): Display type of the shipping method

**`target`**

* **Type**: `object | null`
* **Description**: Target shipping method information. Only works when the widget is added under Delivery methods.
* **Properties**:
  * `isCurrentSelected` (`boolean`): Whether this method is selected
  * `code` (`string`): Shipping method identifier
  * `title` (`string`): Display name
  * `cost.amount` (`number`): Shipping cost amount

#### Usage Example

```liquid
Shipping to: {{ shipping.state }}, {{ shipping.country }}

{% if shipping.selected %}
  Selected Method: {{ shipping.selected.label }}
  Cost: {{ shipping.target.cost.amount }}
{% else %}
  Please select a shipping method
{% endif %}
```

### Order

The `order` object contains information about the current order being processed.

#### Properties

**`payment.selected`**

* **Type**: `object`
* **Description**: Selected payment method information
* **Properties**:
  * `type` (`'creditCard' | 'deferred' | 'local' | 'manualPayment' | 'offsite' | 'other' | 'paymentOnDelivery' | 'redeemable' | 'wallet' | 'customOnsite' | null`): Payment method type

**`metafields`**

* **Type**: `array`
* **Description**: Additional custom data attached to the order
* **Properties**:
  * `key` (`string`): Metafield identifier
  * `value` (`string`): Metafield value
  * `namespace` (`string`): Grouping namespace. use "checkoutbuilder" to access fields created with "Custom fields" widget.

#### Usage Example

```liquid
Payment Method: {{ order.payment.selected.type }}

Order Details:
{% for field in order.metafields %}
  {% if field.namespace == "checkoutbuilder" %}
    {{ field.key }}: {{ field.value }}
  {% endif %}
{% endfor %}
```

## Filters

The editor supports various filters to transform values. Filters are applied using the pipe character (`|`).

### String Filters

| Filter       | Description                             | Parameters                                                                               |
| ------------ | --------------------------------------- | ---------------------------------------------------------------------------------------- |
| `replace`    | Replaces all occurrences of a substring | <p><code>search</code> (string, required)<br><code>replace</code> (string, required)</p> |
| `upcase`     | Converts string to uppercase            | None                                                                                     |
| `downcase`   | Converts string to lowercase            | None                                                                                     |
| `capitalize` | Capitalizes the first character         | None                                                                                     |
| `append`     | Appends a string to the end             | `suffix` (string, required)                                                              |
| `prepend`    | Prepends a string to the beginning      | `prefix` (string, required)                                                              |
| `strip`      | Removes whitespace from both ends       | None                                                                                     |
| `split`      | Splits a string into an array           | `separator` (string, required)                                                           |

#### Example

```liquid
{% assign title = "hello world" %}
{{ title | capitalize | replace: "world", "everyone" }}
Output: "Hello everyone"

{{ "  spaces  " | strip }}
Output: "spaces"
```

### Number Filters

| Filter       | Description                    | Parameters                      |
| ------------ | ------------------------------ | ------------------------------- |
| `ceil`       | Rounds up to nearest integer   | None                            |
| `floor`      | Rounds down to nearest integer | None                            |
| `round`      | Rounds to nearest integer      | None                            |
| `divided_by` | Divides by a number            | `divisor` (number, required)    |
| `minus`      | Subtracts a number             | `subtrahend` (number, required) |
| `plus`       | Adds a number                  | `addend` (number, required)     |
| `times`      | Multiplies by a number         | `multiplier` (number, required) |

#### Example

```liquid
{{ 4.6 | ceil }}
Output: 5

{{ 10 | divided_by: 3 | round }}
Output: 3

{{ product.price | times: 0.8 | round }}
Output: Price with 20% discount
```

### Array Filters

| Filter  | Description                     | Parameters                                   |
| ------- | ------------------------------- | -------------------------------------------- |
| `first` | Returns the first element       | None                                         |
| `last`  | Returns the last element        | None                                         |
| `join`  | Joins elements with a separator | `separator` (string, optional, default: " ") |
| `size`  | Returns array length            | None                                         |

#### Example

```liquid
{% assign fruits = "apple,banana,orange" | split: "," %}
{{ fruits | join: " and " }}
Output: "apple and banana and orange"

{{ fruits | first }}
Output: "apple"

{{ fruits | size }}
Output: 3
```

### Filter Chaining

You can chain multiple filters together. They are applied from left to right.

```liquid
{{ "hello world" | capitalize | replace: "world", "everyone" | append: "!" }}
Output: "Hello everyone!"
```

> ⚠️ **Important Notes**
>
> * Maximum 3 filters per variable (see complexity rules)
> * Filters must match the input type they accept
> * Some filters change the value type (e.g., `split` converts string to array)
> * Use intermediate variables for complex transformations

## Control Flow

### Conditional Tags

Available tags:

* `if`/`elsif`/`else`/`endif`
* `unless`/`endunless`

Example:

```liquid
{% if cart.cost.total > 100 %}
  High-value cart
{% elsif cart.cost.total > 50 %}
  Medium-value cart
{% else %}
  Standard cart
{% endif %}
```

### Loops

Available controls:

* `for`/`endfor`
* `break`
* `continue`

> ⚠️ **Important Limitations**
>
> * Maximum 20 iterations per loop
> * No nested loops allowed
> * Range loops limited to 20 steps: `(1..20)`

Example:

```liquid
{% for line in lines %}
  {{ line.merchandise.title }}
  {% if line.quantity > 10 %}{% break %}{% endif %}
{% endfor %}
```

## Show/Hide System

### Basic Usage

Templates are hidden by default and must be explicitly shown:

```liquid
{% if cart.cost.total > 100 %}
  {% show %}
{% endif %}
```

```liquid
{% if cart.quantity == 0 %}
  {% hide %}
{% endif %}
```

> 📝 **Key Rules**
>
> * First show/hide tag wins
> * Processing stops at show/hide
> * Default state is hidden

## Template Complexity

### Limits

```typescript
{
  TOTAL_MAX: 50,        // Max complexity score
  LOOPS_MAX: 5,         // Max loops
  NESTING_MAX: 3,       // Max nesting
  CONDITIONS_MAX: 10,   // Max conditions
  ASSIGNMENTS_MAX: 15,  // Max assignments
  FILTERS_PER_VAR: 3    // Max filters per variable
}
```

### Scoring

Each element adds to complexity:

* Loop: +5 points
* Condition: +2 points
* Assignment: +1 point
* Filter: +1 point
* Large range loop: +3 extra points

## Best Practices

### 1. Optimize Loops

Pre-calculate values outside loops:

```liquid
{% assign total_cost = cart.cost.total %}
{% for line in lines %}
  {% if line.cost.totalAmount.amount > total_cost | divided_by: 2 %}
    High-value item: {{ line.merchandise.title }}
  {% endif %}
{% endfor %}
```

### 2. Use Early Exits

Exit early when possible:

```liquid
{% if cart.quantity == 0 %}
  {% hide %}
{% endif %}
```

### 3. Keep Filters Simple

Avoid long filter chains:

```liquid
{# Good #}
{% assign title = line.merchandise.title | upcase %}
{{ title | replace: "OLD", "NEW" }}

{# Avoid #}
{{ line.merchandise.title | upcase | replace: "OLD", "NEW" | strip }}
```

### 4. Handle Null Values

Always check for null:

```liquid
{% if shipping.selected %}
  {{ shipping.selected.label }}
{% else %}
  Select shipping method
{% endif %}
```

### 5. Document Complex Logic

Use comments for clarity:

```liquid
{% comment %}
  Express shipping requirements:
  - Cart total > 100
  - All items need shipping
  - Customer logged in
{% endcomment %}
```

### 6. Optimize Property Usage

Each property access in your template triggers a recalculation when that property changes. To ensure optimal performance:

* Only use properties that are necessary for your logic
* Remove debug statements before saving
* Avoid accessing deeply nested properties repeatedly

```liquid
{# Bad - Accessing unnecessary properties #}
{% if customer.loggedIn and customer.acceptsEmailMarketing and customer.acceptsSmsMarketing %}
  {{ cart.cost.total }}
  {{ cart.cost.subtotal }}
  {{ cart.cost.tax }}
{% endif %}

{# Good - Only using required properties #}
{% if customer.loggedIn %}
  {{ cart.cost.total }}
{% endif %}
```

```liquid
{# Bad - Repeated deep property access #}
{% for line in lines %}
  {{ line.merchandise.product.title }}
  {% if line.merchandise.product.vendor == "Specific" %}
    {{ line.merchandise.product.productType }}
  {% endif %}
{% endfor %}

{# Good - Assign deep properties to variables #}
{% for line in lines %}
  {% assign product = line.merchandise.product %}
  {{ product.title }}
  {% if product.vendor == "Specific" %}
    {{ product.productType }}
  {% endif %}
{% endfor %}
```

> ⚠️ **Performance Impact**
>
> * Each property access creates a dependency
> * Changes to any accessed property trigger template recalculation
> * Unused property access impacts performance unnecessarily
> * Debug statements should be removed in production
