El planner generaba 3+ steps para tareas simples causando que el coder repitiera acciones en cada step (creaba el módulo varias veces). Ahora el engine fusiona los steps en 1 coder con descripción combinada. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
6.1 KiB
Module Creation Guide
Style Reference
When creating new modules, you MUST match the visual style of the existing project. Follow these steps IN ORDER:
Step 1: Check for docs/project-styles.md
- If the file exists → read it and use it as your style reference. DONE — skip to module creation.
- If the file does NOT exist → continue to Step 2.
Step 2: Determine if exploration is needed
- Count modules in
template/estandar/modulos/that havebuilder.jsonand do NOT start withcustom- - If 3+ qualifying modules exist → continue to Step 3
- If fewer than 3 → skip exploration, create the module based on the user's description. The style will be defined as modules are created.
Step 3: Explore and GENERATE the style guide (MANDATORY)
- Read
index-base.tplandstyle.cssof 3-4 representative modules (only those withbuilder.json, skipcustom-*) - You MUST then call
save_project_styleswith a markdown summary including:- Primary/secondary/accent colors (hex values)
- Font families and sizes used
- Spacing scale (padding/margin patterns)
- Common Tailwind classes and custom CSS patterns
- Button styles, card styles, section layouts
- Any recurring design patterns (gradients, shadows, borders, etc.)
- This saves
docs/project-styles.mdwhich will be read by future module creation tasks — no re-exploration needed.
After creating a module: if docs/project-styles.md does not exist yet and there are now 3+ modules, call save_project_styles.
Module Structure
Each module lives in template/estandar/modulos/<moduleId>/ with:
index-base.tpl— Twig template (source — EDIT THIS)style.css— Module stylesscript.js— Module JavaScriptbuilder.json— Compiled builder vars (auto-generated, do NOT edit)index.tpl/index-twig.tpl— Compiled (auto-generated, do NOT edit)
Creating a Module — Full Workflow
If the module needs JavaScript, you MUST read docs/css-js-conventions.md before writing index-base.tpl or script.js.
If the module needs server-side logic, dynamic data processing, form handling, or reusable backend behavior, you MUST read docs/hooks-and-api.md before creating hook.php or any global hook.
If the module will call hooks from Twig, also review docs/twig-filters.md for the hook filter syntax.
If index-base.tpl contains builder fields (data-field-type), you MUST review docs/builder-fields.md before writing the template.
Hard rules for module files:
index-base.tplis for HTML/Twig onlyscript.jsis for module JavaScriptstyle.cssis for module CSShook.phpis for server-side logic- Do NOT embed
<script>tags inindex-base.tpl - Do NOT put PHP logic in
index-base.tpl script.jsandstyle.cssare static files: do NOT use Twig syntax inside them- Do NOT use
{{ ... }},{% ... %},c-if,c-for, or builder attributes insidescript.jsorstyle.css - If JavaScript needs dynamic values such as
section_idor a hook endpoint, expose them fromindex-base.tplviadata-*attributes - Every editable builder field with
data-field-typeMUST also definedata-field-label - Avoid Tailwind arbitrary-value syntax such as
text-[...],font-[...],leading-[...],bg-[...]insideindex-base.tpl; move those styles tostyle.css
- Read style reference (steps above)
acai-write— Create the module files directly (index-base.tpl,style.css,script.js, optionalhook.php) using project-relative paths and complete file contents.- If the server-side logic belongs only to that module, create
template/estandar/modulos/<module-id>/hook.php - If the logic should be reused across modules/pages, create a global hook in
hooks/hooks.<hook-id>.php - Inside the module, reference its own hook with
/hooks/<module-id>/ - Example: module folder
template/estandar/modulos/buscadorapartados_hjd8s/-> hook endpoint/hooks/buscadorapartados_hjd8s/
- If the server-side logic belongs only to that module, create
- Automatic compile — Writing
index-base.tplautomatically creates the generated template placeholders and triggers compilation.compile_moduleis only a manual recovery tool if you need to force a recompile without changing the file. add_module_to_record— Adds the module to a page. Response includessectionId— use it directly in the next step.set_module_config_vars— Fill variables with content. Response includesuploadFieldswith{ fieldName, recordNum }for each upload variable.- Upload images — Use
generate_imagethenupload_record_imagewith therecordNumandfieldNamefrom step 5'suploadFields. No need to read builder.json or call get_module_config_vars. navigate_browser— Navigate to the page so the user can see the result.
HTML Field Types
Use these data-field-type attributes in index-base.tpl:
| Attribute | Purpose | Example |
|---|---|---|
headfield |
Editable heading | <h2 data-field-type="headfield">Title</h2> |
textfield |
Short editable text | <span data-field-type="textfield">Text</span> |
wysiwyg |
Rich text editor | <div data-field-type="wysiwyg">Content</div> |
upload |
Image upload | <img data-field-type="upload" src="..."> |
list |
Select dropdown | <div data-field-type="list" data-options="opt1,opt2"> |
multiv2 |
Repeater/records | <div data-field-type="multiv2">...</div> |
checkbox |
Toggle | <div data-field-type="checkbox"> |
colorpicker |
Color picker | <div data-field-type="colorpicker"> |
MJML Modules
Modules with MJMLModule: true in their schema are email modules:
- Only appear when the page table is
mail_marketing - For
mail_marketingtables, only MJML modules are shown - Use MJML markup instead of standard HTML
Key Rules
- Always use Tailwind CSS as primary styling
- Use
section_idvariable for unique anchors/scoping - Use
internovariable to detect CMS editor vs public view - Include other modules with:
<module_id :param1="value1"></module_id> - Editing
index-base.tplwithacai-writeoracai-line-replacecompiles automatically - Twig uses filters (with
|), never functions - Twig concatenation uses
~:'value=' ~ variable