Files
agenticSystem/docs/11b-rules-cheat-sheet.md
Jordan Diaz 2ad2a6f87b docs: data-field-show descubrible desde el summary y el cheat-sheet
La seccion ya estaba escrita, pero el agente no llegaba a ella. Dos motivos:

- El summary del frontmatter y el parrafo de entrada de 01-builder-fields
  enumeran lo que cubre el doc y no mencionaban ni el agrupado en pestanas ni
  la visibilidad condicional. Ese summary no es decorativo: entra en el texto
  que se embebe (title + summary + primeros 2000 chars) y es lo que se ve en
  list_docs, asi que una seccion en el char 10000 sin rastro arriba es
  invisible para la busqueda semantica y para el que decide que doc abrir.

- 11b-rules-cheat-sheet es el doc de consulta rapida y ya tenia la linea de
  data-field-group; sin la hermana de data-field-show, quien mirase ahi
  concluia que las pestanas no se pueden condicionar.

Se anade la linea al cheat-sheet con la gramatica minima y los dos errores
tipicos (se referencia el nombre de variable y no el label; `campo=` es vacio).
2026-08-20 18:00:16 +00:00

132 lines
7.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
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, pestañas y visibilidad condicional de campos (data-field-group, data-field-show), 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` | `<p>` | String |
| `headfield` | `<h1>``<h6>` | String + variable `_tag` |
| `textbox` | `<div>` | String multilínea |
| `wysiwyg` | `<div class="wysiwyg">` | HTML string |
| `link` | `<a>` | URL string |
| `upload` | `<img>` | Array `[{urlPath, info1, info2, info3, info4}]` |
| `uploadMulti` | `<li>` | Itera archivos subidos |
| `list` (fijo) | `<div data-list-options="...">` | Valor seleccionado |
| `list` (tabla) | `<div data-list-table="...">` | `num` del registro |
| `multiv2` | `<li>` wrapper | Array de objetos |
| `colors` | `<div data-field-colors="fondo,titulo">` | Objeto de N colores por nombre |
| `colorpicker` | `<div>` | Hex color |
Pestañas en el panel del módulo: `data-field-group="Estilos"` en el elemento del campo (sin group → pestaña "Principal").
Visibilidad condicional: `data-field-show="modo=1"` en el campo, y `data-field-group-show="modo=1"` en **una** var del grupo para condicionar la pestaña entera. Se referencia el NOMBRE DE VARIABLE, no el label. `modo=` significa vacío (clave de la primera opción de todo `list`), `,` es OR, `!=` niega y `;` encadena condiciones (AND).
## Atributos Acai
| Atributo | Uso | Ejemplo |
|----------|-----|---------|
| `c-if` | Condicional | `<p c-if="activo = 1">` |
| `c-else` | Rama else | `<p c-else>` |
| `c-for` | Loop array | `<li c-for="item in items">` |
| `c-for` (tabla) | Loop BD | `<li c-for="p in productos" c-where="'activo=1'" c-limit="10">` |
| `c-hidden` | Variable oculta | `<div c-hidden="true">` |
| `c-class` | Clase condicional | `<div c-class="{ 'bg-red': color == '1' }">` |
| `c-required` | Required condicional | `c-required="'2' not in camposquitar"` |
| `c-form` | Formulario | `<c-form tableName="'contacto'" captcha="true">` |
## 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 | `"<p>Texto</p>"` |
| `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 |
## Traducciones (multiidioma)
| Regla | Detalle |
|-------|---------|
| Prefix `www` = idioma base | URLs sin prefijo. Otro prefix (p.ej. `en`) sirve bajo `/en/...` — lista con `list_web_languages` |
| Traducir `enlace` con cuidado | Es editable por idioma (path absoluto, p.ej. `/en/contact/`); si cambia el enlace base, CocoEnlace lo regenera |
| Valor `''` borra la traducción | `set_record_translations` con `''` elimina la fila y cae al idioma base |
| Base64 transparente | El valor se guarda Base64 en `cms_traducciones`; tú siempre pasas/recibes texto plano |
| `multitext` = JSON completo | Se traduce el JSON serializado entero en una sola fila, no item por item |
| Campos traducibles | Solo `textfield`, `textbox`, `wysiwyg`, `codigo`, `multitext` |
| Leer traducido | `get_record`/`list_table_records` con `lang: "<prefix>"` |
| Vars de módulo | Sobre `builder_custom` con el `recordNum` de `varsMeta`, clave = NOMBRE de la var (`titulo`), nunca la columna `titleN` |
| Textos generales | Traducir el campo `texto` del registro en `textos_generales` (localiza por `identificador`) |
## 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`).