Sintaxis de Xporter: qué funciona
Un mapa honesto de cómo se trata la sintaxis de plantillas al estilo de Xporter cuando sube un documento de Word al modo de plantilla Word. Refleja el analizador de migración que se ejecuta en cada subida: las mismas clasificaciones que ve en el informe de compatibilidad del editor.
La promesa honesta
Exportelier no es compatible con Xporter, no es un sustituto de Xporter y no ejecuta plantillas de Xporter. Lo que hace es ayudarle a migrar: al subir un documento, el analizador reconoce la sintaxis habitual al estilo de Xporter y le indica, construcción por construcción, si ya funciona, si puede convertirse automáticamente, si necesita una reescritura manual o si queda fuera del alcance por diseño.
Dos garantías firmes:
- La sintaxis ajena solo se reconoce, nunca se ejecuta. El analizador lee la forma de una construcción —
#{for …},${dateformat(…)}— y nada de una plantilla subida se evalúa jamás como código. - No se copia código de terceros. Los patrones de detección y las sugerencias de alias son de autoría propia de Exportelier, a partir de formas de sintaxis documentadas públicamente.
Cada hallazgo cae en una de cuatro clases.
1. Funciona sin cambios
Si su plantilla ya usa la sintaxis canónica de Exportelier, funciona sin más. Esto genera una nota informativa, no una advertencia.
| Construcción | Ejemplo |
|---|---|
| Token de valor | ${issue.key} |
| Bucle | ${#each issue.subtasks as sub}…${/each} |
| Condición | ${#if issue.assignee}…${#else}…${/if} |
2. Convertible automáticamente
Sintaxis habitual de Xporter con un equivalente seguro uno a uno. El editor muestra una advertencia y ofrece un reemplazo copiable.
| Construcción de Xporter | Equivalente en Exportelier | Notas |
|---|---|---|
${Key}, ${Summary}, ${Status}, … | ${issue.key}, ${issue.summary}, ${issue.status}, … | Alias de campos escalares. |
${Assignee.displayName} | ${issue.assignee.displayName} | Alias de raíz conocido; el resto de la ruta se conserva. |
#{for comments} | ${#each comments as c} | Apertura de bucle. |
#{if(Assignee)} | ${#if issue.assignee} | Condición simple de presencia. |
#{else} | ${#else} | Marcador else. |
Alias escalares reconocidos (16): Key, Summary, Description, Status, Priority, Resolution, Assignee, Reporter, Creator, Created, Updated, DueDate, IssueType, Type, Project, Labels.
Alias de colección reconocidos (5): Comments, Attachments, Subtasks, Links, Worklogs.
Una sugerencia tiene la forma correcta, pero el destino debe seguir siendo una vinculación real de la referencia de tokens. Algunos alias requieren un ajuste manual:
- No vinculables:
Creator→issue.creator,Resolution→issue.resolution,Project→issue.project,IssueType/Type→issue.issuetype. Ninguno es una vinculación de nivel A. - Diferencia de mayúsculas:
DueDatese sugiere comoissue.duedate; la vinculación esissue.dueDate. - Tipo incorrecto:
Labelsse sugiere como escalar, peroissue.labelses una colección: use${#each issue.labels as l}…. - Vínculos de incidencia:
Linksse sugiere comolinks, pero la vinculación real esissue.issueLinks.
3. No admitido pero explicable
No hay correspondencia limpia uno a uno, pero sí una forma clara de expresar la misma intención. El editor explica la reescritura; es una advertencia, no un bloqueo.
| Construcción de Xporter | Por qué | Qué hacer en su lugar |
|---|---|---|
${Comments[0].Body} | Las rutas no admiten indexación con corchetes. | Itere: ${#each comments as c}${c.body}${/each}. |
#{end} | Un terminador genérico. | Use el cierre correspondiente: ${/each} o ${/if}. |
#{if(votes > 0)} | Las condiciones solo comprueban la presencia de una ruta; no hay operadores. | Compruebe presencia: ${#if issue.votes}. |
#{elseif(…)} | No existe elseif. | Anide condiciones. |
Cualquier otra directiva #{…} | No se reconoce. | Sustitúyala por sintaxis ${…}. |
${#each}/${/if} desequilibrados, ruta incorrecta, ${ sin cerrar | Lo detecta el analizador sintáctico. | Corrija el token; el informe indica la posición exacta. |
4. Inseguro o no admitido
Fuera de alcance a propósito: admitirlo convertiría la plantilla en un motor de scripting, que Exportelier deliberadamente no es. El editor muestra un error y la construcción nunca se ejecuta.
| Construcción de Xporter | Estado | Qué hacer en su lugar |
|---|---|---|
${dateformat("yyyy-MM-dd")} y otras llamadas a funciones o filtros | Las funciones nunca se ejecutan. | Use el conjunto fijo de formateadores, p. ej. ${issue.created | date("yyyy-MM-dd")}. |
${jql("project = ABC")} / #{JQL: …} | JQL nunca se ejecuta desde una plantilla. | Elija las incidencias mediante el contexto de exportación. |
| JavaScript, Groovy, Velocity, FreeMarker, filtros JS | No es un lenguaje de scripting. | Exprese el diseño con tokens, bucles, condiciones y formateadores. |
Variables set, break/continue, aritmética, expresiones | No es un lenguaje de scripting. | Reestructure con las construcciones admitidas. |
Qué hace el validador con estos hallazgos
Al subir el documento, cada hallazgo se convierte en un diagnóstico con una severidad:
- info: funciona sin cambios, sin acción necesaria.
- warning: convertible automáticamente o explicable; la exportación continúa, aunque un valor puede quedar vacío si la vinculación es desconocida.
- error: sintaxis insegura o no admitida, ruta insegura o error de análisis.
Las construcciones que Word conserva pero no rellena —cuadros de texto, notas al pie, controles de contenido, códigos de campo, comentarios y control de cambios— se comunican aparte como advertencias unsupported-location. El documento las mantiene, pero los tokens que contienen no se rellenan.