# 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


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://help.checkoutbuilder.com/widgets-1/conditions-code-editor.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
