feat: Add dynamic multi-language support for the GUI#643
Conversation
- Introduced LoadLanguage.ps1 to detect system UI language and load corresponding language files. - Implemented ConvertTo-LocalizedXaml function to replace %LANG:Key% markers in XAML with localized strings. - Updated various GUI scripts to utilize localization functions for displaying messages and labels. - Replaced hardcoded strings with localized versions in MainWindow-AppSelection.ps1, MainWindow-Deployment.ps1, Show-MainWindow.ps1, and Show-MessageBox.ps1. - Added language file loading in Win11Debloat.ps1 and set default language to system UI language with a fallback to en-US.
- Updated es-ES.json with extensive translations for tweaks, features, and tooltips. - Enhanced LoadLanguage.ps1 to support new translation functions for categories, features, and tooltips. - Modified MainWindow-AppSelection.ps1 to utilize translated recommendations for app removal. - Updated MainWindow-TweaksBuilder.ps1 to display translated category names, feature labels, and tooltips in the UI.
📝 WalkthroughWalkthroughAdds end-to-end localization support to Win11Debloat. A new ChangesLocalization Pipeline
Sequence Diagram(s)sequenceDiagram
participant Win11Debloat.ps1
participant LoadLanguage.ps1
participant LanguagesPath
participant Show-MainWindow.ps1
participant GUI Scripts
Win11Debloat.ps1->>LoadLanguage.ps1: LoadLanguage (system culture or parameter)
LoadLanguage.ps1->>LanguagesPath: exact match → prefix glob → en-US fallback
LanguagesPath-->>LoadLanguage.ps1: JSON file bytes
LoadLanguage.ps1-->>Win11Debloat.ps1: $script:Lang object
Win11Debloat.ps1->>Show-MainWindow.ps1: invoke Show-MainWindow
Show-MainWindow.ps1->>LoadLanguage.ps1: ConvertTo-LocalizedXaml(rawXaml, $script:Lang)
LoadLanguage.ps1-->>Show-MainWindow.ps1: XAML with %LANG:Key% replaced
Show-MainWindow.ps1->>Show-MainWindow.ps1: parse and display localized XAML
GUI Scripts->>LoadLanguage.ps1: L / Get-LangFeature / Get-LangCategory / ...
LoadLanguage.ps1-->>GUI Scripts: translated string or fallback
Estimated code review effort🎯 4 (Complex) | ⏱️ ~60 minutes 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. Comment |
There was a problem hiding this comment.
🧹 Nitpick comments (1)
Scripts/FileIO/LoadLanguage.ps1 (1)
58-58: ⚡ Quick winConsider adding nested object keys to the skip list for defensive coding.
The
skipKeyslist currently excludes only metadata keys, but the JSON schema also contains nested objects (FeaturesToolTips,FeaturesCategories,FeaturesLabels,FeaturesGroups,GroupsToolTipsper PR objectives and context snippets). If someone later mistakenly adds a placeholder like%LANG:FeaturesToolTips%to the XAML, line 63 would stringify the object as"System.Management.Automation.PSCustomObject"and substitute that garbage into the markup.While no current XAML placeholder uses these keys, extending the skip list prevents future bugs:
-$skipKeys = @('Version', 'LanguageName', 'NativeName', 'LanguageCode') +$skipKeys = @('Version', 'LanguageName', 'NativeName', 'LanguageCode', 'FeaturesToolTips', 'FeaturesCategories', 'FeaturesLabels', 'FeaturesGroups', 'GroupsToolTips')Alternatively, guard by type:
if ($prop.Value -is [PSCustomObject] -or $prop.Value -is [Array]) { continue }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@Scripts/FileIO/LoadLanguage.ps1` at line 58, The skipKeys array needs to be extended to include nested object keys (FeaturesToolTips, FeaturesCategories, FeaturesLabels, FeaturesGroups, GroupsToolTips) to prevent them from being stringified and inserted into XAML if someone accidentally adds a placeholder for them. Add these nested object keys to the skipKeys list alongside the existing metadata keys like Version and LanguageName. Alternatively, add a type guard in the property iteration logic around line 63 to check if the property value is a PSCustomObject or Array type and skip it, which provides defensive coverage without hardcoding specific key names.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Nitpick comments:
In `@Scripts/FileIO/LoadLanguage.ps1`:
- Line 58: The skipKeys array needs to be extended to include nested object keys
(FeaturesToolTips, FeaturesCategories, FeaturesLabels, FeaturesGroups,
GroupsToolTips) to prevent them from being stringified and inserted into XAML if
someone accidentally adds a placeholder for them. Add these nested object keys
to the skipKeys list alongside the existing metadata keys like Version and
LanguageName. Alternatively, add a type guard in the property iteration logic
around line 63 to check if the property value is a PSCustomObject or Array type
and skip it, which provides defensive coverage without hardcoding specific key
names.
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro Plus
Run ID: 9710bc0e-d713-48e7-b8b6-e3f8ddaa3d41
📒 Files selected for processing (10)
Config/Languages/en-US.jsonConfig/Languages/es-ES.jsonSchemas/MainWindow.xamlScripts/FileIO/LoadLanguage.ps1Scripts/GUI/MainWindow-AppSelection.ps1Scripts/GUI/MainWindow-Deployment.ps1Scripts/GUI/MainWindow-TweaksBuilder.ps1Scripts/GUI/Show-MainWindow.ps1Scripts/GUI/Show-MessageBox.ps1Win11Debloat.ps1
Summary
This PR adds a dynamic localization system to the Win11Debloat GUI, allowing the interface to display in the user's system language automatically.
Changes
Scripts/FileIO/LoadLanguage.ps1— new language loader: detects system UI culture, loads the matching JSON file fromConfig/Languages/, falls back toen-US. Provides helper functions:L,Get-LangCategory,Get-LangFeature,Get-LangGroupLabel,Get-LangGroupValue,Get-LangFeatureTooltip,Get-LangGroupTooltipConfig/Languages/en-US.json— full English strings for all UI labels, tooltips, categories, messages and feature descriptionsConfig/Languages/es-ES.json— complete Spanish (Castilian) translationSchemas/MainWindow.xaml— all hardcoded strings replaced with%LANG:key%markersScripts/GUI/— all GUI scripts updated to useL 'key'calls and lang helper functions for dynamically-built controls (tweaks, app list, tooltips)Win11Debloat.ps1— loads language on startup via$script:Lang = LoadLanguageHow it works
On startup, the script reads
[System.Globalization.CultureInfo]::CurrentUICulture. It tries an exact match (es-ES.json), then a prefix match (es-*.json), then falls back toen-US.json. New languages can be added by dropping a JSON file inConfig/Languages/.Adding a new language
Create
Config/Languages/<culture-code>.jsonfollowing the structure ofen-US.json. The loader will pick it up automatically.Multi-Language Localization System Implementation
This PR introduces a comprehensive dynamic localization framework to the Win11Debloat GUI, enabling the interface to automatically display in the user's system language with a fallback to English.
Core Infrastructure
Scripts/FileIO/LoadLanguage.ps1— New module providing language detection and localization helpers:LoadLanguagefunction: Detects the system UI culture (e.g.,es-ES,en-US) and loads the corresponding JSON language file fromConfig/Languages/. Uses an "exact match → prefix glob →en-USfallback" strategyConvertTo-LocalizedXamlfunction: Substitutes%LANG:Key%markers in XAML with translated values, XML-escaping results for safe XAML attribute usageL(generic key lookup),Get-LangCategory,Get-LangFeature,Get-LangGroupLabel,Get-LangGroupValue,Get-LangFeatureTooltip,Get-LangGroupTooltipLanguage Resources
Config/Languages/en-US.jsonandConfig/Languages/es-ES.json— Complete localization files (~371 lines each) containing:UI Integration
Schemas/MainWindow.xaml— Updated to replace 79 hardcoded English strings with%LANG:key%markers across:GUI Scripts — Modified to use localization functions:
MainWindow-AppSelection.ps1: App status and scope descriptions now use localized stringsMainWindow-Deployment.ps1: Overview and deployment messages use localized resourcesMainWindow-TweaksBuilder.ps1: Category headers, feature labels, group options, and tooltips are localizedShow-MainWindow.ps1: XAML is processed throughConvertTo-LocalizedXamlon load; error messages and UI text use localized resourcesShow-MessageBox.ps1: Button labels (OK, Cancel, Yes, No) use localized resourcesWin11Debloat.ps1— Loads the language module and initializes the system language on startup:$script:LanguagesPathpointing toConfig/LanguagesScripts/FileIO/LoadLanguage.ps1$script:LangviaLoadLanguagewith automatic system language detection anden-USfallbackLanguage Extension
Adding support for additional languages requires creating a new JSON file in
Config/Languages/<culture-code>.jsonfollowing the structure of theen-US.jsontemplate. The loader automatically detects and uses the file based on the system UI culture.