Sistema de temas
Liquid
A linguagem dos temas, com as regras próprias da Promisse Store.
Liquid é uma linguagem de template: você escreve HTML e marca onde entram os dados da loja. O motor usado é o LiquidJS, com algumas regras próprias que aparecem nesta página.
Os três elementos#
| Elemento | Sintaxe | Para que serve |
|---|---|---|
| Saída | {{ ... }} |
Imprime um valor. |
| Tag | {% ... %} |
Lógica: condições, laços e variáveis. |
| Filtro | {{ valor | filtro }} |
Transforma um valor. |
Imprimir valores#
<h1>{{ store.name }}</h1>
<img src="{{ product.images[0] }}" alt="{{ product.name }}">
<p>{{ route.params.id }}</p>Condições#
{% if product.stock_amount == 0 %}
<span>Esgotado</span>
{% elsif product.stock_amount < 5 %}
<span>Últimas {{ product.stock_amount }} unidades</span>
{% else %}
<span>Disponível</span>
{% endif %}
{% unless options.store_status %}
<p>Estamos em manutenção.</p>
{% endunless %}Operadores: ==, !=, >, <, >=, <=, contains, and e or.
O que conta como falso#
Esta é a diferença que mais pega de surpresa. Aqui, os valores seguem a regra do JavaScript:
| Valor | Em um if |
|---|---|
0 |
Falso |
"" |
Falso |
nil e false |
Falso |
[] |
Verdadeiro |
Por isso, lista vazia precisa ser testada pelo tamanho:
{% if catalog.categories.size > 0 %}
...
{% endif %}Laços#
{% for item in catalog.products limit: 8 %}
<a href="/product/{{ item.slug }}">{{ forloop.index }}. {{ item.name }}</a>
{% else %}
<p>Nenhum produto disponível.</p>
{% endfor %}Dentro do laço, forloop traz index, length, first e last. O bloco else roda quando a lista está vazia. Use .size para saber o tamanho de uma lista.
Variáveis próprias#
{% assign destaques = catalog.products | where: "highlight", true %}
{% assign url = product.slug | default: product.id %}
{% capture saudacao %}Olá, {{ user.name | default: "visitante" }}{% endcapture %}
<p>{{ saudacao }}</p>page_title é uma variável especial: ela define o título da aba do navegador.
{% assign page_title = product.name %}Layout e blocos#
O layout é a moldura comum das páginas. Ele marca onde entra o conteúdo:
<header>{{ store.name }}</header>
<main>{% block content %}{% endblock %}</main>Cada página aponta para o layout e preenche o bloco:
{% layout 'layouts/theme' %}
{% block content %}
<h1>Início</h1>
{% endblock %}Snippets#
Um snippet é um pedaço reaproveitável. Passe para ele tudo o que ele precisa:
{% for item in catalog.products limit: 8 %}
{% render 'snippets/product-card', product: item %}
{% endfor %}{% render %} e {% layout %} aceitam o caminho com ou sem .liquid e só enxergam arquivos do próprio tema.
Filtros#
Filtros da plataforma#
| Filtro | Exemplo | Resultado |
|---|---|---|
money |
{{ 1234.5 | money }} |
R$ 1.234,50 |
raw |
{{ product.description | raw }} |
HTML sem escapar |
json |
{{ product | json | raw }} |
JSON seguro para colocar em <script> |
Filtros comuns#
| Filtro | Exemplo | Resultado |
|---|---|---|
default |
{{ user.name | default: "visitante" }} |
visitante |
where |
{{ catalog.products | where: "highlight", true }} |
Filtra a lista |
split e first |
{{ "Ana Lima" | split: " " | first }} |
Ana |
upcase |
{{ "oi" | upcase }} |
OI |
truncate |
{{ "abcdefghij" | truncate: 5 }} |
ab... |
times e plus |
{{ 10 | times: 2 | plus: 1 }} |
21 |
round |
{{ 3.14159 | round: 2 }} |
3.14 |
Passar dados para o JavaScript#
O filtro json é seguro dentro de <script>, mesmo com texto digitado por clientes:
<script>
const produto = {{ product | json | raw }};
</script>Erros comuns#
| Sintoma | Causa |
|---|---|
| O HTML da descrição aparece como texto | Falta | raw. |
{{ product.name }} sai vazio |
product só existe nas rotas de produto. Em outras páginas, percorra catalog.products. |
{% if lista %} sempre entra |
Lista vazia é verdadeira. Use lista.size > 0. |
| Uma variável some dentro do snippet | Passe no {% render %}. |
| A loja mostra a página padrão no lugar do tema | O render falhou ou passou do limite. Veja os limites. |

