UNPKG

al-development-collection

Version:

AI Native AL Development toolkit for Microsoft Dynamics 365 Business Central with GitHub Copilot integration

387 lines (320 loc) 10.2 kB
--- agent: agent model: Claude Sonnet 4.5 description: 'Translate AL extensions using XLF translation files for Business Central multilingual support.' tools: ['edit', 'runNotebooks', 'search', 'new', 'runCommands', 'runTasks', 'runSubagent', 'usages', 'vscodeAPI', 'problems', 'changes', 'testFailure', 'openSimpleBrowser', 'fetch', 'githubRepo', 'nab-al.al-toolbox/getTextsToTranslate', 'nab-al.al-toolbox/saveTranslatedTexts', 'nab-al.al-toolbox/getTranslatedTextsMap', 'nab-al.al-toolbox/getTranslatedTextsByState', 'nab-al.al-toolbox/getTextsByKeyword', 'nab-al.al-toolbox/refreshXlf', 'nab-al.al-toolbox/createLanguageXlf', 'extensions', 'todos', 'runTests'] --- # AL Translation Workflow Your goal is to translate AL extension texts for `${input:TargetLanguage}`. ## Translation Workflow ### 1. Identify Translation Files Locate XLF files in the Translations folder: - `.g.xlf` - Generated translation file (source) - Language-specific files (e.g., `MyApp.es-ES.xlf`) ### 2. Create or Refresh Language File #### Creating a New Language File ``` createLanguageXlf ``` Parameters: - `generatedXlfFilePath`: Path to the .g.xlf file - `targetLanguageCode`: Language code (e.g., 'es-ES', 'fr-FR', 'de-DE') - `matchBaseAppTranslation`: true (to pre-populate with Microsoft's base translations) #### Refreshing an Existing Language File ``` refreshXlf ``` Parameters: - `generatedXlfFilePath`: Path to the .g.xlf file - `filePath`: Path to the language-specific XLF file to refresh ### 3. Retrieve Texts to Translate #### Get Untranslated Texts ``` getTextsToTranslate ``` Parameters: - `filePath`: Path to the XLF file - `limit`: Number of texts to retrieve (0 for all) - `offset`: Starting position (for pagination) Returns: - `id`: Unique identifier - `source`: Text to translate - `sourceLanguage`: Source language code - `type`: Context (e.g., 'Table Customer - Field Name - Property Caption') - `maxLength`: Character limit (if applicable) - `comments`: Contextual information about placeholders (%1, %2, etc.) #### Search Specific Texts ``` getTextsByKeyword ``` Parameters: - `filePath`: Path to the XLF file - `keyword`: Search term or regex pattern - `limit`: Number of results - `isRegex`: true/false - `caseSensitive`: true/false - `searchInTarget`: true (search in translations) / false (search in source) ### 4. Translation Strategy #### Using Translation Memory ``` getTranslatedTextsMap ``` Parameters: - `filePath`: Path to a reference XLF file - `limit`: Number of translations (0 for all) Use this to: - Maintain consistency with previous translations - Reference similar language translations (e.g., es-ES vs es-MX) - Build a translation glossary #### Review Translations by State ``` getTranslatedTextsByState ``` Parameters: - `filePath`: Path to the XLF file - `translationStateFilter`: 'needs-review', 'translated', 'final', 'signed-off' - `limit`: Number of texts - `sourceText`: Optional filter for specific source text ### 5. Translate and Save #### Translation Best Practices 1. **Preserve Placeholders** - Source: `"Processing %1 records"` - Translation: `"Procesando %1 registros"` - Keep %1, %2, %3 in the same order 2. **Respect Character Limits** - Check `maxLength` property - Adjust translation to fit constraints - Use abbreviations if necessary 3. **Maintain Context** - Review `type` field for object context - Field captions may differ from action captions - Consider UI space constraints 4. **Use Consistent Terminology** - Reference `getTranslatedTextsMap` for existing translations - Maintain glossary of technical terms - Follow Microsoft's base app translations #### Save Translations ``` saveTranslatedTexts ``` Parameters: - `filePath`: Path to the XLF file - `translations`: Array of translation objects Translation object structure: ```json { "id": "unique-identifier", "targetText": "Translated text", "targetState": "translated" // or "needs-review-translation", "final", "signed-off" } ``` **Batch Translation Example:** ```json { "filePath": "c:/path/to/MyApp.es-ES.xlf", "translations": [ { "id": "Table_Customer_Field_Name_Caption", "targetText": "Nombre", "targetState": "translated" }, { "id": "Page_CustomerCard_Action_NewSalesOrder_Caption", "targetText": "Nuevo pedido de venta", "targetState": "translated" } ] } ``` ### 6. Quality Assurance #### Translation Review Workflow 1. **First Pass** - Initial translation - State: `translated` - Review context and placeholders 2. **Review Pass** - Quality check - State: `needs-review-translation` - Verify terminology consistency - Check character limits - Test in UI if possible 3. **Final Pass** - Approval - State: `final` - Native speaker review - UI/UX validation 4. **Sign-off** - Production ready - State: `signed-off` - Ready for deployment #### Common Translation Issues **Issue 1: Placeholder Mismatch** ``` ❌ 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" // Too long ✅ Translation: "Registrar" ``` **Issue 3: Context Ignored** ``` Source: "Post" Context 1: "Page SalesOrder - Action Post - Caption" Translation: "Registrar" ✅ Context 2: "Table Post - Field Name - Caption" Translation: "Poste" ✅ // Different meaning! ``` ### 7. Translation Workflow Example #### Scenario: Translate Customer Module to Spanish **Step 1: Create language file** ``` createLanguageXlf( generatedXlfFilePath: "c:/MyApp/Translations/MyApp.g.xlf", targetLanguageCode: "es-ES", matchBaseAppTranslation: true ) ``` **Step 2: Get untranslated texts** ``` getTextsToTranslate( filePath: "c:/MyApp/Translations/MyApp.es-ES.xlf", limit: 50, offset: 0 ) ``` **Step 3: Check existing translations** ``` getTranslatedTextsMap( filePath: "c:/ReferenceApp/Translations/Reference.es-ES.xlf", limit: 0 ) ``` **Step 4: Translate batch** ``` saveTranslatedTexts( filePath: "c:/MyApp/Translations/MyApp.es-ES.xlf", translations: [ { id: "...", targetText: "...", targetState: "translated" }, { id: "...", targetText: "...", targetState: "translated" } ] ) ``` **Step 5: Review translations** ``` getTranslatedTextsByState( filePath: "c:/MyApp/Translations/MyApp.es-ES.xlf", translationStateFilter: "translated", limit: 0 ) ``` **Step 6: Mark for review** ``` saveTranslatedTexts( filePath: "c:/MyApp/Translations/MyApp.es-ES.xlf", translations: [ { id: "...", targetText: "...", targetState: "needs-review-translation" } ] ) ``` **Step 7: Final approval** ``` saveTranslatedTexts( filePath: "c:/MyApp/Translations/MyApp.es-ES.xlf", translations: [ { id: "...", targetText: "...", targetState: "final" } ] ) ``` ## Language Codes Reference ### Common Language Codes - `es-ES` - Spanish (Spain) - `es-MX` - Spanish (Mexico) - `fr-FR` - French (France) - `fr-CA` - French (Canada) - `de-DE` - German (Germany) - `de-AT` - German (Austria) - `it-IT` - Italian - `pt-PT` - Portuguese (Portugal) - `pt-BR` - Portuguese (Brazil) - `nl-NL` - Dutch (Netherlands) - `nl-BE` - Dutch (Belgium) - `da-DK` - Danish - `sv-SE` - Swedish - `nb-NO` - Norwegian (Bokmål) - `fi-FI` - Finnish - `pl-PL` - Polish - `cs-CZ` - Czech - `ru-RU` - Russian - `zh-CN` - Chinese (Simplified) - `zh-TW` - Chinese (Traditional) - `ja-JP` - Japanese - `ko-KR` - Korean ## Advanced Scenarios ### Scenario 1: Regional Variations When translating for multiple regions (e.g., es-ES vs es-MX): 1. Create base translation (es-ES) 2. Use `getTranslatedTextsMap` to copy to regional variant 3. Adjust regional-specific terms 4. Save with appropriate language code ### Scenario 2: Translation Glossary Build consistent terminology: ``` getTextsByKeyword( filePath: "MyApp.es-ES.xlf", keyword: "Customer|Sales|Invoice|Post", isRegex: true, searchInTarget: true ) ``` ### Scenario 3: Incremental Updates After code changes: 1. Refresh XLF: `refreshXlf` 2. Get new texts: `getTextsToTranslate` 3. Preserve existing translations (auto-maintained) 4. Translate only new items ### Scenario 4: Quality Review Review translations that need attention: ``` getTranslatedTextsByState( filePath: "MyApp.es-ES.xlf", translationStateFilter: "needs-review", limit: 0 ) ``` ## Best Practices ### 1. Translation Memory - Maintain a reference translation file - Use `getTranslatedTextsMap` for consistency - Build glossaries for technical terms ### 2. Batch Operations - Translate in batches (20-50 items) - Use consistent terminology within batch - Save progress frequently ### 3. Context Awareness - Always review the `type` field - Consider UI placement and space - Test translations in actual pages when possible ### 4. Quality Control - Use translation states effectively - Implement review workflows - Native speaker validation ### 5. Automation - Use `matchBaseAppTranslation` for base app terms - Reference similar language variants - Maintain translation glossaries ## Workflow Summary 1. **Setup**: Create or refresh language file 2. **Retrieve**: Get texts to translate with context 3. **Research**: Check translation memory and glossaries 4. **Translate**: Translate batch respecting context and limits 5. **Save**: Save translations with appropriate state 6. **Review**: Quality check and state progression 7. **Deploy**: Final approval and sign-off ## Success Criteria - ✅ All required texts translated - ✅ Placeholders preserved correctly - ✅ Character limits respected - ✅ Terminology consistent - ✅ Context-appropriate translations - ✅ Quality review completed - ✅ Translations marked with correct state