diff --git a/docs/03-modules-and-sections.md b/docs/03-modules-and-sections.md index 2d01cce..9eaa997 100644 --- a/docs/03-modules-and-sections.md +++ b/docs/03-modules-and-sections.md @@ -208,10 +208,10 @@ Las variables son **propiedades del objeto iterado**, no variables sueltas. Los valores textuales de las variables de un módulo (títulos, descripciones, wysiwyg, etc.) NO se guardan en la fila de la página, sino en la tabla `builder_custom`. Por eso una traducción de módulo apunta siempre a `builder_custom`, no a `apartados` ni a la tabla de la página. Para traducir las vars de una instancia de módulo: -1. `get_module_config_vars({ tableName, recordNum, sectionId })` devuelve `varsMeta`: por cada variable, su ubicación física `{ fieldName, recordNum }` en `builder_custom` (y por cada item en las vars multi). -2. `set_record_translations({ tableName: "builder_custom", recordNum: , prefix, fields: { : "texto traducido" } })`. +1. `get_module_config_vars({ tableName, recordNum, sectionId })` devuelve `varsMeta`: de ahí interesa el `recordNum` (la fila de `builder_custom` de la instancia; en vars multi, uno por item). +2. `set_record_translations({ tableName: "builder_custom", recordNum: , prefix, fields: { : "texto traducido" } })` — p.ej. `{ titulo: "...", subtitulo: "..." }`. -El nombre humano de la variable (p.ej. `titulo`) NO es el nombre de columna real (p.ej. `title2`): usa siempre el `fieldName` que da `varsMeta`. Ver el workflow completo en `09-mcp-tools-reference.md`. +CRÍTICO: la clave de traducción es el NOMBRE de la var del builder.json (`titulo`, `subtitulo`, `enlace_anchor`...), NUNCA la columna física de `builder_custom` (`title3`, `text1`...). El runtime traduce con `t($record, $var)` por nombre de var; con la columna física se guarda pero no se pinta jamás (la action lo rechaza con 400). Tampoco añadas filtros `| translate` a las plantillas del módulo: el motor traduce las vars automáticamente. Ver el workflow completo en `09-mcp-tools-reference.md`. ## Layout global vs módulos diff --git a/docs/09-mcp-tools-reference.md b/docs/09-mcp-tools-reference.md index f8e9b0f..3581903 100644 --- a/docs/09-mcp-tools-reference.md +++ b/docs/09-mcp-tools-reference.md @@ -307,9 +307,9 @@ Ejemplo: traducir la vacante num=12 al inglés. Los textos de un módulo Builder viven en la tabla `builder_custom`, no en la tabla de la página. 1. `list_web_languages` — obtén el `prefix` destino. -2. `get_module_config_vars({ tableName, recordNum, sectionId })` — devuelve `varsMeta`: por cada variable su `{ fieldName, recordNum }` físico en `builder_custom` (y por item en vars multi). -3. Por cada variable a traducir, `set_record_translations({ tableName: "builder_custom", recordNum: , prefix, fields: { : "texto traducido" } })`. -4. Para vars multi, repite con el `recordNum`/`fieldName` de cada item que devuelve `varsMeta`. +2. `get_module_config_vars({ tableName, recordNum, sectionId })` — de `varsMeta` toma el `recordNum` (fila de `builder_custom`; en vars multi, uno por item). +3. `set_record_translations({ tableName: "builder_custom", recordNum: , prefix, fields: { : "..." } })` — la clave es el nombre de la var (`titulo`, `subtitulo`, `enlace_anchor`), NUNCA la columna física (`title3`): el motor traduce por nombre de var y la columna física se rechaza con 400. No añadas `| translate` a la plantilla: las vars se traducen solas. +4. Para vars multi, repite por cada item con su `recordNum` de `varsMeta` (las claves siguen siendo los nombres de las sub-vars). ### 14. Traducir un texto general (literal de plantilla) diff --git a/docs/11b-rules-cheat-sheet.md b/docs/11b-rules-cheat-sheet.md index eb65283..d8e05a0 100644 --- a/docs/11b-rules-cheat-sheet.md +++ b/docs/11b-rules-cheat-sheet.md @@ -98,7 +98,7 @@ Resumen ejecutable de reglas críticas, tipos de campo, filtros y formatos de da | `multitext` = JSON completo | Se traduce el JSON serializado entero en una sola fila, no item por item | | Campos traducibles | Solo `textfield`, `textbox`, `wysiwyg`, `codigo`, `multitext` | | Leer traducido | `get_record`/`list_table_records` con `lang: ""` | -| Vars de módulo | Se traducen sobre `builder_custom` usando `varsMeta` de `get_module_config_vars` | +| Vars de módulo | Sobre `builder_custom` con el `recordNum` de `varsMeta`, clave = NOMBRE de la var (`titulo`), nunca la columna `titleN` | | Textos generales | Traducir el campo `texto` del registro en `textos_generales` (localiza por `identificador`) | ## Variables globales en Twig diff --git a/mcp-server/tools/helpers/ACAI_ENDPOINTS.md b/mcp-server/tools/helpers/ACAI_ENDPOINTS.md index 701c688..dd4a289 100644 --- a/mcp-server/tools/helpers/ACAI_ENDPOINTS.md +++ b/mcp-server/tools/helpers/ACAI_ENDPOINTS.md @@ -389,7 +389,7 @@ Notas: `prefix === "www"` es el idioma base (URLs sin prefijo, `urlPrefix === "" Notas: - Solo campos traducibles: `textfield`, `textbox`, `wysiwyg`, `codigo`, `multitext` (el multitext se traduce como el JSON serializado completo en una fila). - Un `fieldValue` vacío (`''`) borra la traducción y el runtime cae al idioma base. -- Vars de módulo: usar `tableName: 'builder_custom'` + el `recordNum`/`fieldName` que da `varsMeta` de `get_module_config_vars`. +- Vars de módulo: `tableName: 'builder_custom'` + `recordNum` de `varsMeta` (`get_module_config_vars`), pero el fieldName es el NOMBRE DE LA VAR del builder.json (`titulo`, `subtitulo`, `enlace_anchor`...), nunca la columna física `titleN`/`textN` (la action la rechaza con 400). - Lectura traducida en línea: las tools `list_table_records`/`get_record` pasan `options.translates = ` al `cmsApi` get (equivalente al header `X-ACAI-ACCEPT-LANGUAGE` en cms_api v3). ## Patrones Comunes diff --git a/mcp-server/tools/languages/getRecordTranslations.js b/mcp-server/tools/languages/getRecordTranslations.js index 63d9456..e717a04 100644 --- a/mcp-server/tools/languages/getRecordTranslations.js +++ b/mcp-server/tools/languages/getRecordTranslations.js @@ -19,7 +19,7 @@ Params: Returns translations shaped as { "": { "": { "": "" } } }. -To translate module vars, first call get_module_config_vars to obtain varsMeta ({ fieldName, recordNum } per var) and read from tableName='builder_custom'. For template literals, read tableName='textos_generales' field 'texto'.`, +To read module var translations, call get_module_config_vars for the recordNum (varsMeta) and read tableName='builder_custom' — rows are keyed by VAR NAME ('titulo', 'subtitulo'...), not by physical column (title3). For template literals, read tableName='textos_generales' field 'texto'.`, withAuthParams({ tableName: z.string().describe("Table name without 'cms_' prefix (e.g. 'apartados', 'builder_custom', 'textos_generales')"), recordNums: z.array(z.number()).describe("Array of record 'num' primary keys to read translations for"), diff --git a/mcp-server/tools/languages/setRecordTranslations.js b/mcp-server/tools/languages/setRecordTranslations.js index 94f1ec1..c802c85 100644 --- a/mcp-server/tools/languages/setRecordTranslations.js +++ b/mcp-server/tools/languages/setRecordTranslations.js @@ -13,7 +13,7 @@ Four usage scenarios: 1. Normal records — translate the visible text fields of any content table. tableName without 'cms_', recordNum = the record 'num', fields = { fieldName: translatedText }. 2. configuracion / configuracion_tienda — the global settings tables are ordinary records; translate their text fields the same way (locate the row with list_table_records). 3. textos_generales — the template literals used by the Twig '| translate' filter are normal records: translate their 'texto' field. Find the right num by 'identificador' with list_table_records first (tableName='textos_generales', fields={ texto: '...' }). -4. Module vars — the textual values of a module live in the 'builder_custom' table. Call get_module_config_vars to get varsMeta ({ fieldName, recordNum } per var, and per item for multi vars), then set tableName='builder_custom', recordNum + fields={ : translatedText } from varsMeta. +4. Module vars — the textual values of a module live in the 'builder_custom' table. Call get_module_config_vars to get varsMeta and use its recordNum, BUT the field key MUST be the VAR NAME from builder.json (e.g. 'titulo', 'subtitulo', 'enlace_anchor') — NEVER the physical column (title3, text1...): the engine translates module vars by var name and physical columns are rejected. Example: set tableName='builder_custom', recordNum=, fields={ titulo: 'Translated title' }. Rules: - An EMPTY STRING ('') as a value DELETES that translation (falls back to base language at runtime).