El desarrollo local via Docker ya no se usa -- todo el trabajo es via Forge/MCP. Mantener las menciones a localhost:8080, docker exec y .docker/ confundia sobre el workflow real. Se deja el campo de respuesta 'dockerUrl' de generate_image tal cual (es el nombre real que devuelve la API hoy, no una instruccion de workflow).
135 lines
8.7 KiB
Markdown
135 lines
8.7 KiB
Markdown
# Acai CMS — Project Instructions
|
|
|
|
This is an Acai CMS website project. Follow these instructions when working with the codebase.
|
|
|
|
## Environment
|
|
|
|
- The site runs on Acai Forge — get the live editable URL with the `get_web_url` MCP tool (never assume a fixed domain)
|
|
- You can make HTTP requests to test pages, APIs, or form submissions against that URL
|
|
- If you need to inspect the live site, use browser tools (Playwright MCP) or HTTP requests to the Forge URL
|
|
|
|
## Project Structure
|
|
|
|
```
|
|
.
|
|
├── template/estandar/
|
|
│ ├── modulos/ # Builder modules (visual components)
|
|
│ │ └── <module-id>/
|
|
│ │ ├── index-base.tpl # Twig template (source — EDIT THIS)
|
|
│ │ ├── style.css # Module styles
|
|
│ │ └── script.js # Module JavaScript
|
|
│ │ ├── index.tpl # Compiled (auto-generated, do NOT edit)
|
|
│ │ ├── index-twig.tpl # Compiled (auto-generated, do NOT edit)
|
|
│ │ └── builder.json # Compiled builder vars (auto-generated, do NOT edit)
|
|
│ ├── css/ # Global CSS
|
|
│ └── js/ # Global JavaScript
|
|
├── hooks/ # PHP hooks (server-side logic)
|
|
├── cms/
|
|
│ ├── data/schema/ # Database table schemas (JSON)
|
|
│ ├── lib/plugins/ # CMS plugins
|
|
│ └── uploads/ # Uploaded media files
|
|
└── .acai # Project config (domain, tokens, DB credentials)
|
|
```
|
|
|
|
## Key Concepts
|
|
|
|
### Modules (`template/estandar/modulos/`)
|
|
Visual components that the site builder uses. Each module is a self-contained unit with its own template (Twig + Acai attributes), CSS, and JS. Modules are placed on pages via the drag-and-drop builder. The editable file is always `index-base.tpl`.
|
|
|
|
- Include other modules: `<module_id :param1="value1"></module_id>`
|
|
- Each module instance gets a unique `section_id` variable for anchors/scoping
|
|
- Use `interno` variable to detect CMS editor mode vs public view
|
|
|
|
See [docs/modular-system.md](docs/modular-system.md) for detailed rules.
|
|
|
|
### Pages
|
|
Every record with an `enlace` field is a page. Pages are either **Builder** (modular) or **Standard**:
|
|
|
|
- **Builder**: `controlador` = `cms/lib/plugins/builder_saas/controlador.php` — content via modules
|
|
- **Standard**: `controlador` = `cms/lib/plugins/builder_saas/controlador_tabla.php` — content in record fields
|
|
|
|
**Critical**: Never change `enlace` or `controlador` of existing pages unless explicitly asked.
|
|
|
|
See [docs/pages-and-records.md](docs/pages-and-records.md) for full details.
|
|
|
|
### General Sections
|
|
Database-backed templates (headers, footers, record views) that use the `thisrecord` variable to access record fields. They use the same Twig + Acai attribute engine as modules.
|
|
|
|
- Upload fields return arrays: `thisrecord.image[0].urlPath`
|
|
- Foreign keys use `_num` suffix: `category_num`
|
|
|
|
See [docs/modular-system.md](docs/modular-system.md) for details.
|
|
|
|
### Hooks (`hooks/`)
|
|
PHP files that execute server-side logic. Triggered by:
|
|
- Twig filter: `'hooks/module_id/' | hook({param: value})`
|
|
- HTML tag: `<hook result="var" endpoint="/hooks/module_id/" :param="value"></hook>`
|
|
- JavaScript: `CmsApi.hook('/hooks/module_id/', {param: value}, callback)`
|
|
- Form action: via `c-form` attribute
|
|
|
|
There are two valid hook locations:
|
|
- Global hooks in `hooks/hooks.<hook-id>.php` for reusable/shared server-side logic
|
|
- Module-specific hooks in `template/estandar/modulos/<module-id>/hook.php` for logic owned by a single module
|
|
|
|
How to reference them:
|
|
- Global hook `hooks/hooks.calcular_precio.php` -> endpoint `/hooks/calcular_precio/`
|
|
- Module hook `template/estandar/modulos/hero_banner/hook.php` -> endpoint `/hooks/hero_banner/`
|
|
- Module hook `template/estandar/modulos/buscadorapartados_hjd8s/hook.php` -> endpoint `/hooks/buscadorapartados_hjd8s/`
|
|
|
|
Rule of thumb:
|
|
- If the logic is only used by one module, prefer that module's `hook.php`
|
|
- If the logic will be reused by several modules/pages, create a global hook in `hooks/`
|
|
- Return arrays from hooks; do not use `echo json_encode(...)` or `exit`
|
|
|
|
See [docs/hooks-and-api.md](docs/hooks-and-api.md) for usage.
|
|
|
|
## Acai Core (web-base)
|
|
|
|
The project workspace contains only the **customization layer** (modules, hooks, schemas, uploads). The CMS core (routing, rendering engine, admin panel, APIs) lives in a separate, shared directory called **web-base**.
|
|
|
|
Do NOT modify web-base files — they are shared across all projects.
|
|
|
|
## Critical Rules
|
|
|
|
1. **Before working with any area (hooks, modules, templates, CSS/JS, etc.), read the corresponding documentation in `docs/` first.** Do not guess or assume — always consult the docs before taking action.
|
|
2. **NEVER use `mkdir` to create directories.** Instead, use `acai-write` to create the first file inside the directory — this creates parent directories automatically. For example, to create a new module, directly write the `index-base.tpl` file.
|
|
3. Only edit `index-base.tpl` in modules — `index.tpl`, `index-twig.tpl`, and `builder.json` are auto-generated
|
|
4. Editing or creating any `index-base.tpl` through `acai-write` or `acai-line-replace` triggers automatic compilation. `compile_module` is only for manual recovery when you need to force a recompile without changing the file.
|
|
5. `script.js` and `style.css` are static files — do NOT use Twig syntax inside them. Pass dynamic values from `index-base.tpl` via `data-*` attributes.
|
|
6. Use Twig **filters** (with `|`), never Twig functions
|
|
7. Table names without `cms_` prefix everywhere
|
|
8. Primary key is `num`, never `id`
|
|
9. Upload fields are arrays — access with `[0].urlPath`
|
|
10. Tailwind CSS as primary styling, custom CSS scoped with BEM when needed
|
|
11. Twig concatenation uses `~` operator: `'value=' ~ variable`
|
|
12. `enlace` (link) fields already include slashes — **NEVER modify an existing enlace** unless explicitly asked
|
|
13. **NEVER modify the `controlador` field** of existing records — it defines whether a page is Builder or Standard
|
|
14. **This repository is PUBLIC. NEVER commit secrets** (API keys, `ANTHROPIC_*` tokens, passwords). Local Claude Code config with credentials goes in `.claude/settings.local.json` (git-ignored), never in `.claude/settings.json`. Enable the secret-scanning hook once per clone: `git config core.hooksPath .githooks`. A leaked key stays in git history even after deleting it: rotate it immediately.
|
|
|
|
## MCP Tools
|
|
|
|
This project has MCP tools for managing modules, records, media, and more. **Before starting any task, consult the tools reference for the correct workflow.**
|
|
|
|
See [docs/mcp-tools-reference.md](docs/mcp-tools-reference.md) for the complete list of available tools and step-by-step workflows.
|
|
|
|
Key workflows:
|
|
- **Create module**: Read [docs/module-creation-guide.md](docs/module-creation-guide.md) first → create files with `acai-write` / refine with `acai-line-replace` → automatic compile on `index-base.tpl` → `add_module_to_record` (returns sectionId) → `set_module_config_vars` (returns uploadFields) → images via uploadFields. Use `compile_module` only if you need a manual recompile without editing the file.
|
|
- **Edit module**: `acai-view` → `acai-line-replace` (or `acai-write` for full rewrites) → automatic compile on `index-base.tpl`
|
|
- **Add images**: use `uploadFields` from `set_module_config_vars` response → `upload_record_image`
|
|
- **Generate images**: `generate_image` → `upload_record_image` with returned URL
|
|
|
|
## Documentation
|
|
|
|
- [docs/modular-system.md](docs/modular-system.md) — Modules, general sections, global variables
|
|
- [docs/builder-fields.md](docs/builder-fields.md) — Builder field types, Acai attributes, c-form, components
|
|
- [docs/twig-filters.md](docs/twig-filters.md) — Twig filters reference (get, hook, module, queryDB, etc.)
|
|
- [docs/hooks-and-api.md](docs/hooks-and-api.md) — PHP hooks, CmsApi, CocoDB, record creation
|
|
- [docs/css-js-conventions.md](docs/css-js-conventions.md) — CSS/JS/Vue 3, Tailwind, BEM, native components
|
|
- [docs/quick-reference.md](docs/quick-reference.md) — Cheat sheet: domain rules, field types, filters
|
|
- [docs/production-patterns.md](docs/production-patterns.md) — Real production patterns (header, zigzag, FAQ, forms)
|
|
- [docs/vue-builder-rules.md](docs/vue-builder-rules.md) — CMS-VUE rules (tabs, colorpicker, components)
|
|
- [docs/vue-builder-examples.md](docs/vue-builder-examples.md) — Vue builder examples (Banner Slideshow, etc.)
|
|
- [docs/pages-and-records.md](docs/pages-and-records.md) — Page types (Builder vs Standard), sections, visibility, critical rules
|
|
- [docs/module-creation-guide.md](docs/module-creation-guide.md) — Module creation workflow, style reference, field types
|
|
- [docs/mcp-tools-reference.md](docs/mcp-tools-reference.md) — MCP tools reference, available tools, workflows
|