Skip to content

Add opt-in UI localization framework with Hebrew (RTL) translation#636

Open
yosef-chai wants to merge 1 commit into
Raphire:masterfrom
yosef-chai:feature/hebrew-localization
Open

Add opt-in UI localization framework with Hebrew (RTL) translation#636
yosef-chai wants to merge 1 commit into
Raphire:masterfrom
yosef-chai:feature/hebrew-localization

Conversation

@yosef-chai

@yosef-chai yosef-chai commented Jun 17, 2026

Copy link
Copy Markdown

Summary

This PR adds an optional, opt-in UI localization layer so the GUI can be displayed in another language, with Hebrew (עברית) as the first translation including full right-to-left (RTL) layout.

It is completely opt-in. When no language is selected the script behaves exactly as it does today — every localization function short-circuits to a no-op, the layout stays left-to-right and all strings stay in English. There is no behavioural change for existing users.

How to enable

.\Win11Debloat.ps1 -Language he

Or, to make it the default without passing the parameter each time, set the WIN11DEBLOAT_LANG environment variable (e.g. he).

What it adds

  • Scripts/Localization/Localize.ps1 — a single English -> translation dictionary plus a small runtime engine:
    • Get-LocalizedString / Format-Localized — used at dynamic call sites.
    • Invoke-WindowLocalization — walks a loaded WPF window, translates every visible string and sets FlowDirection to RightToLeft.
    • Localize-FeaturesData / Localize-ScriptFeatures — translate the display fields of the parsed Features.json / Apps.json data at runtime.
  • Small calls into those helpers from the existing GUI scripts so static XAML, dynamically-built strings, message boxes, tooltips, menus, pop-ups, the tweaks/apps lists and all dialogs are covered.
  • A matching -Language parameter on both Win11Debloat.ps1 and Scripts/Get.ps1 (kept in sync per the contributing guide), plus a short note in the README.

Design & safety notes

  • Strings read back by program logic (e.g. the hidden TabItem header identifiers App Removal / Tweaks) are intentionally not translated, so control flow is unaffected.
  • The one visible-but-logic-coupled control (the app-removal scope combo) was decoupled to compare on SelectedIndex instead of the displayed text.
  • Config/ and Schemas/ are untouched — no translated text is baked into the data or XAML, which keeps future updates conflict-free.
  • Adding another language only requires a second dictionary keyed on the same English source strings; no other changes are needed.

Testing

  • Headless-loaded all eight XAML windows and ran the localizer against them: RTL is applied, every visible label/button/menu/tooltip/combo is translated, and the logic-coupled tab-header identifiers remain English.
  • Verified that the default mode (no -Language) produces identical English, left-to-right output.
  • All modified PowerShell files pass System.Management.Automation.Language.Parser checks.
  • Note: this is an i18n change rather than a Windows tweak, so the registry-file / Sysprep checklist in CONTRIBUTING.md does not apply. review and testing feedback is very welcome.

Adds an optional localization layer so the GUI can be shown in another
language. It is fully opt-in: the default language stays English and every
localization function is a no-op, so behaviour is unchanged for existing
users.

How to enable:
  .\Win11Debloat.ps1 -Language he
or set the environment variable WIN11DEBLOAT_LANG=he

What it does (only when a language is selected):
- New module Scripts/Localization/Localize.ps1 holds a single
  English -> translation dictionary plus a small runtime engine:
  Get-LocalizedString, Format-Localized, Invoke-WindowLocalization
  (walks the loaded WPF tree, translates every visible string and sets
  FlowDirection to RightToLeft) and Localize-FeaturesData /
  Localize-ScriptFeatures (translate the display fields of the parsed
  Features.json / Apps.json data at runtime).
- Covers the whole GUI: static XAML, dynamically built strings, message
  boxes, tooltips, menus, pop-ups, the tweaks/apps lists and all dialogs.

Design notes:
- Strings that are read back by program logic (e.g. the hidden TabItem
  header identifiers "App Removal"/"Tweaks") are intentionally not
  translated. The visible-but-logic-coupled app-removal scope combo now
  compares on SelectedIndex instead of the displayed text.
- Config/ and Schemas/ are left untouched; existing scripts only gained
  small calls into the localization helpers.
- Adds a matching -Language parameter to Win11Debloat.ps1 and
  Scripts/Get.ps1, and documents it in the README. A new language only
  needs a second dictionary keyed on the same English source strings.
@Raphire

Raphire commented Jun 17, 2026

Copy link
Copy Markdown
Owner

Heya,

Thanks for taking the time to contribute.

I haven't been able to fully dive into this yet, but from a quick glance through I did notice that the current implementation is very much focussed on just the 2 translations, making it very hard to expand this in the future.

I have been personally experimenting with adding this feature as well in a manner that would make it easier to add multiple languages. With the idea that each language gets a specific language file that is dynamically parsed by the script.

You're welcome to continue with this PR and rework it toward that approach. Otherwise I'll pick up where I left off, and you can always add your translations & other changes on top once that's in place.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants