Saltar al contenido principal

Sintaxis del Fluid Engine

El Fluid Engine de OmniBuy implementa una sintaxis compatible con Liquid, con extensiones propias. Los templates pueden usar Go html/template (legacy) o Liquid (feature-flagged con LIQUID_ENGINE=enabled). La detección es automática: si un archivo usa delimitadores {% %}, se procesa como Liquid.

Salida de datos

SintaxisDescripción
{{ expr }}Salida con auto-escape HTML
{{- expr -}}Salida con trim de espacios
{{{ expr }}}Salida raw (sin escape)
{# comment #}Comentario (no se renderiza)

Variables y objetos

{{ store.name }} <!-- Nombre de la tienda -->
{{ product.title }} <!-- Título del producto -->
{{ product.price | money }} <!-- Precio formateado -->
{{ cart.item_count }} <!-- Cantidad de items en el carrito -->

Las variables se acceden con notación de puntos. Si un campo es nil o null, se renderiza como string vacío.

Tags de control de flujo

if / elsif / else

{% if product.compare_at_price > product.price %}
<span class="badge-sale">Oferta</span>
{% elsif product.available == false %}
<span class="badge-sold-out">Agotado</span>
{% else %}
<span class="badge-new">Nuevo</span>
{% endif %}

unless (inverso de if)

{% unless customer.logged_in %}
<a href="/account/login">Inicia sesión</a>
{% endunless %}

case / when

{% case product.type %}
{% when "camisa" %}
<p>Tipo: Camisa</p>
{% when "pantalon", "jeans" %}
<p>Tipo: Pantalón</p>
{% else %}
<p>Tipo: Otro</p>
{% endcase %}

for (iteración)

{% for variant in product.variants %}
<option value="{{ variant.id }}">{{ variant.title }} — {{ variant.price | money }}</option>
{% else %}
<option>No hay variantes</option>
{% endfor %}

Variables del forloop:

VariableDescripción
forloop.indexIteración actual (1-based)
forloop.index0Iteración actual (0-based)
forloop.firsttrue en la primera iteración
forloop.lasttrue en la última iteración
forloop.lengthTotal de elementos
forloop.rindexIteración desde el final (1-based)
forloop.rindex0Iteración desde el final (0-based)

Parámetros del for:

{% for product in collection.products limit:6 offset:3 reversed %}
<!-- ... -->
{% endfor %}

assign y capture

{% assign max_price = 0 %}
{% for product in collection.products %}
{% if product.price > max_price %}
{% assign max_price = product.price %}
{% endif %}
{% endfor %}

{% capture greeting %}
Hola, {{ customer.first_name }}. Tienes {{ cart.item_count }} items.
{% endcapture %}

render y section

{% render "product-card", product: product, show_price: true %}

{% section "hero" %}
{% section "featured_products" %}

render invoca un snippet. section invoca una sección de contenido (Go template).

paginate

{% paginate collection.products by 20 %}
{% for product in collection.products %}
<!-- ... -->
{% endfor %}

{{ paginate | default_pagination }}
{% endpaginate %}

cycle

{% for item in items %}
<div class="{% cycle "odd", "even" %}">{{ item.title }}</div>
{% endfor %}

Con grupo para ciclos independientes:

{% cycle group: "colors", "rojo", "azul", "verde" %}
{% cycle group: "shapes", "cuadrado", "circulo" %}

break y continue

{% for product in collection.products %}
{% if product.available == false %}
{% continue %}
{% endif %}
{% if product.price > 1000 %}
{% break %}
{% endif %}
<!-- renderizar producto -->
{% endfor %}

Operadores

OperadorEjemploDescripción
=={{ a == b }}Igualdad
!= / <>{{ a != b }}Desigualdad
<, >{{ a < b }}Comparación
<=, >={{ a >= b }}Comparación
contains{{ tags contains "sale" }}Contiene (string o array)
and{{ a and b }}AND lógico
or{{ a or b }}OR lógico
not{% unless not flag %}NOT unario

Literales

{{ true }} <!-- booleano -->
{{ false }}
{{ nil }} <!-- nulo -->
{{ null }}
{{ "" }} <!-- string vacío -->
{{ "hola mundo" }} <!-- string -->
{{ 42 }} <!-- entero -->
{{ 3.14 }} <!-- float -->
{{ [1, 2, 3] }} <!-- array -->

Control de espacios

{%- if condition -%}
Sin espacios alrededor
{% endif %}

{% if condition %}
Con espacios normales
{% endif %}

Los guiones (-) recortan el whitespace adyacente al tag.

Tags especiales

TagDescripción
{% raw %}...{% endraw %}Texto literal sin procesar por Liquid
{% comment %}...{% endcomment %}Bloque de comentario
{% schema %}...{% endschema %}JSON schema de la sección (parseado al compilar)
{% style %}...{% endstyle %}CSS embebido (agregado al build)
{% script %}...{% endscript %}JS embebido (agregado al build)

Detección automática de motor

El sistema detecta el motor de template al cargar un archivo:

  • Go template: archivos con {{define}}, {{block}}, {{template}} — se procesan con html/template
  • Liquid: archivos con {% %} sin delimitadores Go — se procesan con el motor Liquid

Esto es transparente para el theme developer: puede usar cualquiera de los dos motores en el mismo tema.