Skill: AL Translation Management
Purpose
Manage multilingual translations for AL extensions using XLF files: create and refresh language files, batch-translate with NAB AL Tools, preserve placeholders, enforce character limits, maintain terminology consistency, and implement quality review workflows.
When to Load
This skill should be loaded when:
- A new target language needs to be added to an AL extension
- Untranslated texts need to be translated after code changes
- Translation quality review is needed (placeholder validation, character limits)
- Regional language variations must be managed (es-ES vs es-MX)
- Incremental translation is required after refreshing XLF files
Core Patterns
Pattern 1: Create Language File
Create a new XLF translation file from the generated source:
createLanguageXlf
generatedXlfFilePath: "Translations/MyApp.g.xlf"
targetLanguageCode: "es-ES"
matchBaseAppTranslation: true // pre-populate from Microsoft base translations
Rules:
- The
.g.xlffile is auto-generated by the AL compiler — never edit it manually matchBaseAppTranslation: truecopies existing Microsoft translations for standard terms- One language file per locale:
MyApp.es-ES.xlf,MyApp.fr-FR.xlf, etc.
Pattern 2: Refresh and Retrieve Texts
After code changes, sync the language file and get new untranslated texts:
// Step 1: Refresh — adds new entries, preserves existing translations
refreshXlf
generatedXlfFilePath: "Translations/MyApp.g.xlf"
filePath: "Translations/MyApp.es-ES.xlf"
// Step 2: Get untranslated texts with context
getTextsToTranslate
filePath: "Translations/MyApp.es-ES.xlf"
limit: 50
offset: 0
Each text entry includes:
id— unique identifier for the translation unitsource— original text to translatetype— context:Table Customer - Field Name - Property CaptionmaxLength— character limit (if set in AL source)comments— notes about placeholders (%1, %2)
Pattern 3: Batch Translation
Translate multiple texts in a single operation:
saveTranslatedTexts
filePath: "Translations/MyApp.es-ES.xlf"
translations: [
{
"id": "Table_ContosoProject_Field_Description_Caption",
"targetText": "Descripción",
"targetState": "translated"
},
{
"id": "Page_ContosoProjectCard_Action_Release_Caption",
"targetText": "Lanzar",
"targetState": "translated"
},
{
"id": "Codeunit_ContosoMgt_Error_CustomerNotFound",
"targetText": "Cliente %1 no encontrado.",
"targetState": "translated"
}
]
Translation rules:
- Preserve placeholders —
%1,%2,%3must appear in the same order - Respect
maxLength— abbreviate if needed, never exceed - Match context — same English word may have different translations depending on
type - Follow Microsoft terminology — use base app translations for standard BC terms
Pattern 4: Translation Quality Review
Use translation states to implement a review workflow:
| State | Meaning | Who |
|---|---|---|
translated |
Initial translation done | Translator |
needs-review-translation |
Flagged for review | Translator / QA |
final |
Reviewed and approved | Reviewer |
signed-off |
Production-ready | Language lead |
// Find texts needing review
getTranslatedTextsByState
filePath: "Translations/MyApp.es-ES.xlf"
translationStateFilter: "needs-review-translation"
limit: 0
// After review, promote to final
saveTranslatedTexts
filePath: "Translations/MyApp.es-ES.xlf"
translations: [
{ "id": "...", "targetText": "...", "targetState": "final" }
]
Common quality issues:
// Issue 1: Missing placeholder
❌ Source: "Posted %1 of %2"
❌ Translation: "Registrado %2" // missing %1
✅ Translation: "Registrado %1 de %2"
// Issue 2: Character limit exceeded
❌ Source: "Post" (maxLength: 10)
❌ Translation: "Registrar y contabilizar" // 25 chars
✅ Translation: "Registrar" // 9 chars
// Issue 3: Context-dependent meaning
Source: "Post"
Context: Action caption → "Registrar" ✅
Context: Table name → "Correo" ✅ (different meaning!)
Pattern 5: Translation Memory and Glossary
Use existing translations for consistency:
// Get all translated texts as a reference map
getTranslatedTextsMap
filePath: "Translations/MyApp.es-ES.xlf"
limit: 0
// Search for specific terms across translations
getTextsByKeyword
filePath: "Translations/MyApp.es-ES.xlf"
keyword: "Customer|Vendor|Invoice"
isRegex: true
caseSensitive: false
searchInTarget: true
Glossary approach:
- Before translating a batch, retrieve existing translations with
getTranslatedTextsMap - Search for related terms with
getTextsByKeywordto ensure consistent terminology - Standard BC terms should match Microsoft's official base app translations
Pattern 6: Regional Variations
Manage locale-specific translations (e.g., es-ES vs es-MX):
// Step 1: Create base translation (es-ES)
createLanguageXlf
generatedXlfFilePath: "Translations/MyApp.g.xlf"
targetLanguageCode: "es-ES"
matchBaseAppTranslation: true
// Step 2: Create regional variant from base
createLanguageXlf
generatedXlfFilePath: "Translations/MyApp.g.xlf"
targetLanguageCode: "es-MX"
matchBaseAppTranslation: true
// Step 3: Get base translations as reference
getTranslatedTextsMap
filePath: "Translations/MyApp.es-ES.xlf"
limit: 0
// Step 4: Copy base, then adjust regional terms
// "Ordenador" (es-ES) → "Computadora" (es-MX)
// "Factura" stays the same in both
Workflow
Step 1: Setup
- Build the extension to generate the
.g.xlffile:al_build - Create language file for each target locale (Pattern 1)
- If language files already exist, refresh them (Pattern 2)
Step 2: Translate
- Retrieve untranslated texts with
getTextsToTranslate(paginate withlimit/offset) - Check translation memory for consistency (Pattern 5)
- Translate in batches of 20-50 items (Pattern 3)
- Save progress frequently — use
targetState: "translated"
Step 3: Review
- Retrieve texts by state:
getTranslatedTextsByStatewith"translated"filter - Validate:
- All placeholders preserved (
%1,%2, etc.) - Character limits respected
- Context-appropriate translations
- Consistent terminology across the extension
- All placeholders preserved (
- Mark reviewed texts:
targetState: "needs-review-translation"→"final"
Step 4: Finalize
- Verify no untranslated texts remain:
getTextsToTranslatewithlimit: 0 - Promote all
finaltexts tosigned-off - Build the extension to verify XLF integration:
al_build - Test the UI in the target language
Common Language Codes
| Code | Language | Code | Language |
|---|---|---|---|
es-ES |
Spanish (Spain) | fr-FR |
French (France) |
es-MX |
Spanish (Mexico) | fr-CA |
French (Canada) |
de-DE |
German | pt-BR |
Portuguese (Brazil) |
it-IT |
Italian | nl-NL |
Dutch |
da-DK |
Danish | sv-SE |
Swedish |
nb-NO |
Norwegian | fi-FI |
Finnish |
pl-PL |
Polish | cs-CZ |
Czech |
ja-JP |
Japanese | zh-CN |
Chinese (Simplified) |
References
Constraints
- This skill covers XLF translation management, batch translation, and quality review workflows
- Do NOT edit
.g.xlffiles manually — they are compiler-generated - Do NOT remove or reorder placeholders (
%1,%2) in translations - Do NOT exceed
maxLengthcharacter limits defined in AL source - Do NOT translate without checking existing translation memory first (consistency)
- Translation testing in UI →
skill-testing.md| Page captions and tooltips →skill-pages.md