## Global Drops

### site

**Available in**: All contexts

**Properties**:
```liquid
{{ site.id }}           <!-- Site ID -->
{{ site.name }}         <!-- Site name -->
{{ site.url }}          <!-- Site URL -->
{{ site.host }}         <!-- Site host slug -->
{{ site.description }}  <!-- Site description -->
{{ site.default_locale }}<!-- Default language -->
{{ site.locales }}      <!-- Available languages -->
{{ site.logo }}         <!-- Site logo asset -->
{{ site.favicon }}      <!-- Site favicon -->
```

**Example**:
```liquid
<head>
  <title>{{ page.title }} - {{ site.name }}</title>
  <link rel="icon" href="{{ site.favicon }}">
  <meta name="description" content="{{ site.description }}">
</head>
```

### html5

**Available in**: Layouts only

**Methods**:
```liquid
{{ html5.open_tag }}    <!-- <!DOCTYPE html><html lang="..."> -->
{{ html5.close_tag }}   <!-- </html> -->
```

**Example**:
```liquid
{{ html5.open_tag }}
<head>...</head>
<body>...</body>
{{ html5.close_tag }}
```

### csp_nonce

**Available in**: All contexts

**Purpose**: Content Security Policy nonce for inline scripts/styles

```liquid
<style nonce="{{csp_nonce}}">
  /* Inline styles */
</style>

<script nonce="{{csp_nonce}}">
  // Inline JavaScript
</script>

<!-- Via filters -->
{{ 'root' | asset_url: 'css' | stylesheet_tag: nonce: csp_nonce }}
{{ 'app' | asset_url: 'js' | script_tag: nonce: csp_nonce }}
```

---

## Page-Specific Drops

### page

**Available in**: All contexts

**Properties**:
```liquid
{{ page.id }}           <!-- Page ID -->
{{ page.name }}         <!-- Page name -->
{{ page.title }}        <!-- Page title -->
{{ page.path }}         <!-- Page path (/products) -->
{{ page.excerpt }}      <!-- Page excerpt -->
{{ page.meta_tags }}    <!-- Page meta tags -->
{{ page.grid_type }}    <!-- Grid type (widget pages) -->
{{ page.widgets }}      <!-- Page widgets array -->
{{ page.has_router }}   <!-- Router enabled? -->
{{ page.page_type }}    <!-- "default", "content", "entry", "origination" -->
```

**Example**:
```liquid
<article class="page">
  <h1>{{ page.title }}</h1>

  {% if page.excerpt %}
    <p class="excerpt">{{ page.excerpt }}</p>
  {% endif %}

  <div class="content">
    {{ content_for_layout }}
  </div>

  <!-- SEO -->
  {% if page.meta_tags.description %}
    <meta name="description" content="{{ page.meta_tags.description }}">
  {% endif %}
</article>
```

### page_grid

**Available in**: Grid snippets only

**Structure**: Object with columns matching grid type

**Example** (in `full_three_cols_grid` snippet):
```liquid
<div class="grid three-cols">
  <div class="col-0">
    {% for widget in page_grid.column_0 %}
      {% snippet widget %}
    {% endfor %}
  </div>

  <div class="col-1">
    {% for widget in page_grid.column_1 %}
      {% snippet widget %}
    {% endfor %}
  </div>

  <div class="col-2">
    {% for widget in page_grid.column_2 %}
      {% snippet widget %}
    {% endfor %}
  </div>
</div>
```

---

## Content Drops

### spaces

**Available in**: All contexts

**Purpose**: Access published content from Content API

**Structure**:
```liquid
{{ spaces['space_uid'] }}                        <!-- Space object -->
{{ spaces['space_uid'].types['type_uid'] }}      <!-- Type object -->
{{ spaces['space_uid'].types['type_uid'].entries }}<!-- All entries -->
```

**Space Properties**:
```liquid
{{ spaces['blog'].name }}       <!-- Space name -->
{{ spaces['blog'].slug }}       <!-- Space slug/UID -->
{{ spaces['blog'].url }}        <!-- Space API URL -->
```

**Type Properties**:
```liquid
{{ spaces['blog'].types['post'].name }}    <!-- Type name -->
{{ spaces['blog'].types['post'].slug }}    <!-- Type slug/UID -->
{{ spaces['blog'].types['post'].single }}  <!-- Single entry type? -->
```

**Example**:
```liquid
<!-- List blog posts -->
{% assign posts = spaces['blog'].types['post'].entries %}

<div class="blog-posts">
  {% for post in posts %}
    <article>
      <h2>{{ post.fields['Title'] }}</h2>
      <p>{{ post.fields['Excerpt'] }}</p>
      <a href="/blog/{{ post.slug }}">Read More</a>
    </article>
  {% endfor %}
</div>
```

### entries

**Available in**: Content page index templates only

**Purpose**: All entries of content type for current page

```liquid
<!-- /blog page with content_type_id set -->
<h1>All Blog Posts</h1>

{% for entry in entries %}
  <article>
    <h2>
      <a href="/blog/{{ entry.slug }}">
        {{ entry.fields['Title'] }}
      </a>
    </h2>
    <time>{{ entry.published_at | date: "%B %d, %Y" }}</time>
  </article>
{% endfor %}
```

### entry

**Available in**: Content page show templates only

**Purpose**: Single entry accessed by slug

```liquid
<!-- /blog/my-post-slug -->
<article>
  <h1>{{ entry.fields['Title'] }}</h1>
  <time>{{ entry.published_at | date: "%B %d, %Y" }}</time>

  <div class="content">
    {{ entry.fields['Body'] }}
  </div>

  <!-- Entry metadata -->
  <dl>
    <dt>Published</dt>
    <dd>{{ entry.published_at | date: "%B %d, %Y" }}</dd>

    <dt>Last Updated</dt>
    <dd>{{ entry.updated_at | date: "%B %d, %Y" }}</dd>

    <dt>Author</dt>
    <dd>{{ entry.fields['Author Name'] }}</dd>
  </dl>

  <!-- Entry relationships -->
  {% if entry.fields['Related Products'] %}
    <h2>Related Products</h2>
    {% for product_id in entry.fields['Related Products'] %}
      {% assign product = spaces['catalog'].types['product'].entries | by_id: product_id %}
      {{ product.fields['Name'] }}
    {% endfor %}
  {% endif %}
</article>
```

**Entry Properties**:
```liquid
{{ entry.id }}              <!-- Entry ID -->
{{ entry.uuid }}            <!-- Entry UUID -->
{{ entry.slug }}            <!-- Entry slug -->
{{ entry.name }}            <!-- Entry name -->
{{ entry.excerpt }}         <!-- Entry excerpt -->
{{ entry.meta }}            <!-- Entry metadata -->
{{ entry.tags }}            <!-- Entry tags array -->
{{ entry.category }}        <!-- Entry category -->
{{ entry.published_at }}    <!-- Publish timestamp -->
{{ entry.updated_at }}      <!-- Update timestamp -->
{{ entry.fields }}          <!-- Entry fields object -->
```

**Critical: Field Access Notation**

⚠️ **MUST use bracket notation with exact field names**:

```liquid
<!-- ✅ CORRECT -->
{{ entry.fields['Product Name'] }}
{{ entry.fields['Price'] }}
{{ entry.fields['SKU'] }}

<!-- ❌ WRONG - won't work -->
{{ entry.fields.product_name }}
{{ entry.fields.price }}
{{ entry.fields.sku }}
```

**See**: [LIQUID_BEST_PRACTICES.md](LIQUID_BEST_PRACTICES.md) for complete field notation guide.

---

## Navigation Drops

### menus

**Available in**: All contexts

**Purpose**: Access published navigation menus

**Structure**:
```liquid
{{ menus['menu_slug'] }}        <!-- Menu object by slug -->
{{ menus['menu_slug'].items }}  <!-- Menu items array -->
```

**Menu Properties**:
```liquid
{{ menus['main-nav'].name }}    <!-- Menu name -->
{{ menus['main-nav'].slug }}    <!-- Menu slug -->
{{ menus['main-nav'].items }}   <!-- Menu items -->
```

**Menu Item Properties**:
```liquid
{{ item.id }}           <!-- Item ID -->
{{ item.label }}        <!-- Display text -->
{{ item.url }}          <!-- Link URL -->
{{ item.target }}       <!-- Link target (_blank, null) -->
{{ item.visible }}      <!-- Is visible? -->
{{ item.parent_id }}    <!-- Parent item ID (for nested) -->
{{ item.position }}     <!-- Position in menu -->
{{ item.children }}     <!-- Child items array -->
```

**Example - Simple Menu**:
```liquid
<nav class="main-nav">
  <ul>
    {% for item in menus['main-nav'].items | visible_items %}
      <li>
        <a href="{{ item.url }}"
           {% if item.target %}target="{{ item.target }}"{% endif %}>
          {{ item.label }}
        </a>
      </li>
    {% endfor %}
  </ul>
</nav>
```

**Example - Nested Menu**:
```liquid
<nav class="main-nav">
  <ul>
    {% for item in menus['main-nav'].items | visible_items %}
      {% if item.parent_id == null %}
        <li class="{% if item.children.size > 0 %}has-dropdown{% endif %}">
          <a href="{{ item.url }}">{{ item.label }}</a>

          {% if item.children.size > 0 %}
            <ul class="dropdown">
              {% for child in item.children | visible_items %}
                <li>
                  <a href="{{ child.url }}">{{ child.label }}</a>
                </li>
              {% endfor %}
            </ul>
          {% endif %}
        </li>
      {% endif %}
    {% endfor %}
  </ul>
</nav>
```

**Critical: Always Filter by Visibility**

```liquid
<!-- ✅ CORRECT - filter visible items -->
{% for item in menus['footer'].items | visible_items %}

<!-- ❌ WRONG - includes hidden items -->
{% for item in menus['footer'].items %}
```

---

## User & Session Drops

### user

**Available in**: Layouts, snippets, pages, widgets (**NOT CSS/JS templates**)

**Purpose**: Currently authenticated user

> **Note**: In Modyo Liquid, the drop name is `user`, not `current_user`. Check authentication with `{% if user %}` — NOT `{% if user.logged_in %}` (does not exist).

**Properties**:
```liquid
{{ user.id }}                          <!-- User ID -->
{{ user.name }}                        <!-- Full name -->
{{ user.first_name }}                  <!-- First name -->
{{ user.last_name }}                   <!-- Last name -->
{{ user.email }}                       <!-- Email address -->
{{ user.username }}                    <!-- Username -->
{{ user.avatar.url }}                  <!-- Avatar URL (may be blank) -->
{{ user.realm_default_avatar }}        <!-- Default avatar from realm config -->
{{ user.tags }}                        <!-- User tags -->
{{ user.custom_fields }}               <!-- Custom user fields -->
{{ user.unread_notifications_count }}  <!-- Unread notification count -->
```

**Initials pattern**:
```liquid
{{ user.first_name | slice: 0 }}{{ user.last_name | slice: 0 }}
```

**Example**:
```liquid
{% if user %}
  <div class="user-menu">
    {% if user.avatar.url != blank %}
      <img src="{{ user.avatar.url }}" alt="{{ user.name }}">
    {% else %}
      <span class="avatar-initials">{{ user.first_name | slice: 0 }}{{ user.last_name | slice: 0 }}</span>
    {% endif %}
    <span>Welcome, {{ user.first_name }}</span>

    <ul class="dropdown">
      <li><a href="{{ site.url }}/profile">My Profile</a></li>
      {% if user.unread_notifications_count > 0 %}
        <li><a href="{{ site.url }}/notifications">Notifications ({{ user.unread_notifications_count }})</a></li>
      {% endif %}
      <li><a href="{{ site.url }}/logout">Logout</a></li>
    </ul>
  </div>
{% elsif site.login_enabled %}
  <div class="auth-links">
    <a href="{{ site.url }}/login">Login</a>
    <a href="{{ site.url }}/register">Sign Up</a>
  </div>
{% endif %}
```

**Login/Logout URLs**:
- Login: `{{ site.url }}/login`
- Logout: `{{ site.url }}/logout`
- Register: `{{ site.url }}/register`

**Site properties**:
- `site.login_enabled` — whether login is enabled for the site (use for conditional login links)

**Session snippet**: Use `{% snippet "shared/general/session" %}` to include the built-in session management (handles login/logout flow, avatar, dropdown).

### session

**Available in**: Layouts, snippets, pages, widgets (**NOT CSS/JS templates**)

**Purpose**: Current user session

**Properties**:
```liquid
{{ session.authenticated }}     <!-- Is user logged in? -->
{{ session.locale }}            <!-- Current locale -->
{{ session.segments }}          <!-- User segments -->
```

**Example**:
```liquid
{% if session.authenticated %}
  <p>You are logged in</p>
{% else %}
  <p>Please log in to continue</p>
{% endif %}

<!-- Personalized content by segment -->
{% if session.segments contains "premium" %}
  <div class="premium-content">
    <!-- Premium features -->
  </div>
{% endif %}
```

---

## Modyo-Specific Filters

### Asset Filters

```liquid
<!-- CSS asset URL -->
{{ 'root' | asset_url: 'css' }}
<!-- Output: https://cdn.modyo.cloud/.../root.css -->

<!-- JS asset URL -->
{{ 'app' | asset_url: 'js' }}
<!-- Output: https://cdn.modyo.cloud/.../app.js -->

<!-- CSS tag with nonce -->
{{ 'root' | asset_url: 'css' | stylesheet_tag: media: 'screen', nonce: csp_nonce }}
<!-- Output: <link href="..." rel="stylesheet" media="screen" nonce="abc123"> -->

<!-- JS tag with defer -->
{{ 'app' | asset_url: 'js' | script_tag: defer: 'defer', nonce: csp_nonce }}
<!-- Output: <script src="..." defer="defer" nonce="abc123"></script> -->
```

### Entry Filters

```liquid
<!-- Find entry by slug -->
{{ spaces['blog'].types['post'].entries | by_slug: 'my-post' }}

<!-- Find entry by UUID -->
{{ spaces['blog'].types['post'].entries | by_uuid: '12345-67890' }}

<!-- Find entry by ID -->
{{ spaces['blog'].types['post'].entries | by_id: 42 }}

<!-- Filter by category -->
{{ spaces['blog'].types['post'].entries | by_category: 'news' }}

<!-- Filter by tag -->
{{ spaces['blog'].types['post'].entries | by_tag: 'featured' }}

<!-- Sort entries -->
{{ spaces['blog'].types['post'].entries | order_by: 'published_at', 'desc' }}
```

### Menu Filters

```liquid
<!-- Filter visible items -->
{{ menus['main-nav'].items | visible_items }}
```

### Standard Liquid Filters

```liquid
<!-- String filters -->
{{ text | upcase }}                  <!-- UPPERCASE -->
{{ text | downcase }}                <!-- lowercase -->
{{ text | capitalize }}              <!-- Capitalize -->
{{ text | strip_html }}              <!-- Remove HTML tags -->
{{ text | truncate: 100 }}           <!-- Truncate to 100 chars -->

<!-- Number filters -->
{{ price | money }}                  <!-- Format as currency -->
{{ number | plus: 10 }}              <!-- Add 10 -->
{{ number | minus: 5 }}              <!-- Subtract 5 -->
{{ number | times: 2 }}              <!-- Multiply by 2 -->
{{ number | divided_by: 3 }}         <!-- Divide by 3 -->

<!-- Date filters -->
{{ date | date: "%B %d, %Y" }}      <!-- Format: January 20, 2025 -->
{{ date | date: "%Y-%m-%d" }}        <!-- Format: 2025-01-20 -->

<!-- Array filters -->
{{ array | size }}                   <!-- Array length -->
{{ array | first }}                  <!-- First element -->
{{ array | last }}                   <!-- Last element -->
{{ array | join: ', ' }}             <!-- Join with comma -->
{{ array | sort }}                   <!-- Sort array -->
{{ array | uniq }}                   <!-- Remove duplicates -->

<!-- URL filters -->
{{ text | url_encode }}              <!-- URL encode -->
{{ url | append: '?page=2' }}        <!-- Append to URL -->
```

---

## Common Patterns

### Pattern 1: Conditional User Content

```liquid
{% if user %}
  <!-- Authenticated user content -->
  <div class="dashboard">
    <h1>Welcome back, {{ user.first_name }}</h1>
    <a href="{{ site.url }}/logout">Logout</a>
  </div>
{% elsif site.login_enabled %}
  <!-- Public content -->
  <div class="marketing">
    <h1>Sign up today!</h1>
    <a href="{{ site.url }}/register">Get Started</a>
  </div>
{% endif %}
```

### Pattern 2: Content Listing with Pagination

```liquid
{% assign posts = spaces['blog'].types['post'].entries %}
{% assign page_size = 10 %}
{% assign page_num = request.params.page | default: 1 %}
{% assign offset = page_num | minus: 1 | times: page_size %}

<div class="blog-posts">
  {% for post in posts limit: page_size offset: offset %}
    <article>
      <h2>{{ post.fields['Title'] }}</h2>
      <p>{{ post.fields['Excerpt'] }}</p>
      <a href="/blog/{{ post.slug }}">Read More</a>
    </article>
  {% endfor %}
</div>

<!-- Pagination -->
{% assign total_pages = posts.size | divided_by: page_size | ceil %}
<nav class="pagination">
  {% for i in (1..total_pages) %}
    <a href="?page={{ i }}" {% if i == page_num %}class="active"{% endif %}>
      {{ i }}
    </a>
  {% endfor %}
</nav>
```

### Pattern 3: Multi-Language Content

```liquid
{% case site.default_locale %}
{% when 'es' %}
  <h1>Bienvenido</h1>
{% when 'pt' %}
  <h1>Bem-vindo</h1>
{% else %}
  <h1>Welcome</h1>
{% endcase %}

<!-- Or using translations -->
{{ 'welcome.title' | t }}
```

### Pattern 4: Dynamic Navigation

```liquid
<nav class="breadcrumb">
  <a href="/">{{ site.name }}</a>

  {% if page.page_type == 'entry' %}
    <span class="separator">›</span>
    <a href="{{ page.path }}">{{ page.name }}</a>
    <span class="separator">›</span>
    <span>{{ entry.fields['Title'] }}</span>
  {% else %}
    <span class="separator">›</span>
    <span>{{ page.name }}</span>
  {% endif %}
</nav>
```

### Pattern 5: Featured Content

```liquid
<!-- Featured posts with fallback -->
{% assign featured = spaces['blog'].types['post'].entries | by_tag: 'featured' | limit: 3 %}

{% if featured.size > 0 %}
  <section class="featured">
    <h2>Featured Posts</h2>
    {% for post in featured %}
      <article>
        <h3>{{ post.fields['Title'] }}</h3>
        <p>{{ post.fields['Excerpt'] }}</p>
      </article>
    {% endfor %}
  </section>
{% else %}
  <!-- Fallback to recent posts -->
  {% assign recent = spaces['blog'].types['post'].entries | order_by: 'published_at', 'desc' | limit: 3 %}
  <section class="recent">
    <h2>Recent Posts</h2>
    {% for post in recent %}
      <article>
        <h3>{{ post.fields['Title'] }}</h3>
      </article>
    {% endfor %}
  </section>
{% endif %}
```

---

## Limitations

### CSS/JS Templates: No Private Drops

**❌ These will FAIL in CSS/JS templates**:
```liquid
/* CSS template - FAILS */
.user-name::after {
  content: "{{ user.name }}";  /* ERROR */
}

// JS template - FAILS
window.USER = {
  name: "{{ user.name }}",      // ERROR
  authenticated: {{ session.authenticated }}  // ERROR
};
```

**✅ Use server-rendered snippets instead**:
```liquid
<!-- In snippet (server-rendered) -->
<style nonce="{{csp_nonce}}">
  .user-name::after {
    content: "{{ user.name }}";  /* OK */
  }
</style>

<script nonce="{{csp_nonce}}">
  window.USER = {
    name: "{{ user.name }}",      // OK
    authenticated: {{ session.authenticated }}  // OK
  };
</script>
```

### Field Name Notation

**❌ Dot notation doesn't work**:
```liquid
{{ entry.fields.product_name }}   <!-- FAILS -->
{{ entry.fields.price }}          <!-- FAILS -->
```

**✅ Bracket notation required**:
```liquid
{{ entry.fields['Product Name'] }}   <!-- Works -->
{{ entry.fields['Price'] }}          <!-- Works -->
```

### Performance Considerations

**❌ Avoid nested loops on large datasets**:
```liquid
{% for post in spaces['blog'].types['post'].entries %}
  {% for comment in spaces['blog'].types['comment'].entries %}
    {% if comment.fields['Post ID'] == post.id %}
      <!-- O(n²) complexity -->
    {% endif %}
  {% endfor %}
{% endfor %}
```

**✅ Use relationships or limit loops**:
```liquid
{% assign posts = spaces['blog'].types['post'].entries | limit: 10 %}
{% for post in posts %}
  {% assign comments = spaces['blog'].types['comment'].entries | by_post_id: post.id %}
  <!-- Better performance -->
{% endfor %}
```

---

## Best Practices

### 1. Always Check Existence

```liquid
<!-- ❌ Assumes field exists -->
{{ entry.fields['Author'] }}

<!-- ✅ Check first -->
{% if entry.fields['Author'] %}
  {{ entry.fields['Author'] }}
{% endif %}
```

### 2. Use Exact Field Names

```liquid
<!-- ✅ Copy field name from type-get -->
{{ entry.fields['Product Name'] }}   <!-- Exact match -->
{{ entry.fields['SKU'] }}             <!-- Case-sensitive -->
```

### 3. Filter Menu Visibility

```liquid
<!-- ✅ Always filter -->
{% for item in menus['main'].items | visible_items %}
```

### 4. Provide Fallbacks

```liquid
<!-- ✅ Graceful degradation -->
{% assign products = spaces['catalog'].types['product'].entries %}

{% if products.size > 0 %}
  <!-- Show products -->
{% else %}
  <p>No products available</p>
{% endif %}
```

### 5. Use Semantic Variables

```liquid
<!-- ✅ Clear intent -->
{% assign blog_posts = spaces['blog'].types['post'].entries %}
{% assign featured_posts = blog_posts | by_tag: 'featured' %}
{% assign recent_posts = blog_posts | order_by: 'published_at', 'desc' | limit: 5 %}
```

### 6. Comment Complex Logic

```liquid
{% comment %}
  Featured carousel: Shows up to 5 featured products.
  Falls back to recent products if no featured items.
{% endcomment %}

{% assign featured = spaces['catalog'].types['product'].entries | by_tag: 'featured' | limit: 5 %}

{% if featured.size > 0 %}
  <!-- Featured products -->
{% else %}
  <!-- Fallback to recent -->
{% endif %}
```

---

## Summary

**Key Takeaways**:

1. **Full Liquid**: Layouts, snippets, pages, widgets have ALL drops
2. **Partial Liquid**: CSS/JS templates have NO private drops (current_user, session)
3. **Field Access**: MUST use bracket notation with exact names
4. **Always Check**: Verify variable existence before use
5. **Filter Visibility**: Always use `visible_items` for menus
6. **Context Matters**: Different drops available in different templates

**Quick Reference Table**:

| Drop | Layouts | Pages | Widgets | CSS/JS |
|------|---------|-------|---------|--------|
| `site` | ✅ | ✅ | ✅ | ✅ |
| `page` | ✅ | ✅ | ✅ | ✅ |
| `spaces` | ✅ | ✅ | ✅ | ✅ |
| `menus` | ✅ | ✅ | ✅ | ✅ |
| `user` | ✅ | ✅ | ✅ | ❌ |
| `session` | ✅ | ✅ | ✅ | ❌ |
| `entries` | ❌ | ✅ (index) | ❌ | ❌ |
| `entry` | ❌ | ✅ (show) | ❌ | ❌ |
| `variables` | ❌ | ❌ | ✅ | ❌ |

---

**Document Version**: 1.0.0
**Last Updated**: 2025-01-20
**Related Docs**: [LIQUID_BEST_PRACTICES.md](LIQUID_BEST_PRACTICES.md), [CSS_ORGANIZATION.md](CSS_ORGANIZATION.md)
