# Quick Reference ## Reglas Críticas | Regla | Correcto | Incorrecto | |-------|----------|------------| | Nombres de tabla | `'productos'` | `'cms_productos'` | | Primary key | `record.num` | `record.id` | | Foreign keys | `categoria_num` | `categoria_id` | | Upload fields | `record.imagen[0].urlPath` | `record.imagen` | | Optimizar imagen | `record.imagen[0].urlPath \| imagec(800)` | `record.imagen.url` | | Filtros Twig | `{{ 'table' \| get() }}` | `{{ get('table') }}` | | Campo enlace | `{{ producto.enlace }}` (ya tiene barras) | `"/{{ producto.enlace }}/"` | | Nombres builder vars | `data-field-label` → sin espacios/especiales, minúsculas | Mantener casing original | | Checkbox | `1` o `0` (número) | `true`/`false` | | Formato fecha | `YYYY-MM-DD HH:mm:ss` | Cualquier otro formato | | c-if igualdad | `c-if="x = 'valor'"` (un `=`) | `c-if="x == 'valor'"` | | Twig if igualdad | `{% if x == 'valor' %}` (doble `==`) | `{% if x = 'valor' %}` | | queryDB tablas | `SELECT * FROM cms_tabla` (con prefijo) | `SELECT * FROM tabla` | | get tablas | `'tabla' \| get()` (sin prefijo) | `'cms_tabla' \| get()` | ## Builder Variable Types | Type | Elemento | Retorna | |------|----------|---------| | `textfield` | `

` | String | | `headfield` | `

`-`

` | String + var `_tag` | | `textbox` | `
` | String multilínea | | `wysiwyg` | `
` | HTML string | | `link` | `` | URL string | | `upload` | `` | Array de `{urlPath, info1}` | | `uploadMulti` | `
  • ` | Itera archivos subidos | | `list` (fijo) | `
    ` | Valor seleccionado | | `list` (tabla) | `
    ` | `num` del registro | | `multiv2` | `
  • ` wrapper | Array de objetos | ## Acai HTML Attributes | Atributo | Uso | Ejemplo | |----------|-----|---------| | `c-if` | Condicional | `

    ` | | `c-else` | Rama else | `

    ` | | `c-for` | Loop array | `

  • ` | | `c-for` | Loop tabla | `
  • ` | | `c-hidden` | Variable oculta | `

    ` | | `c-class` | Clase condicional | `

    ` | | `c-form` | Formulario | `` | ## Twig Filters | Filtro | Uso | |--------|-----| | `get` | `'table' \| get(where, order, limit)` | | `hook` | `'hooks/module_id/' \| hook({params})` | | `module` | `'module_id' \| module({params})` | | `queryDB` | `'SELECT ...' \| queryDB()` | | `imagec` | `path \| imagec(width)` | | `translate` | `'text' \| translate` (Twig) / `t_var('text')` (PHP) / `CmsApi.t_var('text')` (JS) | | `json_decode` | `'json_string' \| json_decode` | | `raw` | `variable \| raw` | | `truncate` | `text \| truncate(100)` | ## Formato de datos para registros | Tipo | Formato | Ejemplo | |------|---------|---------| | Text field | String | `"Texto"` | | Text box | String multilínea | `"Línea 1\nLínea 2"` | | Date/time | `YYYY-MM-DD HH:mm:ss` | `"2025-12-03 10:30:00"` | | Wysiwyg | HTML string | `"

    Texto

    "` | | List | String o número | `"activo"` o `"1"` | | Checkbox | Número 1/0 | `1` o `0` | | Multivalores | String JSON | `"[{\"producto\":\"1\"}]"` | | Upload | NO enviar — subir imagen después de crear registro | ## Variables globales | Variable | Descripción | |----------|-------------| | `section_id` | ID único por instancia del módulo | | `server.HTTP_HOST` | Dominio actual | | `loop.index` | Índice de iteración (1-based) | | `loop.index is odd/even` | Para layouts alternados | | `interno` | True dentro del editor CMS | | `thisrecord` | Registro actual (en secciones generales) | ## Testing | Regla | Detalle | |-------|---------| | Hooks devuelven JSON en network | Al testear con Playwright, usar `browser_network_requests` o `fetch()` en `browser_evaluate`. El snapshot visual no muestra respuestas de hooks | | Vue tarda en montar | Después de navegar a una página con Vue, esperar 3-5s antes de verificar contenido | | `?pruebas` | Añadir a URL para bypass de modo mantenimiento (una vez por sesión) |