{"id":21221321,"url":"https://github.com/Xcube-Studio/FluentLauncher.Infra.Localization","last_synced_at":"2025-07-10T12:31:50.741Z","repository":{"id":183135658,"uuid":"669659755","full_name":"Xcube-Studio/FluentLauncher.Localization","owner":"Xcube-Studio","description":"Fluent Launcher 的 本地化计划","archived":false,"fork":false,"pushed_at":"2024-11-16T07:41:51.000Z","size":265,"stargazers_count":0,"open_issues_count":1,"forks_count":5,"subscribers_count":0,"default_branch":"main","last_synced_at":"2024-11-16T08:26:41.081Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Xcube-Studio.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-07-23T02:39:02.000Z","updated_at":"2024-11-16T07:41:55.000Z","dependencies_parsed_at":"2023-07-23T04:28:45.000Z","dependency_job_id":"cd9cd6e6-3e50-41d0-aec8-150e2bdf9e54","html_url":"https://github.com/Xcube-Studio/FluentLauncher.Localization","commit_stats":null,"previous_names":["xcube-studio/fluentlauncher.localizationporoject","xcube-studio/fluentlauncher.localization"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Xcube-Studio%2FFluentLauncher.Localization","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Xcube-Studio%2FFluentLauncher.Localization/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Xcube-Studio%2FFluentLauncher.Localization/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Xcube-Studio%2FFluentLauncher.Localization/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Xcube-Studio","download_url":"https://codeload.github.com/Xcube-Studio/FluentLauncher.Localization/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":225638619,"owners_count":17500607,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-20T22:26:40.478Z","updated_at":"2025-07-10T12:31:50.729Z","avatar_url":"https://github.com/Xcube-Studio.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Fluent Launcher Localization Project\n\nEnglish | [简体中文](README_zh.md)\n\nThis repository provides the translation resources and localization toolchain for [Fluent Launcher](https://github.com/Xcube-Studio/Natsurainko.FluentLauncher), which currently supports the following languages:\n\n- English (en-US)\n- Simplified Chinese (zh-Hans)\n- Traditional Chinese (zh-Hant)\n- Russian (ru-RU)\n- Ukrainian (uk-UA)\n\nIf you wish to add more languages, please submit a PR following [these instructions](#adding-a-language). Once the PR is accepted, support for the new language will be added in the next release.\n\n## Translation Resources\n\nAll the strings in Fluent Launcher and their translations for various languages are stored in multiple `.csv` files within the `Views/` directory. To manage the large number of strings in the app efficiently, we will use the relative path to the `Views/` directory and the filename of the `.csv` file to describe the component that owns the strings in the file. During the build process of Fluent Launcher, the localization toolchain will convert these `.csv` files into PRI resources used by the WinUI app.\n\n### `.csv` File Paths\n\nEach `.csv` file in the `Views/` directory typically corresponds to a page in Fluent Launcher. The filename and path should match the corresponding page in [Natsurainko.FluentLauncher/Views](https://github.com/Xcube-Studio/Natsurainko.FluentLauncher/tree/main/Natsurainko.FluentLauncher/Views). Strings in these files may be used in the associated `View.xaml`, `View.xaml.cs`, or `ViewModel.cs`. For some components that only have a `ViewModel.cs`, the strings used are also stored in a separate `.csv` file.\n\nOther strings used in backend code are stored in specific `.csv` files, such as `Views/Exceptions.csv` and `Views/Converters.csv`.\n\n### `.csv` Content\n\nThe `.csv` files storing translation resources must use UTF8-BOM encoding. Each row represents a string and its translations for all supported languages. Every `.csv` file must include the following header:\n\n| Id | Property | en-US | zh-Hans | zh-Hant | ru-RU | uk-UA |\n| -- | -------- | ----- | ------- | ------- | ----- | ----- |\n\n\n- `Id` and `Property` describe the string's path in the PRI resource system.\n\n  - If the string is only used in backend code, the `Id` field must start with an `_` prefix, and the `Property` field must be empty.\n\n- Each subsequent column represents a language supported by Fluent Launcher, identified by its language code.\n\n### Adding a Language\n\nClone this repository:\n\n```bash\ngit clone https://github.com/Xcube-Studio/FluentLauncher.Localization.git\n```\n\nAdd a column to the rightmost side of each `.csv` file. Enter the new language code in the header and provide translations for each row. **Do NOT** modify the content of the `Id` and `Property` columns. The headers of all `.csv` files must remain consistent.\n\nYou may submit a PR after completing partial translations. The Fluent Launcher build system allows missing translations. Untranslated strings will fall back to the content of the `en-US` column.\n\n## WinUI 3 Localization Toolchain\n\n### `.resw` Generator\n\n`FluentLauncher.Infra.Localizer` is a C# command-line tool for converting all `.csv` files in the `Views/` directory into a set of `Resources.lang-\u003clang\u003e.resw` files that can be used by WinUI apps, where `\u003clang\u003e` is the language code of a supported language. You can also specify a default language using the `--default-language` option. Translations of the default language will be stored in the `Resources.resw` file, which will provide the default translations of strings in the app.\n\nEach item in a `.csv` file represetns a PRI string resource. The PRI resource ID is formatted using the following pattern:  \n`\u003cpath_relative_to_Views_directory\u003e_\u003ccsv_file_name\u003e_\u003cresourceId\u003e/\u003cresourcePropertyId\u003e`.\n\nExample: An entry in `Views/Settings/AboutPage.csv`:\n\n| Id | Property | en-US             | zh-Hans  | zh-Hant  | ru-RU  | uk-UA      |\n| -- | -------- | ----------------- | -------- | -------- | ------ | ---------- |\n| T1 | Text     | Other information | 其它信息 | 其它信息 | Другая | информация |\n\nWill output to the `.resw` file as:\n\n```xml\n\u003cdata name=\"Settings_AboutPage_T1.Text\" xml:space=\"preserve\"\u003e\n  \u003cvalue\u003eOther information\u003c/value\u003e\n\u003c/data\u003e\n```\n\nHere, `\u003cvalue\u003e` contains the translation for the corresponding language.\n\nUsage of the command-line program:\n\n````\nDescription:\n  Convert .csv files to .resw files for UWP/WinUI localization\n\nUsage:\n  FluentLauncher.Infra.Localizer [options]\n\nOptions:\n  --src \u003csrc\u003e (REQUIRED)                 The source folder containing the .csv files\n  --out \u003cout\u003e (REQUIRED)                 The output folder for .resw files\n  --languages \u003clanguages\u003e (REQUIRED)     All languages for translation\n  --default-language \u003cdefault-language\u003e  Default language of the app []\n  --version                              Show version information\n  -?, -h, --help                         Show help and usage information\n````\n\n### `.resw` Resource Accessor Source Generator\n\nTo simplify the access of PRI string resources in a WinUI project using C#, a Roslyn source generator is provided to generate the code that reads strings in the `.resw` files. The `FluentLauncher.Infra.LocalizedStrings` project provides the `GeneratedLocalizedStringsAttribute` for marking a `partial` static class, in which the string accessors will be generated as properties. Since `.resw` files are not C# source files, they need to be included as `AdditionalFiles` in the `.csproj` file of the WinUI project to allow the source generator to read them.\n\nThese tools can be used in any C# WinUI project by referencing the following projects:\n\n```xml\n\u003cItemGroup\u003e\n    \u003cProjectReference Include=\"..\\FluentLauncher.Localization\\FluentLauncher.Infra.LocalizedStrings.SourceGenerators\\FluentLauncher.Infra.LocalizedStrings.SourceGenerators.csproj\" OutputItemType=\"Analyzer\" ReferenceOutputAssembly=\"false\" /\u003e\n    \u003cProjectReference Include=\"..\\FluentLauncher.Localization\\FluentLauncher.Infra.LocalizedStrings\\FluentLauncher.Infra.LocalizedStrings.csproj\" /\u003e\n\u003c/ItemGroup\u003e\n```\n\nExample: If the project contains two `.resw` files:\n\n- `Resources.resw` with two resources:\n\n  - `Button1.Content`\n  - `Sample_Message`\n\n- `TextBlocks.resw` with one resource:\n\n  - `DemoTextBlock.Text`\n\n\nThe source generator will produce the following code:\n\n```csharp\n[GeneratedLocalizedStrings]\npartial static class LocalizedStrings\n{\n    private static ResourceManager s_resourceManager;\n    private static ResourceMap s_resourceMap;\n\n    static LocalizedStrings()\n    {\n        s_resourceManager = new();\n        s_resourceMap = s_resourceManager.MainResourceMap;\n    }\n\n    // Default resource map (Resources.resw)\n    public static string Button1_Content =\u003e s_resourceMap.GetValue(\"Resources/Button1/Content\").ValueAsString;\n    public static string Sample_Message =\u003e s_resourceMap.GetValue(\"Resources/Sample_Message\").ValueAsString;\n\n    // Other resw files\n    public static class TextBlocks\n    {\n        public static string DemoTextBlock_Text =\u003e s_resourceMap.GetValue(\"TextBlocks/DemoTextBlock/Text\").ValueAsString;\n    }\n\n    public static void UpdateLanguage()\n    {\n        s_resourceManager = new();\n        s_resourceMap = s_resourceManager.MainResourceMap;\n    }\n}\n```\n\nNote: `Resources.resw` provides the default resource group in WinUI, and the source generator will generates accessors as members of the class marked by `GeneratedLocalizedStrings`. For other `.resw` files, the source generator creates a nested class named after the resource group and generates accessors within it.\n\nIf the project contains multiple `.resw` files with the same name but different qualifiers, the source generator will prioritize the file without a qualifier. If all versions have qualifiers, the alphabetically first file name will be used for code generation.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FXcube-Studio%2FFluentLauncher.Infra.Localization","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FXcube-Studio%2FFluentLauncher.Infra.Localization","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FXcube-Studio%2FFluentLauncher.Infra.Localization/lists"}