> For the complete documentation index, see [llms.txt](https://ereemby.gitbook.io/docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ereemby.gitbook.io/docs/sistema-de-temas/variaveis.md).

# Variáveis

Visão geral de todas as variáveis disponíveis no template, schema completo e padrões de uso.

Esta seção documenta **todas as variáveis disponíveis no template Liquid** da Ereemby. As variáveis são populadas automaticamente pelo servidor antes do template ser renderizado, então você só precisa acessar pelo nome em qualquer página onde elas existem.

```liquid
Olá, {{ user.name | default: "visitante" }}! Bem-vindo à {{ store.name }}.
```

### Mapa das variáveis

A maioria está em **todas as páginas**. Algumas aparecem **apenas em rotas específicas**.

| Variável                                                 | O que contém                                      | Onde está disponível      |
| -------------------------------------------------------- | ------------------------------------------------- | ------------------------- |
| [`Store`](/docs/sistema-de-temas/variaveis/store.md)     | Nome, descrição, logo e banner da loja            | Todas as páginas          |
| [`User`](/docs/sistema-de-temas/variaveis/user.md)       | Nome e email do usuário logado                    | Todas as páginas          |
| [`Social`](/docs/sistema-de-temas/variaveis/social.md)   | Links das 7 redes sociais                         | Todas as páginas          |
| [`Options`](/docs/sistema-de-temas/variaveis/options.md) | Flags de configuração, status, login e avaliações | Todas as páginas          |
| [`Dates`](/docs/sistema-de-temas/variaveis/dates.md)     | Data e hora atuais do servidor                    | Todas as páginas          |
| [`Catalog`](/docs/sistema-de-temas/variaveis/catalog.md) | Categorias, produtos e variantes, em listas       | Todas as páginas          |
| [`Product`](/docs/sistema-de-temas/variaveis/product.md) | Dados do produto sendo visualizado                | Apenas em `/product/[id]` |

{% hint style="info" %}
**`Product` e `Products` compartilham a maioria dos nomes de campo,** `price`, `category_id`, `stock_amount`, `comparison`, `quantity`. A diferença real está nos **campos extras** que cada um tem.
{% endhint %}

### Schema completo

Visão de tudo o que está disponível no contexto do template. Use esta seção como referência rápida.

#### Variáveis globais

```ts
{
  store: {
    name: string;                    // sempre presente, "" se vazio
    description: string;             // sempre presente, "" se vazio
    icon: string;                    // URL ou ""
    banner: string;                  // URL ou ""
  };

  user: {
    name: string | null;             // null se deslogado
    email: string | null;            // null se deslogado
  };

  social: {
    facebook: string | null;
    instagram: string | null;
    twitter: string | null;
    youtube: string | null;
    whatsapp: string | null;         // pode ser número ou URL
    telegram: string | null;
    discord: string | null;
  };

  options: {
    store_status: boolean;           // true = loja ativa
    force_auth: boolean;             // true = exige login
    feedback_status: boolean;        // true = avaliações habilitadas
  };

  dates: {
    date: Date;                      // use com | date: "..."
    year: number;
    month: number;                   // 1 a 12
    day: number;                     // 1 a 31
    time: {
      hours: number;                 // 0 a 23
      minutes: number;               // 0 a 59
      seconds: number;               // 0 a 59
    };
  };

  catalog: {
    categories: Category[];          // plano, só folhas
    categories_all: Category[];      // árvore completa, com sub_categories
    products: Product[];             // todos os produtos
    variants: Variant[];             // todas as variantes, flat
  };
}

Category: {
  id: string;
  name: string;
  slug: string;
  sub_title: string;                 // pode ser ""
  icon: string;                      // URL ou ""
  banner: string;                    // URL ou ""
  position: number;
  parent_category: string | null;    // ID do pai, null se raiz
  createdAt: string;                 // ISO 8601
  products: Product[];
  sub_categories?: Category[];       // só em categories_all
}

Product: {
  id: string;
  name: string;
  images: string[];                  // pode ser []
  price: number;                     // preço atual
  comparison: number | null;         // preço "de", null se sem desconto
  quantity: {
    min: number;
    max: number;                     // sempre presente
  };
  stock_amount: number;
  type: string;                      // "series" ou "texto"
  category_id: string;               // ID da categoria
  position: number | null;
  automatic: boolean;
  createdAt: string;                 // ISO 8601
  variants: Variant[];
  variants_values: {
    min: Variant | null;             // variante mais barata
    max: Variant | null;             // variante mais cara
  };
}

Variant: {
  id: number;
  name: string;
  price: number;
  comparison: number | null;
  quantity: {
    min: number;
    max: number;                     // sempre presente
  };
  stock_amount: number;
  icon: string;                      // URL ou ""
  images: string[];
  type: string;                      // "series" ou "texto"
  category_id: string;
  position: number | null;
  automatic: boolean;
  createdAt: string;
}
```

#### Variável adicional em página de produto

Quando o visitante está em uma página individual de produto, **uma variável extra aparece**:

```ts
{
  product: {
    id: string;
    name: string;
    price: number;                              // mesmo nome do catálogo
    comparison: number | null;
    quantity: { min: number; max: number };
    stock_amount: number;
    sold: number;                               // exclusivo da página
    hideSold: boolean;                          // exclusivo da página
    description: string;                        // exclusivo, HTML processado
    type: 'texto' | 'series' | 'variante';     // tipo mais estrito
    category_id: string;
    embed_video: string | null;                 // exclusivo
    images: string[];
    automatic: boolean;
    instructions: string | null;                // exclusivo
    variants: ProductVariant[];
    fields: ProductField[];                     // exclusivo, campos do checkout
    feedback: ProductFeedback;                  // exclusivo
  };
}

ProductVariant: {
  id: number;                                   // mesmo tipo do catálogo
  name: string;
  price: number;
  comparison: number | null;
  quantity: { min: number; max: number };
  stock_amount: number;
  sold: number;                                 // exclusivo
  hideSold: boolean;                            // exclusivo
  description: string;                          // exclusivo
  type: 'texto' | 'series';
  category_id: string;
  embed_video: string | null;                   // exclusivo
  images: string[];
  icon: string | null;                          // pode ser null aqui
  automatic: boolean;
  instructions: string | null;                  // exclusivo
  // a variante NÃO tem fields próprio; campos de variante ficam em
  // product.fields com ref_variant === variant.id
}

ProductField: {
  id: number;                                   // amarra a resposta no checkout
  name: string;                                 // rótulo exibido
  description: string;                          // ajuda / placeholder
  type: string;                                 // ex.: 'texto' | 'numero' | 'roblox'
  ref_product: string | null;                   // escopo: produto inteiro
  ref_variant: number | null;                   // escopo: só aquela variante
  ref_category: string | null;                  // escopo: toda a categoria
  character_limit: { min: number; max: number };
  required: boolean;
}

ProductFeedback: {
  stats: {
    stars: { '1': number, '2': number, '3': number, '4': number, '5': number };
    total: number;
    average: number;
  };
  reviews: ProductReview[];
  generate_text_ia: boolean;
}

ProductReview: {
  id: number;
  comment: string;
  star: number;
  like: number;
  is_anonymous: boolean;
  is_approved: boolean;
  tags: string[];
  response_staff: string | null;
  images: string[];
  createdAt: string;
}
```

{% hint style="info" %}
**Diferenças entre `Product` e `Products`:**

Os nomes em comum: `price`, `category_id`, `stock_amount`, `comparison`, `quantity`, são iguais nos dois.
{% endhint %}

|                      | `Product` (página)                                                                     | `Products` (catálogo)                      |
| -------------------- | -------------------------------------------------------------------------------------- | ------------------------------------------ |
| Onde está disponível | Só em `/product/[id]`                                                                  | Todas as páginas                           |
| Campos exclusivos    | `description`, `feedback`, `instructions`, `embed_video`, `sold`, `hideSold`, `fields` | `position`, `createdAt`, `variants_values` |
| Tipo de `type`       | `'texto' \| 'series' \| 'variante'`                                                    | `string`                                   |
| `variant.icon`       | `string \| null`                                                                       | `string`                                   |

{% hint style="info" %}
**`product.fields`** são os campos personalizados que o cliente preenche no checkout. Veja a página de [`Product`](/docs/sistema-de-temas/variaveis/product.md). As variantes não têm `fields` próprio: um campo que vale só para uma variante aparece em `product.fields` com `ref_variant` igual ao `id` da variante.
{% endhint %}

### Como acessar valores

#### Sintaxe básica

```liquid
{{ store.name }}               {# valor direto #}
{{ user.email }}               {# propriedade aninhada #}
{{ product.quantity.min }}     {# duplo aninhamento #}
{{ catalog.products.size }}    {# tamanho de array #}
```

#### Loops

```liquid
{% for product in catalog.products %}
  {{ product.name }}
{% endfor %}
```

#### Condicionais

```liquid
{% if user.name %}
  Bem-vindo, {{ user.name }}!
{% else %}
  Bem-vindo, visitante!
{% endif %}
```

#### Filtros

```liquid
{{ product.price | round: 2 }}                     {# arredonda #}
{{ user.name | upcase }}                           {# maiúsculas #}
{{ dates.date | date: "%d/%m/%Y" }}                {# formata data #}
{{ user.name | default: "visitante" }}             {# fallback #}
{{ catalog.products | sort: "price" }}             {# ordena #}
```

### Verificar se um valor existe

As variáveis têm padrões diferentes de "vazio". Com `jsTruthy: true`, a detecção fica direta:

| Padrão  | Onde aparece                                                                                         | Como detectar                      |
| ------- | ---------------------------------------------------------------------------------------------------- | ---------------------------------- |
| `""`    | `store.*`, `category.icon`, `variant.icon` do catálogo                                               | `{% if store.icon %}`              |
| `null`  | `user.*`, `social.*`, `product.comparison`, `catalog.products[N].position`, `variant.icon` da página | `{% if user.name %}`               |
| `[]`    | `product.images`, `product.variants`, `category.products`                                            | `{% if product.images.size > 0 %}` |
| `0`     | `product.stock_amount`, `feedback.stats.stars['1']`                                                  | `{% if x > 0 %}`                   |
| `false` | `options.*`, `automatic`, `hideSold`                                                                 | `{% if x %}` ou `{% unless x %}`   |

**Regra universal:** `{% if x %}` cobre quase todos os casos. Use `{% if x != blank %}` quando quiser também pegar strings só com espaços, ou `.size > 0` pra arrays.

```liquid
{% if catalog.products.size > 0 %}     {# array com pelo menos 1 item #}
{% if user.name %}                     {# string não vazia e não null #}
{% if product.comparison %}            {# se tem desconto #}
```

### Padrões transversais

#### 1. Saudação personalizada por horário e usuário

```liquid
{% assign saudacao = "Bom dia" %}
{% if dates.time.hours >= 12 and dates.time.hours < 18 %}
  {% assign saudacao = "Boa tarde" %}
{% elsif dates.time.hours >= 18 %}
  {% assign saudacao = "Boa noite" %}
{% endif %}

{{ saudacao }}, {{ user.name | default: "visitante" }}!
```

#### 2. Rodapé completo

```liquid
<footer>
  <p>© {{ dates.year }} {{ store.name }}. Todos os direitos reservados.</p>

  <div class="social">
    {% if social.instagram %}
      <a href="{{ social.instagram }}" target="_blank" rel="noopener">Instagram</a>
    {% endif %}
    {% if social.whatsapp %}
      <a href="https://wa.me/{{ social.whatsapp }}" target="_blank" rel="noopener">WhatsApp</a>
    {% endif %}
  </div>
</footer>
```

#### 3. Acesso restrito

```liquid
{% if options.force_auth and user.name == nil %}
  <div class="auth-required">
    <h2>Acesso restrito</h2>
    <p>Esta loja exige cadastro. <a href="/login">Entre</a> ou <a href="/cadastro">crie uma conta</a>.</p>
  </div>
{% endif %}
```

#### 4. Avaliações condicionais

```liquid
{% if options.feedback_status %}
  <section class="avaliacoes">
    <h2>Avaliações dos clientes</h2>
    <div id="COMPONENT_FEEDBACKS_CARDS"></div>
  </section>
{% endif %}
```

#### 5. Banner sazonal

```liquid
{% if dates.month == 12 %}
  <div class="banner-natal">
    🎄 Ofertas de Natal na {{ store.name }}! Até 31/12.
  </div>
{% endif %}
```

#### 6. Card de produto na home

```liquid
{% for product in catalog.products %}
  <article class="produto">
    {% if product.images.size > 0 %}
      <img src="{{ product.images[0] }}" alt="{{ product.name }}" loading="lazy">
    {% endif %}

    <h3>{{ product.name }}</h3>

    {% if product.comparison %}
      <span class="preco-de">R$ {{ product.comparison }}</span>
    {% endif %}
    <span class="preco">R$ {{ product.price }}</span>

    {% if product.stock_amount > 0 %}
      <button>Comprar</button>
    {% else %}
      <button disabled>Esgotado</button>
    {% endif %}
  </article>
{% endfor %}
```

#### 7. Hero da página de produto com avaliações

Combina `product` com `options.feedback_status`:

```liquid
<section class="produto-hero">
  {% if product.images.size > 0 %}
    <img src="{{ product.images[0] }}" alt="{{ product.name }}">
  {% endif %}

  <h1>{{ product.name }}</h1>

  {% if options.feedback_status and product.feedback.stats.total > 0 %}
    <div class="rating">
      ★ {{ product.feedback.stats.average | round: 1 | replace: ".", "," }}
      ({{ product.feedback.stats.total }} avaliações)
    </div>
  {% endif %}

  <p>R$ {{ product.price }}</p>
</section>
```

### Padrões de nomenclatura

Conhecer os padrões evita perder tempo procurando campo errado.

* **Todos os nomes em inglês** no output do template.
* **`snake_case` é o padrão:** `parent_category`, `sub_title`, `force_auth`, `categories_all`, `sub_categories`, `stock_amount`, `category_id`, `is_anonymous`, `response_staff`, `ref_product`, `ref_variant`, `ref_category`, `character_limit`.
* **Exceções em camelCase:** `createdAt`, `hideSold`.
* **Min/max sempre dentro de `quantity`:** `product.quantity.min`.
* **Tempo aninhado em `time`:** `dates.time.hours`.
* **Booleanos com `_status` ou verbo:** `store_status`, `feedback_status`, `force_auth`, `automatic`.
* **Datas:** `dates.date` é `Date`. `product.createdAt`, `category.createdAt`, `variant.createdAt`, `review.createdAt` são string ISO 8601.
* **`Product` vs `Products`:** singular é a variável da página de produto. Plural é a lista global dentro de `Catalog`.

### Erros comuns globais

{% hint style="danger" %}
**Não use os nomes em português do backend.** Coisas como `{{ produto.nome }}`, `{{ store.desc }}` e `{{ category.nome }}` não funcionam.
{% endhint %}

{% hint style="danger" %}
**Não imprima objetos diretamente.** `{{ store }}`, `{{ product }}` e `{{ catalog }}` geram saída inútil. Sempre acesse propriedades específicas.
{% endhint %}

{% hint style="danger" %}
**Não use `Product` fora de `/product/[id]`.** Em outras páginas ele não existe. Pra listas use `Products` em `catalog.products`.
{% endhint %}

{% hint style="warning" %}
**Os dados são cacheados por 60 segundos.** Mudanças no painel podem demorar até um minuto pra aparecer no template.
{% endhint %}

{% hint style="warning" %}
**`dates` é do servidor, não do visitante.** Se o visitante está em outro fuso, `dates.time.hours` pode estar diferente do horário dele.
{% endhint %}

{% hint style="warning" %}
**Liquid não tem filtro de moeda nativo.** `{{ product.price }}` gera `49.9`, não `R$ 49,90`. Pra formatar, use `| round: 2 | replace: ".", ","`.
{% endhint %}

{% hint style="info" %}
**Padrão de detecção único:** `{% if x %}` cobre string vazia, `null` e zero. Pra arrays use `.size > 0`. Pra strings só com espaços, use `!= blank`.
{% endhint %}

### Onde aprender mais

Cada variável tem uma página dedicada com tabela completa de propriedades, exemplos de uso e armadilhas específicas:

* [**`Store`**](/docs/sistema-de-temas/variaveis/store.md): dados da loja
* [**`User`**](/docs/sistema-de-temas/variaveis/user.md): usuário logado
* [**`Social`**](/docs/sistema-de-temas/variaveis/social.md): redes sociais
* [**`Options`**](/docs/sistema-de-temas/variaveis/options.md): configurações
* [**`Dates`**](/docs/sistema-de-temas/variaveis/dates.md): data e hora
* [**`Catalog`**](/docs/sistema-de-temas/variaveis/catalog.md): catálogo
  * [`Categories`](/docs/sistema-de-temas/variaveis/catalog/categories.md)
  * [`Categories_all`](/docs/sistema-de-temas/variaveis/catalog/categories_all.md)
  * [`Products`](/docs/sistema-de-temas/variaveis/catalog/products.md)
  * [`Variants`](/docs/sistema-de-temas/variaveis/catalog/variants.md)
* [**`Product`**](/docs/sistema-de-temas/variaveis/product.md): dados do produto na página `/product/[id]`
