# Páginas y Registros Este documento explica cómo Acai modela las páginas del sitio: toda fila con campo `enlace` es una página, y según el campo `controlador` puede ser **Builder** (modular, contenido por módulos) o **Standard** (contenido directo en los campos del registro). Cubre los tipos de tabla por `menuType` (`category`, `multi`, `single`, `separador`), las particularidades de la tabla `apartados`, los campos de visibilidad (`visible_en_el_menu` vs `visible`), las reglas inviolables sobre `enlace` y `controlador`, y el patrón canónico para implementar el detalle de un registro vía sección general `custom-{tableName}`. Léelo antes de crear, modificar o eliminar cualquier registro de tabla con `enlace`. ## Tipos de página Todo registro con campo `enlace` es una **página pública**. El campo `controlador` decide cómo se renderiza. ### Builder (modular) - `controlador` = `cms/lib/plugins/builder_saas/controlador.php` - El contenido se construye con **módulos** (drag & drop) - El campo `builder` contiene un array JSON de instancias de módulos - Tools: `add_module_to_record`, `set_module_config_vars`, `list_page_modules`, `reorder_module`, `toggle_module_visibility` - La página renderiza los módulos en orden ### Standard (campos directos) - `controlador` = `cms/lib/plugins/builder_saas/controlador_tabla.php` - El contenido vive en los campos del registro (`content`, `titulo_alternativo`, etc.) - El campo `content` es HTML (wysiwyg) - Tool: `create_or_update_record` para editar el contenido directamente - No se usan módulos del builder ### Cómo detectar el tipo **Siempre comprueba el campo `controlador` del registro**: - Contiene `controlador.php` (sin `_tabla`) → **Builder** - Contiene `controlador_tabla.php` → **Standard** ## Tipos de tabla con páginas (sections) Las tablas con páginas se llaman **secciones**. El campo `menuType` del schema define el tipo: ### `menuType = "category"` - **Jerárquico** — páginas con relaciones padre/hijo - Campos especiales: `parentNum`, `depth`, `globalOrder`, `lineage`, `siblingOrder`, `breadcrumb` - Ejemplo: `apartados` (páginas principales del sitio) - Visibilidad: campo `visible_en_el_menu` (1 visible, 0 oculto) - Orden: `globalOrder` ### `menuType = "multi"` - **Lista plana** — sin jerarquía - Orden: `dragSortOrder` - Ejemplos: `blog`, `noticias`, `productos`, `vacantes`, `travesias` - Visibilidad: campo `visible` (1 visible, 0 oculto) ### `menuType = "single"` - Página única (un solo registro) - Ejemplos: home, about us - No requiere campos de orden ### `menuType = "separador"` - Separador visual en el menú del admin (no es una tabla con datos) ## La tabla `apartados` La tabla principal de páginas en la mayoría de sitios Acai. Características: | Campo | Descripción | |-------|-------------| | `num` | Primary key | | `name` | Nombre de la página (campo título) | | `enlace` | URL pública (ya con barras: `/servicios/`) | | `controlador` | Define Builder vs Standard | | `menuType` | `"category"` (jerárquico) | | `parentNum` | `num` del padre (`0` = raíz) | | `depth` | Nivel de anidamiento (`0` raíz, `1` hijo, `2` nieto) | | `globalOrder` | Orden global en el árbol | | `visible_en_el_menu` | `1` visible, `0` oculto | | `breadcrumb` | Auto-generado | | `builder` | JSON con instancias de módulos (si es Builder) | | `content` | HTML del contenido (si es Standard) | Cada registro de `apartados` puede ser Builder o Standard — comprueba `controlador` por registro. ## Reglas críticas para páginas ### NUNCA cambies el campo `enlace` A menos que el usuario te lo pida explícitamente, **nunca modifiques `enlace`**. Cambiarlo: - Rompe enlaces externos (SEO, marcadores, otros sitios) - Rompe enlaces internos del propio sitio - Genera 404 hasta que se regeneren los aliases Si el usuario sí pide cambiarlo, considera usar la tool `regenerate_enlaces` con `generateAlias=true` para mantener los enlaces antiguos como redirects. ### NUNCA cambies el campo `controlador` `controlador` define si la página es Builder o Standard. Cambiarlo a posteriori rompe el render. Solo se setea durante la creación. ### Campos de visibilidad Comprueba siempre qué campo tiene la tabla antes de cambiar visibilidad: - `apartados` y otras categorías → `visible_en_el_menu` - `blog`, `travesias`, `noticias` y otras multi → `visible` ### Campos de título - Algunas tablas usan `name` (e.g. `apartados`) - Otras usan `title` (e.g. `blog`, `travesias`) - Consulta el schema (`get_table_schema`) antes de asumir. ## Trabajar con páginas Builder ### Añadir contenido a una página Builder nueva 1. Listar módulos disponibles con `acai-glob` (`template/estandar/modulos/*/builder.json`). 2. `add_module_to_record` (uno cada vez, en orden). Devuelve `sectionId`. 3. `set_module_config_vars` con el `sectionId` para rellenar variables. Devuelve `uploadFields`. 4. Imágenes: `upload_record_image` o `generate_image` usando los `recordNum` y `fieldName` de `uploadFields`. 5. `navigate_browser` para que el usuario vea el resultado. ### Editar una página Builder existente 1. `list_page_modules` — ver el layout actual (sectionIds, posiciones, visibilidades). 2. `get_module_config_vars` — leer las variables actuales del módulo a modificar. 3. `set_module_config_vars` — actualizar valores. 4. O editar el template del módulo: `acai-view` + `acai-line-replace` sobre `index-base.tpl` (compila automáticamente). 5. `reorder_module` para mover módulos, `toggle_module_visibility` para ocultar/mostrar. ## Trabajar con páginas Standard Usa `create_or_update_record`. Campos típicos: | Campo | Descripción | |-------|-------------| | `content` | HTML del contenido (wysiwyg) | | `titulo_alternativo` | Título mostrado en la página | | `titulo_de_pagina` | `
Ofrecemos…
" titulo_de_pagina: "Servicios | Mi Sitio" metatag_descripcion: "Descubre nuestros servicios…" ``` ## Patrón canónico — Detalle de registro Para cualquier tabla con campo `enlace` (productos, noticias, vacantes, servicios), **el detalle se resuelve por convención** vía sección general `custom-{tableName}`. Ver `03-modules-and-sections.md` para detalles. Reglas duras: - **NO** crees una página por registro en `apartados`. - **NO** uses ni configures `_detailPage` — no existe. - **NO** uses query params (`?id=5`) en URLs. - **NO** uses hooks para cargar el registro — `thisrecord` ya existe. - El nombre del módulo es **literalmente** `custom-` + `tableName`. Flujo para una funcionalidad tipo "vacantes": 1. `create_table` con `enlace=true` 2. `create_field` para los campos necesarios 3. Crear `template/estandar/modulos/custom-vacantes/index-base.tpl` que use `thisrecord.*` 4. (Opcional) Módulo de listado `vacantes_listado` que consulte y enlace 5. (Opcional) Página índice `/vacantes/` en `apartados` con el módulo de listado ## Campos típicos en tablas "publicables" Cuando creas una tabla con `enlace` (noticias, vacantes, blog), añade por defecto: | Campo | Tipo | Uso | |-------|------|-----| | `fecha_publicacion` | date | Ordenar y filtrar | | `fecha_expiracion` | date (opcional) | Oculta el registro automáticamente cuando caduca | | `visible` | checkbox | Control manual | NO añadas un campo "estado" calculado si ya tienes `visible` + fechas. ## Reglas críticas 1. **Toda tabla con `enlace` produce páginas públicas.** Comprueba el `controlador` para saber si son Builder o Standard. 2. **NUNCA modifiques `enlace`** salvo petición explícita del usuario. 3. **NUNCA modifiques `controlador`** de un registro existente. 4. **PK siempre es `num`**, nunca `id`. Foreign keys con sufijo `_num`. 5. **Visibilidad**: `visible_en_el_menu` para `category`, `visible` para `multi`. Comprueba el schema. 6. **Detalle de registro = `custom-{tableName}`**, nunca página duplicada. 7. **Tablas sin prefijo `cms_`** en todas las llamadas a tools. 8. **Para formularios estándar usa `c-form`**, no construyas POST/hook custom.