## Liquid Drops (Objects Available in Templates)

Modyo provides **Liquid drops** - predefined objects accessible in all templates (snippets, widgets, pages, layouts). These objects are documented at [Modyo Liquid Objects](https://docs.modyo.com/en/platform/channels/liquid-markup/objects.html).

### Core Objects

#### 1. `account` - Platform Information
```liquid
{{ account.url }}         // Platform URL
{{ account.host }}        // Platform subdomain
{{ account.google_key }}  // Google auth credential
```

#### 2. `site` - Current Site
```liquid
{{ site.name }}           // Site name
{{ site.description }}    // Site description
{{ site.language }}       // Site language (en, es, pt)
{{ site.logo }}           // Logo URL
{{ site.url }}            // Site URL
```

#### 3. `page` - Current Page
```liquid
{{ page.content }}        // Page HTML content
{{ page.name }}           // Page name
{{ page.url }}            // Page URL
{{ page.title }}          // Page title
{{ page.description }}    // Page description
{{ page.grid }}           // Associated grid object
```

#### 4. `page_grid` - Widget Layout
```liquid
{{ page_grid.id }}              // Grid ID
{{ page_grid.cache_key }}       // Cache key
{{ page_grid.main_widgets }}    // All widgets (single column)
{{ page_grid.column_0 }}        // Widgets in column 0
{{ page_grid.column_1 }}        // Widgets in column 1
{{ page_grid.column_2 }}        // Widgets in column 2
{{ page_grid.sidebar }}         // Sidebar widgets
```

#### 5. `widget` - Current Widget
```liquid
{{ widget.wid }}                // Widget instance ID
{{ widget.version }}            // Widget version
{{ widget.sync }}               // Sync mode (true/false)
{{ widget.css }}                // Widget CSS
{{ widget.html }}               // Widget HTML
{{ widget.js }}                 // Widget JS
{{ widget.name }}               // Widget name
{{ widget.manager_uuid }}       // Widget definition UUID (OID)
```

#### 6. `entry` - Content Entry
```liquid
{{ entry.space }}         // Space name
{{ entry.category }}      // Category path
{{ entry.type }}          // Entry type
{{ entry.tags }}          // Entry tags
{{ entry.excerpt }}       // Entry excerpt
{{ entry.author }}        // Entry author
{{ entry.fields }}        // Custom fields collection
```

#### 7. `category` - Content Category
```liquid
{{ category.id }}         // Category ID
{{ category.slug }}       // Category slug
{{ category.name }}       // Category name
{{ category.url }}        // Canonical URL
{{ category.children }}   // Child categories
{{ category.parent }}     // Parent category
{{ category.siblings }}   // Sibling categories
```

#### 8. `asset` - Media Asset
```liquid
{{ asset.data_file_name }}  // Filename
{{ asset.description }}     // Description
{{ asset.title }}          // Title
{{ asset.uuid }}           // UUID
{{ asset.url }}            // CDN URL
```

#### 9. `admin_user` - Administrator
```liquid
{{ admin_user.avatar }}     // Avatar URL
{{ admin_user.email }}      // Email
{{ admin_user.first_name }} // First name
{{ admin_user.last_name }}  // Last name
{{ admin_user.name }}       // Full name
```

#### 10. `form` - Forms
```liquid
{{ form.slug }}            // Form identifier
{{ form.alternative }}     // Form alternative
{{ form.answer }}          // Form answer
{{ form.form_response }}   // Form response
{{ form.question }}        // Form question
```

### Context Availability

Different objects are available in different contexts:

| Object | Snippets | Widgets | Pages | Layouts | Templates |
|--------|----------|---------|-------|---------|-----------|
| `account` | ✅ | ✅ | ✅ | ✅ | ✅ |
| `site` | ✅ | ✅ | ✅ | ✅ | ✅ |
| `page` | ✅ | ✅ | ✅ | ✅ | ❌ |
| `page_grid` | ✅ | ❌ | ✅ | ✅ | ❌ |
| `widget` | ✅ | ✅ | ❌ | ❌ | ❌ |
| `entry` | ✅ | ✅ | ✅ | ✅ | ❌ |
| `category` | ✅ | ✅ | ✅ | ✅ | ❌ |
| `asset` | ✅ | ✅ | ✅ | ✅ | ✅ |
| `admin_user` | ✅ | ✅ | ✅ | ✅ | ✅ |
| `form` | ✅ | ✅ | ✅ | ✅ | ❌ |

### Usage Examples

#### In Snippets
```liquid
<!-- snippets/header.liquid -->
<header>
  <img src="{{ site.logo }}" alt="{{ site.name }}">
  <h1>{{ site.name }}</h1>
</header>
```

#### In Widgets
```liquid
<!-- Widget HTML -->
<div class="widget-container">
  <h2>{{ widget.name }}</h2>
  {% if site.language == 'es' %}
    <p>Idioma: Español</p>
  {% else %}
    <p>Language: English</p>
  {% endif %}
</div>
```

#### In Pages (Content Type)
```liquid
<article>
  <h1>{{ entry.fields.title }}</h1>
  <p>{{ entry.excerpt }}</p>
  <div class="meta">
    <span>Category: {{ entry.category.name }}</span>
    <span>Author: {{ entry.author.name }}</span>
  </div>
  <div class="content">
    {{ entry.fields.body }}
  </div>
</article>
```

#### In Grids
```liquid
<!-- Grid snippet -->
<div class="grid-container">
  <div class="main-column">
    {% for widget in page_grid.column_0 %}
      {% snippet widget %}
    {% endfor %}
  </div>
  <div class="sidebar">
    {% for widget in page_grid.sidebar %}
      {% snippet widget %}
    {% endfor %}
  </div>
</div>
```

### Special Variables

#### `csp_nonce`
Content Security Policy nonce for inline scripts/styles:
```liquid
<script nonce="{{csp_nonce}}">
  // Safe inline JavaScript
</script>
<style nonce="{{csp_nonce}}">
  /* Safe inline CSS */
</style>
```

#### `content_for_layout`
In layouts, placeholder for page content:
```liquid
<html>
<body>
  {% snippet 'header' %}
  <main>
    {{ content_for_layout }}  <!-- Page content renders here -->
  </main>
  {% snippet 'footer' %}
</body>
</html>
```

### Important Notes

1. **All objects are read-only** - You cannot modify these objects in Liquid
2. **Context-specific** - Not all objects available in all contexts
3. **Cached** - Some objects like `page_grid` have cache keys for performance
4. **Nested access** - Use dot notation: `entry.fields.custom_field`
5. **Safe by default** - All output is HTML-escaped unless using `| raw` filter

### Liquid Filters

Common filters available on all objects:

```liquid
{{ site.name | upcase }}              // SITE NAME
{{ page.description | truncate: 100 }} // Truncate to 100 chars
{{ entry.created_at | date: "%Y-%m-%d" }} // Format date
{{ asset.url | img_tag }}             // Generate <img> tag
{{ widget.css | raw }}                // Output without escaping
```

---

## Variable System in Modyo

Modyo supports **three types of variables** for passing data in templates, snippets, widgets, and pages. Understanding when to use each type is critical for building maintainable sites.

### Overview

| Variable Type | Syntax | Scope | Management | Use Case |
|--------------|--------|-------|------------|----------|
| **Global Variables** | `{{ vars.NAME }}` or `{{ vars["NAME"] }}` | Account/Site/Widget-wide | Global Variables API | Configuration, API keys, feature flags |
| **Local Variables** | `{{ MY_VARIABLE }}` | Current template only | `{% assign %}` tag | Temporary values, loop variables, calculations |
| **Snippet Parameters** | Passed via `{% snippet %}` | Snippet invocation | Snippet call arguments | Passing data to reusable snippets |

---

### 1. Global Variables (`vars`)

**Global variables** are managed through the Global Variables API and available across multiple contexts.

#### Scope Hierarchy

Global variables exist at **four levels** with a clear override hierarchy:

```
┌─────────────────────────────────────────────────────────────┐
│ 1. Account-Level Variables (Global)                         │
│ - Available across ALL sites in the account                 │
│ - Lowest priority (can be overridden by all other levels)   │
│ - Examples: Shared API endpoints, platform-wide configs     │
└─────────────────────┬───────────────────────────────────────┘
                      │
                      ▼
┌─────────────────────────────────────────────────────────────┐
│ 2. Channel/Site-Level Variables                             │
│ - Available in ALL pages/widgets in the specific site       │
│ - Override account-level variables with same name           │
│ - IMPORTANT: Site vars are NOT reused across stages         │
│   (dev site vars ≠ staging site vars ≠ prod site vars)      │
│ - Examples: Site-specific branding, site API keys           │
└─────────────────────┬───────────────────────────────────────┘
                      │
                      ▼
┌─────────────────────────────────────────────────────────────┐
│ 3. Widget Definition-Level Variables                        │
│ - Defined in widget definition configuration                │
│ - Override site and account variables with same name        │
│ - Available when widget is used on any page                 │
│ - Examples: Widget-specific API endpoints, widget configs   │
└─────────────────────┬───────────────────────────────────────┘
                      │
                      ▼
┌─────────────────────────────────────────────────────────────┐
│ 4. Page-Level Widget Instance Variables                     │
│ - Override widget definition variables when adding widget   │
│   to specific page                                          │
│ - Highest priority among global variables                   │
│ - Same widget can have different vars on different pages    │
│ - Examples: Page-specific widget configuration              │
└─────────────────────────────────────────────────────────────┘
```

#### Important Notes on Scope

**Channel/Site Variables and Stages**:
- Each site has its own set of variables
- Variables are **NOT shared across stages** (development, staging, production)
- Each stage is treated as a separate site with its own variable configuration
- Example: `vars.api_endpoint` in dev site can be `https://dev-api.example.com` while prod site has `https://api.example.com`

**Widget Variables on Pages**:
- When adding a widget to a page, you can override widget definition variables
- This allows the same widget to behave differently on different pages
- Page-level overrides only affect that specific widget instance on that page
- Other instances of the same widget on other pages use widget definition variables (unless also overridden)

#### Syntax

**Dot notation** (recommended):
```liquid
{{ vars.api_endpoint }}
{{ vars.feature_flag_enabled }}
{{ vars.primary_color }}
```

**Bracket notation** (for dynamic names or special characters):
```liquid
{{ vars["api_endpoint"] }}
{{ vars["feature-flag-enabled"] }}  // Hyphens require brackets
{{ vars[variable_name] }}           // Dynamic lookup
```

#### Creating Global Variables

**Account-level**:
```typescript
global-variable-create({
  platformSlug: "fed-team",
  application_type: "account",
  application_id: 1,
  slug: "api_endpoint",
  global_variable_values_attributes: [
    {
      lang: "en",
      default: true,
      value: "https://api.example.com",
      values: null
    }
  ]
})
```

**Site-level**:
```typescript
global-variable-create({
  platformSlug: "fed-team",
  application_type: "site",
  application_id: 4605,
  slug: "site_primary_color",
  global_variable_values_attributes: [
    {
      lang: "en",
      default: true,
      value: "#FF6600",
      values: null
    }
  ]
})
```

**Widget-level**:
```typescript
widget-definitions-variable-create({
  platformSlug: "fed-team",
  siteId: 4605,
  widgetId: 123,
  slug: "widget_api_key",
  variable: {
    lang: "en",
    default: true,
    value: "abc123",
    values: null
  }
})
```

**Page-level (Widget Instance)**:
When adding a widget to a page, you can override widget definition variables:

```typescript
page-add-widgets({
  platformSlug: "fed-team",
  siteId: 4605,
  pageId: 12345,
  widgets: [
    {
      type: "custom_widget",
      definition_uuid: "ac2fe2d381f5436e52b1cea8a37e0a8a2faf5260",
      column: 0,
      position: 0,
      // Override widget definition variables for this page instance
      variables: [
        {
          slug: "api_endpoint",
          value: "https://homepage-api.example.com"  // Page-specific override
        },
        {
          slug: "feature_enabled",
          value: "true"
        }
      ]
    }
  ]
})
```

**Result**: This widget instance on this page will use `https://homepage-api.example.com` for `{{ vars.api_endpoint }}`, overriding the widget definition's default value. Other instances of the same widget on different pages will still use the widget definition's value (unless they also have page-level overrides).

#### Usage Examples

**In widgets**:
```liquid
<script>
  const API_ENDPOINT = "{{ vars.api_endpoint }}";
  const FEATURE_ENABLED = {{ vars.feature_flag_enabled }};
</script>

<div style="background-color: {{ vars.primary_color }}">
  <!-- Content -->
</div>
```

**In snippets**:
```liquid
<!-- snippets/api_client.liquid -->
<script>
  window.API_CONFIG = {
    endpoint: "{{ vars.api_endpoint }}",
    timeout: {{ vars.api_timeout }},
    debug: {{ vars.debug_mode }}
  };
</script>
```

**In layouts**:
```liquid
<head>
  <meta name="theme-color" content="{{ vars.theme_color }}">
  <link rel="stylesheet" href="{{ vars.cdn_url }}/styles.css">
</head>
```

#### Best Practices

✅ **Use for**:
- API endpoints and credentials
- Feature flags
- Theme colors and branding
- CDN URLs
- Configuration that changes per environment

❌ **Don't use for**:
- Temporary calculations
- Loop variables
- Snippet-specific data

---

### 2. Local Variables (Assign)

**Local variables** are declared inline using `{% assign %}` and exist only in the current template scope.

#### Syntax

**Declaration**:
```liquid
{% assign MY_VARIABLE = "value" %}
{% assign count = 0 %}
{% assign total_price = product.price | times: quantity %}
```

**Usage**:
```liquid
{{ MY_VARIABLE }}
{{ count }}
{{ total_price | money }}
```

#### Scope

Local variables are **scoped to the current template file** and do not persist across snippet includes:

```liquid
<!-- page.liquid -->
{% assign page_title = "Welcome" %}
{{ page_title }}  <!-- ✅ Works: "Welcome" -->

{% snippet 'header' %}

<!-- snippets/header.liquid -->
{{ page_title }}  <!-- ❌ Undefined: Variable not in scope -->
```

#### Examples

**Calculations**:
```liquid
{% assign subtotal = 0 %}
{% for item in cart_items %}
  {% assign item_total = item.price | times: item.quantity %}
  {% assign subtotal = subtotal | plus: item_total %}
{% endfor %}

<p>Subtotal: {{ subtotal | money }}</p>
```

**Conditionals**:
```liquid
{% assign is_mobile = false %}
{% if page.user_agent contains "Mobile" %}
  {% assign is_mobile = true %}
{% endif %}

{% if is_mobile %}
  <div class="mobile-view">...</div>
{% else %}
  <div class="desktop-view">...</div>
{% endif %}
```

**String manipulation**:
```liquid
{% assign full_name = user.first_name | append: " " | append: user.last_name %}
{% assign slug = page.title | downcase | replace: " ", "-" %}

<h1>{{ full_name }}</h1>
<meta property="og:url" content="{{ site.url }}/{{ slug }}">
```

**Before using in snippets** (declare in parent template):
```liquid
<!-- page.liquid -->
{% assign highlight_color = "#FF6600" %}
{% assign show_badges = true %}

{% snippet 'product_card', color: highlight_color, badges: show_badges %}
```

#### Best Practices

✅ **Use for**:
- Temporary calculations
- Loop variables
- Conditional values
- String manipulation
- Template-specific logic

❌ **Don't use for**:
- Configuration shared across site
- Data that needs to persist
- Values needed in multiple templates

---

### 3. Snippet Parameters

**Snippet parameters** are passed when calling a snippet, allowing you to pass data from the parent template to the reusable snippet.

#### Syntax

**Passing parameters**:
```liquid
{% snippet 'snippet_name', param1: 'value1', param2: 'value2' %}
```

**Accessing in snippet**:
```liquid
<!-- snippets/snippet_name.liquid -->
{{ param1 }}  <!-- "value1" -->
{{ param2 }}  <!-- "value2" -->
```

#### Examples

**Simple parameter passing**:
```liquid
<!-- page.liquid -->
{% snippet 'product_card', product_name: 'Widget', price: 29.99 %}

<!-- snippets/product_card.liquid -->
<div class="product">
  <h3>{{ product_name }}</h3>
  <span class="price">${{ price }}</span>
</div>
```

**With assigned variables**:
```liquid
<!-- page.liquid -->
{% assign highlight_color = "#FF6600" %}
{% assign discount_percent = 20 %}

{% snippet 'promo_banner', color: highlight_color, discount: discount_percent %}

<!-- snippets/promo_banner.liquid -->
<div style="background-color: {{ color }}">
  <p>Save {{ discount }}% today!</p>
</div>
```

**Complex object passing**:
```liquid
<!-- page.liquid -->
{% for product in products %}
  {% snippet 'product_card', product: product, show_badges: true %}
{% endfor %}

<!-- snippets/product_card.liquid -->
<div class="product-card">
  <h3>{{ product.name }}</h3>
  <p>{{ product.description }}</p>
  <span class="price">{{ product.price | money }}</span>
  {% if show_badges %}
    <span class="badge">New</span>
  {% endif %}
</div>
```

**Passing multiple types**:
```liquid
{% snippet 'banner',
  title: 'Welcome',
  subtitle: 'Get started today',
  button_text: 'Sign Up',
  button_url: '/signup',
  background_color: vars.primary_color,
  show_icon: true
%}

<!-- snippets/banner.liquid -->
<section style="background-color: {{ background_color }}">
  <h1>{{ title }}</h1>
  <p>{{ subtitle }}</p>
  {% if show_icon %}
    <i class="icon-star"></i>
  {% endif %}
  <a href="{{ button_url }}">{{ button_text }}</a>
</section>
```

#### Special: `with` Syntax

**Shorthand for single object parameter**:
```liquid
{% snippet 'product_card' with product %}

<!-- Equivalent to: -->
{% snippet 'product_card', product_card: product %}

<!-- In snippet, access as: -->
{{ product_card.name }}
{{ product_card.price }}
```

#### Best Practices

✅ **Use for**:
- Passing data to reusable snippets
- Component configuration
- Loop iteration data
- Dynamic content in snippets

❌ **Don't use for**:
- Global configuration (use `vars`)
- Internal snippet logic (use `{% assign %}`)

---

### Variable Precedence

When the same variable name exists in multiple contexts, Modyo resolves them in this priority order:

```
┌─────────────────────────────────────────────────────────────┐
│ Priority 1: Snippet Parameters (Highest)                     │
│ - Passed during snippet call                                │
│ - Overrides ALL other variable types                        │
└─────────────────────┬───────────────────────────────────────┘
                      │
                      ▼
┌─────────────────────────────────────────────────────────────┐
│ Priority 2: Local Variables ({% assign %})                  │
│ - Template-scoped assignments                               │
│ - Overrides global vars in same template                   │
└─────────────────────┬───────────────────────────────────────┘
                      │
                      ▼
┌─────────────────────────────────────────────────────────────┐
│ Priority 3: Page-Level Widget Instance Variables            │
│ - Set when adding widget to specific page                  │
│ - Overrides widget definition, site, and account vars      │
└─────────────────────┬───────────────────────────────────────┘
                      │
                      ▼
┌─────────────────────────────────────────────────────────────┐
│ Priority 4: Widget Definition-Level Variables               │
│ - Defined in widget definition settings                    │
│ - Overrides site and account vars                          │
└─────────────────────┬───────────────────────────────────────┘
                      │
                      ▼
┌─────────────────────────────────────────────────────────────┐
│ Priority 5: Channel/Site-Level Variables                    │
│ - Defined for specific site                                │
│ - NOT shared across stages                                 │
│ - Overrides account vars                                   │
└─────────────────────┬───────────────────────────────────────┘
                      │
                      ▼
┌─────────────────────────────────────────────────────────────┐
│ Priority 6: Account-Level Variables (Lowest)                │
│ - Global across all sites                                  │
│ - Used only if not overridden at any other level           │
└─────────────────────────────────────────────────────────────┘
```

**Complete Example**:
```liquid
<!-- Account var: vars.api_endpoint = "https://account-api.example.com" -->
<!-- Site var: vars.api_endpoint = "https://site-api.example.com" -->
<!-- Widget definition var: vars.api_endpoint = "https://widget-api.example.com" -->
<!-- Page-level widget instance var: vars.api_endpoint = "https://page-api.example.com" -->

<!-- In widget on page: -->
{% assign api_endpoint = "https://local-api.example.com" %}
{% snippet 'api_client', api_endpoint: "https://snippet-api.example.com" %}

<!-- Priority resolution for {{ api_endpoint }}: -->
<!-- 1. Snippet param: "https://snippet-api.example.com" (WINS if inside snippet) -->
<!-- 2. Local var: "https://local-api.example.com" (WINS if in main widget) -->
<!-- 3. Page-level: "https://page-api.example.com" (if no local override) -->
<!-- 4. Widget def: "https://widget-api.example.com" (if no page override) -->
<!-- 5. Site var: "https://site-api.example.com" (if no widget override) -->
<!-- 6. Account var: "https://account-api.example.com" (if no site override) -->

<!-- For {{ vars.api_endpoint }} access (global vars only): -->
<!-- 1. Page-level widget instance: "https://page-api.example.com" (WINS) -->
<!-- 2. Widget definition: "https://widget-api.example.com" (if no page override) -->
<!-- 3. Site: "https://site-api.example.com" (if no widget override) -->
<!-- 4. Account: "https://account-api.example.com" (if no site override) -->
```

**Key Insight**: When you access `{{ vars.api_endpoint }}` in a widget on a page, Modyo checks:
1. Does this widget instance on this page have a page-level override? → Use it
2. Does the widget definition have a widget-level variable? → Use it
3. Does the site have a site-level variable? → Use it
4. Does the account have an account-level variable? → Use it
5. If none exist → Variable is undefined

---

### Complete Example: Using All Variable Types

#### Scenario: Product Listing Widget Used on Multiple Pages

**Setup**:
```typescript
// Account-level variable (global)
global-variable-create({
  application_type: "account",
  application_id: 1,
  slug: "api_timeout",
  global_variable_values_attributes: [{ value: "5000" }]  // 5 seconds
})

// Site-level variable (production site only)
global-variable-create({
  application_type: "site",
  application_id: 4605,  // Production site
  slug: "api_endpoint",
  global_variable_values_attributes: [{ value: "https://api.example.com" }]
})

// Widget definition variable
widget-definitions-variable-create({
  widgetId: 123,  // Product List Widget
  slug: "products_per_page",
  variable: { value: "20" }  // Default: 20 products
})

// Page 1: Homepage (override to show 10 products)
page-add-widgets({
  pageId: 456,
  widgets: [{
    definition_uuid: "...",
    variables: [
      { slug: "products_per_page", value: "10" },  // Homepage: 10 products
      { slug: "show_filters", value: "false" }     // Homepage: No filters
    ]
  }]
})

// Page 2: Catalog Page (override to show 50 products)
page-add-widgets({
  pageId: 789,
  widgets: [{
    definition_uuid: "...",
    variables: [
      { slug: "products_per_page", value: "50" },  // Catalog: 50 products
      { slug: "show_filters", value: "true" }      // Catalog: Show filters
    ]
  }]
})
```

**Widget Code** (Product List Widget):
```liquid
<!-- Widget HTML -->
<div class="product-list">
  <!-- Global variables with full hierarchy -->
  <script>
    const API_CONFIG = {
      endpoint: "{{ vars.api_endpoint }}",     // Site-level
      timeout: {{ vars.api_timeout }},         // Account-level
      perPage: {{ vars.products_per_page }}    // Page-level (homepage: 10, catalog: 50)
    };
  </script>

  <!-- Local variable for calculations -->
  {% assign total_pages = total_products | divided_by: vars.products_per_page %}

  <h2>Products (Page 1 of {{ total_pages }})</h2>

  <!-- Conditional based on page-level variable -->
  {% if vars.show_filters == "true" %}
    <div class="filters">
      <!-- Filter UI -->
    </div>
  {% endif %}

  <!-- Loop through products -->
  {% for product in products limit: vars.products_per_page %}
    <!-- Snippet parameters -->
    {% snippet 'product_card',
      product: product,
      show_price: true,
      currency: 'USD'
    %}
  {% endfor %}
</div>
```

**On Homepage** (pageId: 456):
- `{{ vars.api_endpoint }}` → `"https://api.example.com"` (site-level)
- `{{ vars.api_timeout }}` → `5000` (account-level)
- `{{ vars.products_per_page }}` → `10` (page-level override)
- `{{ vars.show_filters }}` → `"false"` (page-level override)

**On Catalog Page** (pageId: 789):
- `{{ vars.api_endpoint }}` → `"https://api.example.com"` (site-level)
- `{{ vars.api_timeout }}` → `5000` (account-level)
- `{{ vars.products_per_page }}` → `50` (page-level override)
- `{{ vars.show_filters }}` → `"true"` (page-level override)

**On Any Other Page** (no page-level override):
- `{{ vars.api_endpoint }}` → `"https://api.example.com"` (site-level)
- `{{ vars.api_timeout }}` → `5000` (account-level)
- `{{ vars.products_per_page }}` → `20` (widget definition default)
- `{{ vars.show_filters }}` → `undefined` (not set at any level)

#### Full Template Example with All Three Types

```liquid
<!-- Layout: layouts/default.liquid -->

<!-- 1. Global variable (site-level) -->
<head>
  <title>{{ page.title }} - {{ site.name }}</title>
  <meta name="theme-color" content="{{ vars.theme_color }}">
</head>

<body>
  {% snippet 'header' %}

  <main>
    <!-- 2. Local variable (template-scoped) -->
    {% assign products_count = products | size %}
    {% assign show_sidebar = true %}

    {% if products_count > 0 %}
      <h2>Found {{ products_count }} products</h2>

      {% for product in products %}
        <!-- 3. Snippet parameters (passed to reusable component) -->
        {% snippet 'product_card',
          product: product,
          highlight: show_sidebar,
          theme: vars.theme_color
        %}
      {% endfor %}
    {% endif %}

    {{ content_for_layout }}
  </main>

  {% snippet 'footer' %}
</body>


<!-- Snippet: snippets/product_card.liquid -->
<div class="product-card" {% if highlight %}class="highlighted"{% endif %}>
  <!-- Parameter from parent -->
  <h3>{{ product.name }}</h3>
  <p>{{ product.description }}</p>

  <!-- Local variable in snippet -->
  {% assign discount_price = product.price | times: 0.8 %}

  <div class="pricing">
    <span class="original">${{ product.price }}</span>
    <span class="discounted">${{ discount_price }}</span>
  </div>

  <!-- Global variable -->
  <button style="background-color: {{ vars.button_color }}">
    Add to Cart
  </button>
</div>
```

---

### Naming Conventions

**Global variables** (`vars`):
- Use `snake_case`: `api_endpoint`, `primary_color`
- Prefix by context: `site_logo`, `widget_api_key`
- Be descriptive: `feature_new_checkout_enabled`

**Local variables**:
- Use `snake_case`: `product_count`, `is_mobile`
- Be concise: `total`, `count`, `enabled`
- Temporary: `i`, `item`, `idx` in loops

**Snippet parameters**:
- Use `snake_case`: `product_name`, `show_badges`
- Match snippet purpose: `color`, `title`, `url`
- Be explicit: `highlight_color` not `color`

---

### Troubleshooting

**Variable not found**:
```liquid
{{ my_variable }}  <!-- Empty output or error -->
```

**Solutions**:
1. Check if it's a global var: `{{ vars.my_variable }}`
2. Check if it was assigned: `{% assign my_variable = "value" %}`
3. Check if it's in scope (local vars don't cross snippets)
4. Check if parameter was passed to snippet

**Variable value unexpected**:
1. Check precedence (snippet param > local assign > global var)
2. Check scope hierarchy (widget > site > account)
3. Check if variable was reassigned with `{% assign %}`

---

### Tools Integration

**Creating global variables**:
```typescript
// Account-level
global-variable-create({
  platformSlug: "fed-team",
  application_type: "account",
  application_id: 1,
  slug: "api_key",
  global_variable_values_attributes: [{ lang: "en", default: true, value: "key123", values: null }]
})

// Site-level
global-variable-create({
  application_type: "site",
  application_id: 4605,
  slug: "site_color"
})

// Widget-level
widget-definitions-variable-create({
  widgetId: 123,
  slug: "widget_endpoint"
})
```

**Listing variables**:
```typescript
global-variables-list({
  platformSlug: "fed-team",
  application_type: "site",
  application_id: 4605,
  lang: "en"
})
```

---

### Summary Table

| Aspect | Global (`vars`) | Local (`assign`) | Snippet Parameters |
|--------|----------------|------------------|-------------------|
| **Syntax** | `{{ vars.NAME }}` | `{{ NAME }}` | `param_name` in snippet |
| **Declaration** | API/UI | `{% assign NAME = value %}` | `{% snippet 'name', param: value %}` |
| **Scope** | Account/Site/Widget/Page | Current template | Snippet invocation |
| **Persistence** | Permanent | Template execution | Snippet execution |
| **Management** | Global Variables API | Liquid tags | Snippet calls |
| **Use Case** | Configuration | Calculations | Component data |
| **Global Precedence** | Page > Widget > Site > Account | N/A | N/A |
| **Overall Precedence** | Lowest | Medium | Highest |

#### Global Variables (`vars`) Sub-Hierarchy

When accessing `{{ vars.NAME }}`, resolution order:

| Level | Scope | Shared Across Stages? | Override Capability |
|-------|-------|----------------------|---------------------|
| **Page-Level Widget Instance** | Specific widget on specific page | N/A (page-specific) | Overrides widget, site, account |
| **Widget Definition** | All instances of widget | ✅ Yes (widget definition is global) | Overrides site, account |
| **Channel/Site** | All pages/widgets in site | ❌ **No** (each stage has own vars) | Overrides account |
| **Account** | All sites in account | ✅ Yes (truly global) | Lowest priority |

---
