Sintassi Xporter: cosa funziona
Una mappa onesta di come viene trattata la sintassi dei modelli in stile Xporter quando carichi un documento Word nella modalità modello Word. Rispecchia lo scanner di migrazione che viene eseguito a ogni caricamento: le stesse classificazioni che vedi nel report di compatibilità dell'editor.
La promessa onesta
Exportelier non è compatibile con Xporter, non è un sostituto di Xporter e non esegue i modelli Xporter. Quello che fa è aiutarti a migrare: al caricamento, lo scanner riconosce la sintassi comune in stile Xporter e ti indica, costrutto per costrutto, se funziona già, se può essere convertito automaticamente, se richiede una riscrittura manuale o se è fuori ambito per scelta progettuale.
Due garanzie ferme:
- La sintassi estranea viene solo riconosciuta, mai eseguita. Lo scanner legge la forma di un costrutto —
#{for …},${dateformat(…)}— e nulla di un modello caricato viene mai valutato come codice. - Non viene copiato codice di terzi. I pattern di rilevamento e i suggerimenti di alias sono scritti da Exportelier a partire da forme sintattiche documentate pubblicamente.
Ogni rilievo ricade in una di quattro classi.
1. Funziona senza modifiche
Se il tuo modello usa già la sintassi canonica di Exportelier, funziona così com'è. Questo produce una nota informativa, non un avviso.
| Costrutto | Esempio |
|---|---|
| Token di valore | ${issue.key} |
| Ciclo | ${#each issue.subtasks as sub}…${/each} |
| Condizione | ${#if issue.assignee}…${#else}…${/if} |
2. Convertibile automaticamente
Sintassi Xporter comune con un equivalente sicuro uno a uno. L'editor mostra un avviso e propone una sostituzione copiabile.
| Costrutto Xporter | Equivalente in Exportelier | Note |
|---|---|---|
${Key}, ${Summary}, ${Status}, … | ${issue.key}, ${issue.summary}, ${issue.status}, … | Alias di campi scalari. |
${Assignee.displayName} | ${issue.assignee.displayName} | Alias di radice noto; il resto del percorso viene mantenuto. |
#{for comments} | ${#each comments as c} | Apertura di ciclo. |
#{if(Assignee)} | ${#if issue.assignee} | Condizione semplice di presenza. |
#{else} | ${#else} | Marcatore else. |
Alias scalari riconosciuti (16): Key, Summary, Description, Status, Priority, Resolution, Assignee, Reporter, Creator, Created, Updated, DueDate, IssueType, Type, Project, Labels.
Alias di raccolta riconosciuti (5): Comments, Attachments, Subtasks, Links, Worklogs.
Un suggerimento ha la forma giusta, ma la destinazione deve comunque essere un'associazione reale del riferimento dei token. Alcuni alias richiedono un aggiustamento manuale:
- Non associabili:
Creator→issue.creator,Resolution→issue.resolution,Project→issue.project,IssueType/Type→issue.issuetype. Nessuno è un'associazione di livello A. - Differenza di maiuscole:
DueDateviene suggerito comeissue.duedate; l'associazione èissue.dueDate. - Tipo errato:
Labelsviene suggerito come scalare, maissue.labelsè una raccolta — usa${#each issue.labels as l}…. - Collegamenti tra ticket:
Linksviene suggerito comelinks, ma l'associazione reale èissue.issueLinks.
3. Non supportato ma spiegabile
Nessuna corrispondenza pulita uno a uno, ma un modo chiaro per esprimere lo stesso intento. L'editor spiega la riscrittura; è un avviso, non un blocco.
| Costrutto Xporter | Perché | Cosa fare invece |
|---|---|---|
${Comments[0].Body} | I percorsi non supportano l'indicizzazione con parentesi. | Itera: ${#each comments as c}${c.body}${/each}. |
#{end} | Un terminatore generico. | Usa la chiusura corrispondente: ${/each} o ${/if}. |
#{if(votes > 0)} | Le condizioni verificano solo la presenza di un percorso; nessun operatore. | Verifica la presenza: ${#if issue.votes}. |
#{elseif(…)} | elseif non esiste. | Annida le condizioni. |
Qualsiasi altra direttiva #{…} | Non riconosciuta. | Sostituiscila con la sintassi ${…}. |
${#each}/${/if} non bilanciati, percorso errato, ${ non chiuso | Rilevato dal parser. | Correggi il token; il report indica la posizione esatta. |
4. Non sicuro o non supportato
Fuori ambito per scelta: supportarli trasformerebbe il modello in un motore di scripting, cosa che Exportelier deliberatamente non è. L'editor mostra un errore e il costrutto non viene mai eseguito.
| Costrutto Xporter | Stato | Cosa fare invece |
|---|---|---|
${dateformat("yyyy-MM-dd")} e altre chiamate a funzioni o filtri | Le funzioni non vengono mai eseguite. | Usa l'insieme fisso di formattatori, ad es. ${issue.created | date("yyyy-MM-dd")}. |
${jql("project = ABC")} / #{JQL: …} | JQL non viene mai eseguito da un modello. | Scegli i ticket tramite il contesto di esportazione. |
| JavaScript, Groovy, Velocity, FreeMarker, filtri JS | Non è un linguaggio di scripting. | Esprimi il layout con token, cicli, condizioni e formattatori. |
Variabili set, break/continue, aritmetica, espressioni | Non è un linguaggio di scripting. | Ristruttura con i costrutti supportati. |
Cosa fa il validatore con questi rilievi
Al caricamento ogni rilievo diventa una diagnostica con una gravità:
- info — funziona senza modifiche, nessuna azione.
- warning — convertibile automaticamente o spiegabile; l'esportazione prosegue, ma un valore può risultare vuoto se l'associazione è sconosciuta.
- error — sintassi non sicura o non supportata, percorso non sicuro o errore di analisi.
I costrutti che Word conserva ma non riempie — caselle di testo, note a piè di pagina, controlli contenuto, codici di campo, commenti e revisioni — vengono segnalati a parte come avvisi unsupported-location. Il documento li mantiene, ma i token al loro interno non vengono riempiti.