- Strengthen CLAUDE.md rule 8: Tailwind with no exceptions - Add CLAUDE.md rule 13: all user-visible text must use translation functions (Twig: | translate, PHP: t_var(), JS: CmsApi.t_var()) - Add t_var() reference to hooks-and-api.md and css-js-conventions.md - Update translate entry in quick-reference.md with all 3 contexts Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
94 lines
4.1 KiB
Markdown
94 lines
4.1 KiB
Markdown
# 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` | `<p>` | String |
|
|
| `headfield` | `<h1>`-`<h6>` | String + var `_tag` |
|
|
| `textbox` | `<div>` | String multilínea |
|
|
| `wysiwyg` | `<div class="wysiwyg">` | HTML string |
|
|
| `link` | `<a>` | URL string |
|
|
| `upload` | `<img>` | Array de `{urlPath, info1}` |
|
|
| `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 |
|
|
|
|
## Acai HTML Attributes
|
|
|
|
| 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` | Loop tabla | `<li c-for="p in productos" c-where="'activo=1'" c-limit="10">` |
|
|
| `c-hidden` | Variable oculta | `<p c-hidden="true" data-field-type="textfield">` |
|
|
| `c-class` | Clase condicional | `<div c-class="{ 'bg-red': color == '1' }">` |
|
|
| `c-form` | Formulario | `<c-form tableName="'contacto'" captcha="true">` |
|
|
|
|
## 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 | `"<p class=\"font-bold\">Texto</p>"` |
|
|
| 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) |
|