Arquitectura
Renick.Content tiene tres capas:
- Contenido. Un documento es una lista de bloques tipados, guardada como JSON en un campo host: una entrada de Tailor, un atributo de modelo, una página de RainLab.Pages o una entrada de RainLab.Blog. JSON Schema v1 define el formato; cada escritura se valida.
- Editor. Una isla de TipTap 3 / React 19 montada por el form widget
contenteditor. El bundle deassets/distestá commiteado, así que una instalación nunca ejecuta una toolchain de JS. - Renderizado.
BlockRendererconvierte el JSON en HTML en cada petición (medianterenickContent,content_render()o|rc_blocks) y aplica las reglas de visibilidad en el servidor.
Mapa de componentes
Al guardar, DocumentSaveGuard normaliza el documento, lo valida de forma estricta y comprueba BlockRules. Las infracciones que el documento guardado ya tenía no impiden guardar. Tras guardar el host se captura una versión y se actualiza el índice de uso de medios.
El documento vive en el host. Las tablas propias del plugin son auxiliares: renick_content_versions (snapshots, registro de auditoría), renick_content_templates, renick_content_media_usage, renick_content_shared (Contenido compartido), renick_content_scripts (Scripts personalizados), renick_content_api_tokens (con hash) y renick_content_ai_usage (presupuesto mensual de IA).
Dónde vive cada cosa
plugins/renick/content/
├── Plugin.php # registrations only
├── routes.php # REST API (off by default), tile/thumb proxies, form endpoints
├── blocks/ # <handle>/<handle>.yaml definition + <handle>.htm partial
├── classes/ # renderer, document model, Content/ContentApi facades, Integrations/, TailorList/, ai/
├── components/ # renickContent, Entry List, submission form
├── contentfields/ # Tailor content field
├── controllers/ # backend pages (tokens, audit log, scripts, shared content, templates)
├── formwidgets/ # ContentEditor, icon picker
├── console/ # renick:content:* commands
├── models/
├── schema/document-v1.json
├── assets/ # src/ editor source; dist/ and frontend/ committed bundles
└── tests/ # PHPUnit; Playwright e2e lives in /tests-e2eEmpieza por Integrar el campo, Crear bloques, la PHP API o la REST API.