Introducción a Liquid
Liquid es un lenguaje de plantillas creado por Shopify que se utiliza para cargar contenido dinámico en páginas web. Consiste en:
- Objetos: Representan contenido y se muestran con
{{ }}(dobles llaves) - Tags(Etiquetas): Crean lógica y control de flujo con
{% %}(llave y porcentaje) - Filtros: Modifican la salida de objetos con
|(pipe)
Sintaxis Básica
Objetos
{{ product.title }} // Muestra el título del producto
{{ shop.name }} // Muestra el nombre de la tienda
{{ page.content }} // Muestra el contenido de una página
Tags(Etiquetas)
{% if condition %} // Inicia un bloque condicional
{% elsif other_condition %} // Condición alternativa
{% else %} // Bloque por defecto
{% endif %} // Cierra el bloque condicional
{% for item in collection %} // Inicia un bucle
{% endfor %} // Cierra el bucle
Filtros
{{ product.price | money }} // Formatea como precio
{{ product.title | upcase }} // Convierte a mayúsculas
{{ "Hola Mundo" | replace: "Mundo", "Shopify" }} // Reemplaza texto
Objetos Globales
shop
{{ shop.name }} // Nombre de la tienda
{{ shop.email }} // Email de la tienda
{{ shop.url }} // URL de la tienda
{{ shop.currency }} // Moneda principal de la tienda
request
{{ request.page_type }} // Tipo de página actual
{{ request.path }} // Ruta de la página actual
{{ request.host }} // Dominio de la tienda
customer (en sesión)
{{ customer.name }} // Nombre completo del cliente
{{ customer.email }} // Email del cliente
{{ customer.orders_count }} // Número de pedidos del cliente
{{ customer.tags }} // Tags asignados al cliente
Operadores de Comparación
{% if product.price > 100 %} // Mayor que
{% if product.price < 100 %} // Menor que
{% if product.price >= 100 %} // Mayor o igual que
{% if product.price <= 100 %} // Menor o igual que
{% if product.price == 100 %} // Igual a
{% if product.price != 100 %} // No igual a
{% if product.title contains "Camiseta" %} // Contiene
Operadores Lógicos
{% if condition1 and condition2 %} // Operador AND lógico
{% if condition1 or condition2 %} // Operador OR lógico
{% if condition1 and condition2 or condition3 %} // Combinación de operadores
{% unless condition %} // Inverso de "if"
{% endunless %}
Bucles y Control de Flujo
{% for product in collection.products %}
{{ product.title }}
{% endfor %}
{% for i in (1..5) %} // Bucle en un rango
{{ i }}
{% endfor %}
{% break %} // Salir del bucle
{% continue %} // Saltar a la siguiente iteración
{% cycle 'odd', 'even' %} // Alternar valores en cada iteración
Variables del Bucle
{{ forloop.index }} // Índice actual (empezando por 1)
{{ forloop.index0 }} // Índice actual (empezando por 0)
{{ forloop.first }} // ¿Es la primera iteración?
{{ forloop.last }} // ¿Es la última iteración?
{{ forloop.length }} // Número total de iteraciones
Variables
{% assign variable = "valor" %} // Asignar una variable
{% capture mi_variable %}Contenido{% endcapture %} // Captura HTML/contenido
Includes y Renders
{% include 'snippet-name' %} // Incluye un snippet
{% include 'product-card', product: product %} // Con parámetros
{% render 'snippet-name' %} // Renderiza un snippet (recomendado)
{% section 'nombre-seccion' %} // Incluye una sección
Filtros Útiles
Texto
{{ product.title | upcase }} // MAYÚSCULAS
{{ product.title | downcase }} // minúsculas
{{ product.title | capitalize }} // Primera Letra En Mayúscula
{{ product.title | escape }} // Escapar HTML
{{ "Hola " | append: "Mundo" }} // Concatenar
{{ product.title | slice: 0, 5 }} // Extrae una parte del texto
{{ product.title | strip_html }} // Elimina HTML
{{ product.title | truncate: 20 }} // Trunca texto a 20 caracteres
Números
{{ product.price | money }} // Formatea como moneda
{{ product.price | money_without_currency }} // Sin símbolo de moneda
{{ product.price | divided_by: 100 }} // División
{{ product.price | times: 0.8 }} // Multiplicación
{{ product.price | plus: 10 }} // Suma
{{ product.price | minus: 10 }} // Resta
{{ product.price | round }} // Redondea
{{ product.price | at_least: 5 }} // Valor mínimo
{{ product.price | at_most: 100 }} // Valor máximo
Fechas
{{ product.published_at | date: "%d/%m/%Y" }} // Formatea fecha
{{ "now" | date: "%H:%M" }} // Hora actual
{{ article.published_at | time_tag }} // Etiqueta <time> HTML
Arrays
{{ product.tags | join: ", " }} // Une array con comas
{{ product.tags | first }} // Primer elemento
{{ product.tags | last }} // Último elemento
{{ product.tags | size }} // Número de elementos
{{ collection.products | sort: "price" }} // Ordenar por precio
{{ collection.products | where: "type", "Camiseta" }} // Filtrar por tipo
Objetos Específicos por Página
Página de Producto
{{ product.title }} // Título del producto
{{ product.description }} // Descripción
{{ product.price }} // Precio
{{ product.images }} // Imágenes
{{ product.featured_image }} // Imagen destacada
{{ product.variants }} // Variantes
{{ product.options }} // Opciones (color, talla, etc.)
{{ product.tags }} // Etiquetas
{{ product.type }} // Tipo de producto
{{ product.vendor }} // Proveedor/Marca
Página de Colección
{{ collection.title }} // Título de la colección
{{ collection.description }} // Descripción
{{ collection.products }} // Productos en la colección
{{ collection.all_products_count }} // Total de productos
{{ collection.image }} // Imagen de la colección
Página de Carrito
{{ cart.items }} // Items en el carrito
{{ cart.item_count }} // Cantidad de productos
{{ cart.total_price }} // Precio total
{{ cart.original_total_price }} // Precio sin descuentos
Condiciones Especiales
{% if template == "product" %} // Verificar tipo de página
{% if product.available %} // ¿Producto disponible?
{% if cart.item_count > 0 %} // ¿Carrito con productos?
{% if customer %} // ¿Cliente logueado?
{% if collections.frontpage.products.size > 0 %} // ¿Colección con productos?
Liquid Avanzado
Filtrado de Colecciones
{% assign featured_products = collections.all.products | where: "type", "Camiseta" %}
{% assign discounted_products = collections.all.products | where: "compare_at_price", ">" , "price" %}
Secciones con Bloques
{% for block in section.blocks %}
{% case block.type %}
{% when 'heading' %}
<h2>{{ block.settings.title }}</h2>
{% when 'text' %}
<p>{{ block.settings.text }}</p>
{% endcase %}
{% endfor %}
Schema de una Sección
{% schema %}
{
"name": "Banner Hero",
"settings": [
{
"type": "text",
"id": "title",
"label": "Título",
"default": "Mi título"
},
{
"type": "image_picker",
"id": "image",
"label": "Imagen"
}
],
"presets": [
{
"name": "Banner Hero",
"category": "Promotional"
}
]
}
{% endschema %}
Consejos y Buenas Prácticas
- Comentarios: Usa
{% comment %}Este es un comentario{% endcomment %}para documentar tu código - Depuración: Usa
{% debug %}o{{ variable | json }}para ver el contenido de variables - Caché: Utiliza
{% render %}en lugar de{% include %}para mejor rendimiento - Snippets: Divide elementos reutilizables en snippets
- Clases dinámicas:
<div class="{% if product.available %}in-stock{% else %}out-of-stock{% endif %}">...</div> - Traducción: Usa
{{ 'products.product.add_to_cart' | t }}para texto traducible