--- title: "Reglas inmutables y cheat-sheet de tipos" tags: [reference, rules, cheat] load_priority: 90 load_when: [cheatsheet] summary: "Reglas no negociables (cms_, num, _num, upload arrays, c-if/{% if %}), tipos de builder field, atributos Acai, filtros Twig, formato de datos para insert/update, errores comunes." --- # Reglas inmutables y cheat-sheet Resumen ejecutable de reglas críticas, tipos de campo, filtros y formatos de datos. Si tienes duda rápida, consulta esto antes de los docs largos. ## Reglas inmutables | Regla | Correcto | Incorrecto | |-------|----------|------------| | Nombres de tabla en tools/Twig/CmsApi | `'productos'` | `'cms_productos'` | | Nombres en `queryDB` | `cms_productos` | `productos` | | Primary key | `record.num` | `record.id` | | Foreign keys | `categoria_num` | `categoria_id` | | Upload fields | `record.imagen[0].urlPath` | `record.imagen` | | Optimizar imagen | `imagen[0].urlPath \| imagec(800)` | `imagen.url` | | Filtros Twig | `{{ 'tabla' \| get() }}` | `{{ get('tabla') }}` | | Campo enlace | `{{ producto.enlace }}` (ya tiene barras) | `"/{{ producto.enlace }}/"` | | Builder var name | `data-field-label` → minúsculas, sin espacios | Mantener casing original | | Checkbox | `1` o `0` (número) | `true` / `false` | | Formato fecha | `YYYY-MM-DD HH:mm:ss` | Cualquier otro | | `c-if` igualdad | `c-if="x = 'valor'"` (un `=`) | `c-if="x == 'valor'"` | | Twig `{% if %}` | `{% if x == 'valor' %}` (doble `==`) | `{% if x = 'valor' %}` | | Concatenación Twig | `'value=' ~ variable` | `'value=' + variable` | ## Tipos de builder field (`data-field-type`) | Tipo | Elemento | Devuelve | |------|----------|----------| | `textfield` | `

` | String | | `headfield` | `

`–`

` | String + variable `_tag` | | `textbox` | `
` | String multilínea | | `wysiwyg` | `
` | HTML string | | `link` | `` | URL string | | `upload` | `` | Array `[{urlPath, info1, info2, info3, info4}]` | | `uploadMulti` | `
  • ` | Itera archivos subidos | | `list` (fijo) | `
    ` | Valor seleccionado | | `list` (tabla) | `
    ` | `num` del registro | | `multiv2` | `
  • ` wrapper | Array de objetos | | `checkbox` | `` o `
    ` | `1` / `0` | | `colorpicker` | `
    ` | Hex color | ## Atributos Acai | Atributo | Uso | Ejemplo | |----------|-----|---------| | `c-if` | Condicional | `

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

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

  • ` | | `c-for` (tabla) | Loop BD | `
  • ` | | `c-hidden` | Variable oculta | `
    ` | | `c-class` | Clase condicional | `
    ` | | `c-required` | Required condicional | `c-required="'2' not in camposquitar"` | | `c-form` | Formulario | `` | ## Filtros Twig | Filtro | Uso | |--------|-----| | `get` | `'tabla' \| get(where, order, limit)` | | `queryDB` | `'SELECT ... FROM cms_tabla' \| queryDB()` | | `hook` | `'hooks/module_id/' \| hook({params})` | | `module` | `'module_id' \| module({params})` | | `imagec` | `path \| imagec(width)` | | `translate` | `'texto' \| translate` (tabla `textos_generales`) | | `raw` | `variable \| raw` | | `truncate` | `text \| truncate(100)` | | `json_decode` | `'json_string' \| json_decode` | | `default` | `variable \| default('fallback')` | | `length`, `upper`, `lower`, `trim`, `replace`, `split`, `filter` | Estándar Twig | ## Formato de datos para insert/update | Tipo | Formato | Ejemplo | |------|---------|---------| | `textfield` | String | `"Texto"` | | `textbox` | String multilínea | `"Línea 1\nLínea 2"` | | `date`/datetime | `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` | | `multitext` | String JSON | `"[{\"item\":\"valor\"}]"` | | `upload` | NO enviar — usar `upload_record_image` después | ## Variables globales en Twig | Variable | Descripción | |----------|-------------| | `section_id` | ID único por instancia del módulo | | `interno` | `true` dentro del editor CMS | | `server.HTTP_HOST` | Dominio actual (sin protocolo) | | `loop.index` | Índice 1-based en `c-for`/`{% for %}` | | `loop.index is odd` / `is even` | Layouts alternados | | `thisrecord` | Registro actual (solo en secciones generales) | ## Errores comunes a evitar - Editar `index.tpl`, `index-twig.tpl` o `builder.json` (autogenerados). - Editar `layout.json` o `custom-header-twig/*` directamente (usa `set_layout_field`). - Usar el `sectionId` como `recordId` para subir imágenes (es el `num` de `builder_custom`). - Usar el nombre de la variable como `fieldName` (es el campo de relations: `image1`, no `imagenes`). - Crear página por registro en `apartados` para detalles (usa `custom-{tableName}/`). - Cambiar `enlace` o `controlador` de un registro existente. - Usar `localhost:8080` o dominios de producción (siempre `get_web_url` + `?pruebas=1`). - Crear archivos JSON de i18n (usa `| translate` + tabla `textos_generales`). - Usar Twig dentro de `script.js` o `style.css` (estáticos — pasa valores via `data-*`). - Llamar `mkdir` (usa `acai-write` directamente — crea el directorio padre). - Usar `upload_record_image` para "reemplazar" una imagen existente (añade un upload nuevo encima — usa `replace_record_image`).