# Twig Filters Reference Acai usa filtros Twig con sintaxis `|`. No usar funciones Twig — solo filtros. ## `get` — Consultar tabla de BD ```twig {{ 'table_name' | get(where, order, limit) }} ``` - `table_name`: sin prefijo `cms_` - `where`: string SQL o objeto (opcional) - `order`: string de orden (opcional) - `limit`: int (opcional) ```twig {# Todos los registros #} {% set products = 'productos' | get() %} {# Con WHERE string #} {% set active = 'productos' | get('activo=1') %} {# Con WHERE objeto #} {% set active = 'productos' | get({activo: 1}) %} {# Con WHERE + ORDER + LIMIT #} {% set latest = 'noticias' | get('publicado=1', 'fecha DESC', 6) %} {# Completo #} {% set caros = 'productos' | get('precio > 100', 'precio DESC', 20) %} {# Single record (primer resultado) #} {% set product = 'productos' | get({num: 42}) %} {{ product[0].nombre }} ``` Iterar resultados: ```twig {% for producto in 'productos' | get('activo=1', 'num DESC', 10) %}

{{ producto.titulo }}

{% endfor %} ``` ## `queryDB` — SQL directo Usa nombre de tabla completo WITH prefijo `cms_`. ```twig {% set results = 'SELECT * FROM cms_productos WHERE precio > 100 ORDER BY precio ASC' | queryDB() %} {# JOIN complejo #} {% set top = 'SELECT p.*, COUNT(v.num) as ventas FROM cms_productos p LEFT JOIN cms_ventas v ON v.producto_num = p.num GROUP BY p.num ORDER BY ventas DESC LIMIT 5' | queryDB() %} ``` Usar solo cuando `get` no sea suficiente. ## `hook` — Ejecutar PHP Hook ```twig {# Llamar y mostrar resultado #} {{ 'hooks/module_id/' | hook({param1: 'value', param2: variable}) }} {# Capturar en variable #} {% set result = 'hooks/calcular_precio/' | hook({cantidad: 5, tipo: 'mayoreo'}) %}

Total: ${{ result.total }}

``` ## `module` — Renderizar otro módulo ```twig {{ 'other_module_id' | module({param1: value1}) }} {# Capturar en variable #} {% set carrito = 'carrito_compras' | module({usuario_id: 123}) %} ``` ## `imagec` — Optimizar/redimensionar imágenes ```twig {# Redimensionar a ancho #} {# En srcset #} ``` ## `translate` — Texto editable y traducción Cualquier string con `| translate` se resuelve contra la tabla `textos_generales` del proyecto. Esta tabla cumple **dos funciones a la vez**: 1. **Traducción**: cada fila guarda la versión del texto por cada idioma habilitado del proyecto. 2. **Edición de contenidos**: es el canal oficial para que el usuario final (o el agente) **modifique esos textos sin tocar código**. El filtro `| translate` no es solo i18n — es el mecanismo por el que un texto "hardcodeado" en una plantilla se vuelve editable desde el CMS. ```twig {{ 'Bienvenido' | translate }} {{ variable | translate }} ``` **Cómo funciona:** - Los strings envueltos en `| translate` en las plantillas o en el código de los módulos se buscan en `textos_generales`. - Si existe la fila, devuelve el valor guardado (en el idioma activo). - Si no existe, devuelve el texto original tal cual (fallback). - Las filas se editan desde el admin del CMS o via `cmsApi` (update sobre `textos_generales`). **Reglas críticas para el agente:** - **No crees archivos JSON de traducciones, `.po`, ni ningún sistema i18n externo**. El único sistema de textos traducibles/editables es la tabla `textos_generales`. - **No hardcodees los textos en el código del módulo** si se espera que el usuario pueda cambiarlos. Envuélvelos siempre en `| translate`: `{{ 'Contáctanos' | translate }}` en vez de `Contáctanos`. - Para **cambiar un texto** (traducirlo o editarlo), el flujo correcto es editar la fila correspondiente en `textos_generales` — nunca modificar el código de la plantilla. - Para **añadir un texto nuevo editable**, basta con escribir el string en el código con `| translate`; el sistema lo recogerá y el usuario podrá editarlo desde el admin. No hace falta insertar la fila manualmente (aunque se puede via `cmsApi` si quieres pre-cargar traducciones). ## `raw` — Renderizar HTML sin escapar ```twig {{ record.description | raw }} ``` ## `truncate` — Truncar texto ```twig {{ record.description | truncate(150) }} ``` ## `json_decode` — Parsear JSON ```twig {% set data = jsonString | json_decode %} {{ data.key }} ``` ## `split`, `filter` — Filtros estándar Twig Misma funcionalidad que Twig estándar. --- ## Operadores y Sintaxis ### Concatenación Twig usa `~` (no `.` ni `+`): ```twig {{ 'Hello ' ~ name ~ '!' }} {% set url = '/products/' ~ product.slug ~ '/' %} ``` ### Concatenar en filtros ```twig {% set stock = 'stocks' | get('producto_num=' ~ producto.num) %} ``` ### Ternario / Default ```twig {{ title | default('Default Title') }} {{ isActive ? 'active' : 'inactive' }} ``` ### Comparaciones ```twig {% if items | length > 0 %} {% if type == 'premium' %} {% if name is not empty %} ``` En `c-if` usar `=` (simple). En `{% if %}` usar `==` (doble). --- ## Ejemplos complejos ### Galería con productos y stock ```twig {% for producto in 'productos' | get('destacado=1', 'num DESC', 12) %}
{{ producto.titulo }}

{{ producto.titulo }}

{{ producto.descripcion | truncate(100) }}

{% set stock = 'stocks' | get('producto_num=' ~ producto.num) %} Stock: {{ stock[0].cantidad }}
{% endfor %} ``` ### Múltiples filtros combinados ```twig {% set categorias = 'categorias' | get() %} {% set productos = 'productos' | get('activo=1', 'titulo ASC', 20) %} {% set stats = 'hooks/obtener_stats/' | hook({fecha_inicio: '2024-01-01'}) %}

{{ stats.titulo | translate }}

{% for prod in productos %}

{{ prod.titulo }}

{% endfor %} ``` --- ## Puntos importantes 1. **Solo filtros, no funciones:** `'tabla' | get()` no `get('tabla')` 2. **Upload fields son arrays:** `record.imagen[0].urlPath`, no `record.imagen` 3. **Tablas sin prefijo `cms_`** en `get()`. Con prefijo en `queryDB()` 4. **Concatenar con `~`:** `'stocks' | get('producto_num=' ~ producto.num)`