Skip to content

fix(i18n): register Persian in AvailableLanguages - #798

Open
pasharm wants to merge 1 commit into
STranslate:mainfrom
pasharm:fix/register-persian-language
Open

pasharm wants to merge 1 commit into
STranslate:mainfrom
pasharm:fix/register-persian-language

Conversation

@pasharm

@pasharm pasharm commented Sep 9, 2026 •

Copy link
Copy Markdown
Contributor

English

src/STranslate/Languages/fa.xaml has been in the tree since #765 and is complete — 792 keys, plus fa.xaml + fa.json for all 21 plugins, with the same key sets as their en counterparts. But fa was never added to AvailableLanguages.

Since that class is the only source of the language list, and the loader builds the file name as $"{LanguageCode}.xaml", Persian never appears in the settings dropdown and all 43 translation files are unreachable at runtime.

This adds the three registrations the contribution checklist asks for:

  • public static I18nPair Persian = new("fa", "فارسی");
  • the Persian, entry in GetAvailableLanguages();
  • "fa" => "سیستم" in GetSystemTranslation — the branch the doc itself calls the easiest to miss;

plus the missing row in the language table of src/docs/i18n-internationalization.md.

RTL

Registering the language does not change any layout. FlowDirection already goes through TextAndLanguageToFlowDirectionConverter, which keys off the language of the text (input, result, history) rather than the UI language, so nothing else changes here. The new doc row states that the UI layout is not mirrored; full RTL mirroring would be separate work.

Persian is appended after Ukrainian, i.e. the list keeps registration order — move it wherever you prefer it to appear in the dropdown.

One thing worth knowing before this ships

fa is the first reachable locale whose default calendar is not Gregorian. ChangeCultureInfo resolves it to fa-IR, whose DateTimeFormat.Calendar is PersianCalendar, so two existing spots render Solar Hijri dates once the UI language is Persian (2026-09-09 becomes 1405-06-18):

  • Core/StorageBase.cs — DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss-fffffff", CultureInfo.CurrentUICulture), the settings backup file name;
  • Helpers/HistoryCsvHelper.cs — item.Time.ToString("yyyy-MM-dd HH:mm:ss.fffffff") without a culture, the history CSV export.

Neither string is parsed back anywhere, so nothing breaks. It is pre-existing behaviour, not something this PR changes, and it is left alone here — but this PR is what makes that code path reachable, so it seemed better to say it up front than to have it turn up after a release.

Verification

  • dotnet build src/STranslate.slnx -c Debug — 0 errors;
  • dotnet test src/STranslate.slnx — 296/296 passing;
  • fa.xaml has 792 keys, the same as en.xaml; all 21 plugins have fa.xaml and fa.json with the same key sets as en;
  • every language dictionary in the tree loads through XamlReader.Load without errors.

Noticed while working on #782 and mentioned there as a follow-up.


中文

src/STranslate/Languages/fa.xaml 自 #765 起就在仓库里,而且是完整的——792 个 key,另有 21 个插件各自的 fa.xaml 与 fa.json,key 集合与对应的 en 文件一致。但 fa 一直没有注册进 AvailableLanguages。

该类是支持语言列表的唯一来源,加载器又按 $"{LanguageCode}.xaml" 拼文件名,因此波斯语从未出现在设置页的语言下拉中,43 个翻译文件在运行时根本无法被使用。

本 PR 按贡献 Checklist 补齐三处注册:

  • public static I18nPair Persian = new("fa", "فارسی");
  • GetAvailableLanguages() 中的 Persian,;
  • GetSystemTranslation 中的 "fa" => "سیستم"——文档自己指出最容易漏的一处;

以及 src/docs/i18n-internationalization.md 语言表中缺失的一行。

RTL

注册语言本身不改变任何布局。FlowDirection 已经通过 TextAndLanguageToFlowDirectionConverter 计算,它依据文本语言(输入框、译文、历史记录)而非界面语言,因此这里不涉及其他改动。新增的文档行也写明了:界面布局未做镜像处理;完整的 RTL 镜像属于另外的工作。

Persian 追加在 Ukrainian 之后,即列表保持注册顺序;若希望在下拉中换个位置,请随意调整。

上线前值得一提的一点

fa 是第一个默认日历不是公历的可用语言。ChangeCultureInfo 会解析为 fa-IR,其 DateTimeFormat.Calendar 为 PersianCalendar,因此界面语言切到波斯语后,有两处会输出伊朗历日期(2026-09-09 显示为 1405-06-18):

  • Core/StorageBase.cs —— DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss-fffffff", CultureInfo.CurrentUICulture),设置备份的文件名;
  • Helpers/HistoryCsvHelper.cs —— 未指定 culture 的 item.Time.ToString("yyyy-MM-dd HH:mm:ss.fffffff"),历史记录 CSV 导出。

这两处都没有反向解析,因此不会损坏数据。这属于既有行为,本 PR 并未改动,这里也不去动它——但正是本 PR 让这条代码路径变得可达,所以觉得提前说明比发布后才发现更好。

验证

  • dotnet build src/STranslate.slnx -c Debug —— 0 错误;
  • dotnet test src/STranslate.slnx —— 296/296 通过;
  • fa.xaml 有 792 个 key,与 en.xaml 相同;21 个插件均有 fa.xaml 与 fa.json,key 集合与 en 一致;
  • 树内所有语言词典均通过 XamlReader.Load 加载,无报错。

此问题是在做 #782 时发现并作为 follow-up 提到的。

`src/STranslate/Languages/fa.xaml` has been in the tree since STranslate#765 and is
complete — 792 keys, plus `fa.xaml` + `fa.json` for all 21 plugins — but `fa` was
never added to `AvailableLanguages`. Since that class is the only place the
language list comes from, Persian never appears in the settings dropdown and the
files are unreachable at runtime.

This adds the three registrations the contribution checklist asks for:

- `I18nPair Persian = new("fa", "فارسی")`;
- the entry in `GetAvailableLanguages()`;
- `"fa" => "سیستم"` in `GetSystemTranslation`, the branch the doc calls the
  easiest to miss;

plus the missing row in the language table of `src/docs/i18n-internationalization.md`.

Persian is written right to left, and the doc row says so: the UI layout is not
mirrored. Translated content already goes through
`TextAndLanguageToFlowDirectionConverter`, which keys off the language of the
text rather than the UI language, so nothing else changes here.

`Persian` is appended after `Ukrainian`, i.e. the list keeps registration order;
move it wherever you prefer it to appear in the dropdown.

One thing worth knowing before this ships: `fa` is the first reachable locale
whose default calendar is not Gregorian. `ChangeCultureInfo` resolves it to
`fa-IR`, whose `DateTimeFormat.Calendar` is `PersianCalendar`, so
`DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss-fffffff", CultureInfo.CurrentUICulture)`
in `Core/StorageBase.cs` (settings backup file name) and the culture-less
`item.Time.ToString("yyyy-MM-dd HH:mm:ss.fffffff")` in `Helpers/HistoryCsvHelper.cs`
(history CSV export) render Solar Hijri dates — 2026-09-09 comes out as
1405-06-18. Nothing is parsed back, so no data breaks; it is pre-existing
behaviour rather than something this PR changes, and left alone here.

Verified: `dotnet build -c Debug` 0 errors, `dotnet test` 296/296.
@pasharm
pasharm force-pushed the fix/register-persian-language branch from 4a3be9e to 94895a9 Compare September 9, 2026 15:39
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.

1 participant