Add complete Acai development documentation
- CLAUDE.md: expanded with critical rules, hook syntax, DB conventions, web-base endpoint - docs/modular-system.md: modules, general sections, global vars, multiv2 - docs/builder-fields.md: all field types, c-if/c-for/c-class, c-form, built-in components - docs/twig-filters.md: get, hook, module, queryDB, imagec, translate, raw, etc. - docs/hooks-and-api.md: PHP hooks, CmsApi CRUD, table schemas, field formats - docs/css-js-conventions.md: Tailwind, BEM, CSS vars, Vue 3 integration, CmsApi JS Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -4,51 +4,102 @@
|
||||
|
||||
Modules are the visual building blocks of Acai websites. Each module lives in `template/estandar/modulos/<module-id>/`.
|
||||
|
||||
### File structure
|
||||
### File Structure
|
||||
|
||||
```
|
||||
<module-id>/
|
||||
├── index-base.tpl # Source Twig template (EDIT THIS)
|
||||
├── index-base.tpl # Source template (EDIT THIS)
|
||||
├── index.tpl # Compiled output (auto-generated, do NOT edit)
|
||||
├── index-twig.tpl # Compiled Twig output (auto-generated, do NOT edit)
|
||||
├── builder.json # Compiled builder vars (auto-generated, do NOT edit)
|
||||
├── style.css # Module-scoped styles
|
||||
└── script.js # Module JavaScript
|
||||
```
|
||||
|
||||
### Twig Templates
|
||||
### Template Syntax
|
||||
|
||||
<!-- TODO: Document Twig syntax, variable access, builder vars -->
|
||||
Templates use a hybrid of **Twig** and **Acai attributes**. The source file is always `index-base.tpl`.
|
||||
|
||||
### Custom Twig Filters
|
||||
```html
|
||||
<section class="hero-section" id="{{ section_id }}">
|
||||
<div class="container mx-auto px-4">
|
||||
<h2 data-field-type="headfield" class="text-3xl font-bold">
|
||||
Title here
|
||||
</h2>
|
||||
<p data-field-type="textbox" class="text-lg text-gray-600">
|
||||
Description text
|
||||
</p>
|
||||
<img data-field-type="upload" src="placeholder.jpg" class="w-full rounded-lg" />
|
||||
<a data-field-type="link" href="#" class="btn">Call to action</a>
|
||||
</div>
|
||||
</section>
|
||||
```
|
||||
|
||||
<!-- TODO: Document custom filters available in Acai (e.g., |translate, |slugify, etc.) -->
|
||||
### Including Modules from Other Modules
|
||||
|
||||
### Builder Variables
|
||||
```html
|
||||
<module_id :param1="value1" :param2="'string value'"></module_id>
|
||||
```
|
||||
|
||||
<!-- TODO: Document how builder vars work, how to access them in templates -->
|
||||
Parameters are received as variables inside the included module.
|
||||
|
||||
### Calling Modules from Other Modules
|
||||
### Global Variables
|
||||
|
||||
<!-- TODO: Document how to include/call modules from other modules or general sections -->
|
||||
| Variable | Description |
|
||||
|----------|-------------|
|
||||
| `section_id` | Unique ID per module instance (use for anchors, JS scoping) |
|
||||
| `interno` | `true` when viewing in CMS editor, `false` on public site |
|
||||
| `server.HTTP_HOST` | Current domain |
|
||||
| `loop.index` | 1-based iteration index (inside `c-for`) |
|
||||
| `loop.index is odd` / `loop.index is even` | For alternating layouts |
|
||||
|
||||
|
||||
## General Sections
|
||||
|
||||
General sections are reusable layout blocks (headers, footers, sidebars) shared across pages.
|
||||
General sections are database-backed templates used for record views, headers, footers, and reusable layouts. They use the same template engine as modules.
|
||||
|
||||
<!-- TODO: Document how general sections differ from modules, where they live, how to create/edit them -->
|
||||
### Key Differences from Modules
|
||||
|
||||
- Access record data via the `thisrecord` variable
|
||||
- Upload fields return **arrays**: `thisrecord.image[0].urlPath`
|
||||
- Additional upload metadata: `info1` (alt text), `info2`, `info3`, `info4`
|
||||
- Foreign key fields use `_num` suffix: `thisrecord.category_num`
|
||||
- Saved via `save_general_section()` (not `save_module()`)
|
||||
- Parser type 2 = Twig (recommended), 0 = Acai legacy syntax
|
||||
|
||||
### Example: Record Template
|
||||
|
||||
```html
|
||||
<article class="product-card">
|
||||
<img src="{{ thisrecord.imagen[0].urlPath }}"
|
||||
alt="{{ thisrecord.imagen[0].info1 }}"
|
||||
class="w-full h-64 object-cover" />
|
||||
<h3 class="text-xl font-semibold">{{ thisrecord.nombre }}</h3>
|
||||
<p class="text-gray-600">{{ thisrecord.descripcion | raw }}</p>
|
||||
<span class="text-2xl font-bold">{{ thisrecord.precio }}€</span>
|
||||
</article>
|
||||
```
|
||||
|
||||
### Variable Assignment
|
||||
|
||||
Use `<set>` tag to create variables from queries:
|
||||
|
||||
```html
|
||||
<set :categories="'categorias' | get()"></set>
|
||||
<set :featured="'productos' | get({destacado: 1}, 'orden ASC', 3)"></set>
|
||||
```
|
||||
|
||||
|
||||
## CSS & JavaScript
|
||||
## Repeatable Content (multiv2)
|
||||
|
||||
### Module Styles (`style.css`)
|
||||
The `multiv2` builder field type creates repeatable groups of fields:
|
||||
|
||||
<!-- TODO: Document scoping rules, CSS conventions -->
|
||||
```html
|
||||
<div c-for="item in record.items">
|
||||
<h3 data-field-type="textfield">{{ item.title }}</h3>
|
||||
<p data-field-type="textbox">{{ item.description }}</p>
|
||||
<img data-field-type="upload" src="{{ item.image }}" />
|
||||
</div>
|
||||
```
|
||||
|
||||
### Module Scripts (`script.js`)
|
||||
|
||||
<!-- TODO: Document JS conventions, lifecycle, event handling -->
|
||||
|
||||
|
||||
## Builder Field Types
|
||||
|
||||
<!-- TODO: Document data-field-type usage, c-form, c-if, c-for, c-class attributes -->
|
||||
Access individual items: `record.items[0].title`, `record.items[1].image`, etc.
|
||||
|
||||
Reference in New Issue
Block a user