Saltar al contenido
merge.uydevelopers

Tags

Los tags son la lógica del template: {% if %}, {% for %},{% render %}. Los de la plataforma están marcados conMerge.

Todos aceptan el control de espacios de Liquid: {%- y -%} sacan los espacios y saltos de línea de alrededor. include no está disponible: usárender.

Tags del theme

sectionMerge

{% section 'nombre' %}

Renderiza una sección estática (la misma en todas las páginas), típicamente el encabezado y el pie desde el layout. Sus settings se guardan en config/settings_data.json y se editan en el editor de temas. Una sección no puede incluirse a sí misma y el anidamiento tiene un tope.

{% section 'header' %}
<main>{{ content_for_layout }}</main>
{% section 'footer' %}

render

{% render 'snippet', variable: valor %}

Renderiza un snippet de snippets/ con su propio alcance: solo ve las variables que le pasás y los objetos globales. Acepta for y with.

{% for product in collection.products %}
  {% render 'product-card', product: product %}
{% endfor %}

formMerge

{% form 'tipo', objeto, atributo: valor %} … {% endform %}

Arma un <form method="post"> con los campos ocultos que la tienda necesita. Tipos que procesa la tienda: product (agrega al carrito), contact (consulta) y customer (suscripción al newsletter). Adentro, form.posted_successfully? y form.errors tienen el resultado del último envío de ese tipo. Otros tipos de Shopify salen con action="#" y el atributo data-form-unsupported para que el theme decida qué mostrar.

{% form 'contact', id: 'contacto' %}
  {% if form.posted_successfully? %}
    <p>{{ 'contact.success' | t }}</p>
  {% endif %}
  {{ form.errors | default_errors }}
  <input type="email" name="contact[email]" required>
  <textarea name="contact[body]"></textarea>
  <button>Enviar</button>
{% endform %}

paginateMerge

{% paginate lista by cantidad %} … {% endpaginate %}

Marca el bloque paginado. La tienda ya pagina las colecciones, la búsqueda y los blogs con un tamaño de página propio (el by se acepta por compatibilidad); adentro, el objeto paginate tiene las páginas y los links.

{% paginate collection.products by 24 %}
  {% for product in collection.products %}…{% endfor %}
  {% if paginate.next %}<a href="{{ paginate.next.url }}">Siguiente</a>{% endif %}
{% endpaginate %}

stylesheetMerge

{% stylesheet %} … {% endstylesheet %}

CSS de una sección o snippet. La plataforma junta todos los bloques en un único archivo que se carga desde content_for_header. Adentro no se interpreta Liquid.

{% stylesheet %}
  .banner { padding: 4rem 1rem; }
{% endstylesheet %}

javascriptMerge

{% javascript %} … {% endjavascript %}

JavaScript de una sección o snippet. Se junta en un único archivo (con defer); cada bloque corre aislado, así que el error de una sección no frena a las demás. Adentro no se interpreta Liquid.

{% javascript %}
  document.querySelectorAll('[data-acordeon]').forEach((el) => { /* … */ });
{% endjavascript %}

Control de flujo

if

{% if condición %} … {% elsif otra %} … {% else %} … {% endif %}

Condicional. Operadores: ==, !=, >, <, >=, <=, contains, and, or.

{% if product.available %}
  <button>Agregar</button>
{% else %}
  <p>Agotado</p>
{% endif %}

unless

{% unless condición %} … {% endunless %}

Lo contrario de if.

{% unless product.available %}<span>Agotado</span>{% endunless %}

case

{% case valor %}{% when a, b %} … {% else %} … {% endcase %}

Elige un bloque según el valor.

{% case section.settings.alineacion %}
  {% when 'centro' %}<div class="centro">
  {% else %}<div>
{% endcase %}

Iteración

for

{% for x in lista limit: n offset: n reversed %} … {% else %} … {% endfor %}

Recorre una lista o un rango ((1..4)). El else se muestra si la lista está vacía. Adentro, forloop tiene index, first, last y length.

{% for product in collection.products limit: 4 %}
  {% render 'product-card', product: product %}
{% else %}
  <p>{{ 'collections.empty' | t }}</p>
{% endfor %}

break

{% break %}

Termina el for.

{% for v in product.variants %}{% if v.available %}{{ v.title }}{% break %}{% endif %}{% endfor %}

continue

{% continue %}

Pasa a la siguiente vuelta del for.

{% for v in product.variants %}{% unless v.available %}{% continue %}{% endunless %}{{ v.title }}{% endfor %}

cycle

{% cycle 'a', 'b' %}

Alterna valores en cada vuelta.

<li class="{% cycle 'par', 'impar' %}">

tablerow

{% tablerow x in lista cols: n %} … {% endtablerow %}

Filas y celdas de una tabla HTML.

<table>{% tablerow p in collection.products cols: 3 %}{{ p.title }}{% endtablerow %}</table>

Variables

captureMerge

{% capture nombre %} … {% endcapture %}

Guarda en una variable lo que renderiza el bloque. Como lo capturado ya es HTML escapado por el motor, al imprimirlo no se vuelve a escapar.

{% capture titulo %}{{ product.title }} · {{ shop.name }}{% endcapture %}
<title>{{ titulo }}</title>

assign

{% assign nombre = valor %}

Crea una variable.

{% assign en_oferta = product.compare_at_price > product.price %}

increment

{% increment contador %}

Imprime un contador y le suma uno.

{% increment visto %}

decrement

{% decrement contador %}

Le resta uno a un contador y lo imprime.

{% decrement restantes %}

echo

{% echo valor | filtro %}

Imprime un valor, como {{ }}. Útil dentro de {% liquid %}.

{% liquid
  echo product.title | upcase
%}

Sintaxis

liquid

{% liquid … %}

Varios tags seguidos sin delimitadores, uno por línea.

{%- liquid
  if variant
    assign price = variant.price
  else
    assign price = product.price
  endif
-%}

comment

{% comment %} … {% endcomment %}

Comentario: no se renderiza.

{% comment %}Tarjeta de producto para grillas{% endcomment %}

#

{% # comentario %}

Comentario de una línea.

{% # Precio con descuento %}

raw

{% raw %} … {% endraw %}

Muestra el contenido sin interpretar Liquid (por ejemplo, plantillas de JavaScript).

{% raw %}{{ esto no se interpreta }}{% endraw %}