|
| 1 | +The Localization Toolkit helps Flow Launcher C# plugin developers make the localization process easier. |
| 2 | + |
| 3 | +## Getting Started |
| 4 | + |
| 5 | +For C# plugins, install and reference [Flow.Launcher.Localization](www.nuget.org/packages/Flow.Launcher.Localization) via NuGet. |
| 6 | + |
| 7 | +## Build Properties |
| 8 | + |
| 9 | +These are properties you can configure in your `.csproj` file to customize the localization process. You can set them in the `<PropertyGroup>` section. For example, to set the `FLLUseDependencyInjection` property to `true`, add the following lines: |
| 10 | + |
| 11 | +```xml |
| 12 | +<PropertyGroup> |
| 13 | + <FLLUseDependencyInjection>true</FLLUseDependencyInjection> |
| 14 | +</PropertyGroup> |
| 15 | +``` |
| 16 | + |
| 17 | +### `FLLUseDependencyInjection` |
| 18 | + |
| 19 | +This flag specifies whether to use dependency injection to obtain an `IPublicAPI` instance. The default is `false`. |
| 20 | +- If set to `false`, the Main class (which must implement **[IPlugin](/API-Reference/Flow.Launcher.Plugin/IPlugin.md)** or **[IAsyncPlugin](/API-Reference/Flow.Launcher.Plugin/IAsyncPlugin.md)**) |
| 21 | + must have a [PluginInitContext](/API-Reference/Flow.Launcher.Plugin/PluginInitContext.md) property that is at least `internal static`. |
| 22 | +- If set to `true`, you can access the `IPublicAPI` instance via `PublicApi.Instance` using dependency injection, and the Main class does not need to include a [PluginInitContext](/API-Reference/Flow.Launcher.Plugin/PluginInitContext.md) property. |
| 23 | + (Note: This approach is not recommended for plugin projects at the moment since it limits compatibility to Flow Launcher 1.20.0 or later.) |
| 24 | + |
| 25 | +## Usage |
| 26 | + |
| 27 | +### Main Class |
| 28 | + |
| 29 | +The Main class must implement [IPluginI18n](/API-Reference/Flow.Launcher.Plugin/IPluginI18n.md). |
| 30 | + |
| 31 | +If `FLLUseDependencyInjection` is `false`, include a [PluginInitContext](/API-Reference/Flow.Launcher.Plugin/PluginInitContext.md) property, for example: |
| 32 | + |
| 33 | +```csharp |
| 34 | + // Must implement IPluginI18n |
| 35 | +public class Main : IPlugin, IPluginI18n |
| 36 | +{ |
| 37 | + // Must be at least internal static |
| 38 | + internal static PluginInitContext Context { get; private set; } = null!; |
| 39 | +} |
| 40 | +``` |
| 41 | + |
| 42 | +### Localized Strings |
| 43 | + |
| 44 | +You can simplify your code by replacing calls like: |
| 45 | +```csharp |
| 46 | +Context.API.GetTranslation("flowlauncher_plugin_localization_demo_plugin_name") |
| 47 | +``` |
| 48 | +with: |
| 49 | +```csharp |
| 50 | +Localize.flowlauncher_plugin_localization_demo_plugin_name() |
| 51 | +``` |
| 52 | + |
| 53 | +If your localization string uses variables, it becomes even simpler! From this: |
| 54 | +```csharp |
| 55 | +string.Format(Context.API.GetTranslation("flowlauncher_plugin_localization_demo_value_with_keys"), firstName, lastName); |
| 56 | +``` |
| 57 | +To this: |
| 58 | +```csharp |
| 59 | +Localize.flowlauncher_plugin_localization_demo_value_with_keys(firstName, lastName); |
| 60 | +``` |
| 61 | + |
| 62 | +### Localized Enums |
| 63 | + |
| 64 | +For enum types (e.g., `DemoEnum`) that need localization in UI controls such as combo boxes, use the `EnumLocalize` attribute to enable localization. For each enum field: |
| 65 | +- Use `EnumLocalizeKey` to provide a custom localization key. |
| 66 | +- Use `EnumLocalizeValue` to provide a constant localization string. |
| 67 | + |
| 68 | +Example: |
| 69 | + |
| 70 | +```csharp |
| 71 | +[EnumLocalize] // Enable localization support |
| 72 | +public enum DemoEnum |
| 73 | +{ |
| 74 | + // Specific localization key |
| 75 | + [EnumLocalizeKey("localize_key_1")] |
| 76 | + Value1, |
| 77 | + |
| 78 | + // Specific localization value |
| 79 | + [EnumLocalizeValue("This is my enum value localization")] |
| 80 | + Value2, |
| 81 | + |
| 82 | + // Key takes precedence if both are present |
| 83 | + [EnumLocalizeKey("localize_key_3")] |
| 84 | + [EnumLocalizeValue("Localization Value")] |
| 85 | + Value3, |
| 86 | + |
| 87 | + // Using the Localize class. This way, you can't misspell localization keys, and if you rename |
| 88 | + // them in your .xaml file, you won't forget to rename them here as well because the build will fail. |
| 89 | + [EnumLocalizeKey(nameof(Localize.flowlauncher_plugin_localization_demo_plugin_description))] |
| 90 | + Value4, |
| 91 | +} |
| 92 | +``` |
| 93 | + |
| 94 | +Then, use the generated `DemoEnumLocalized` class within your view model to bind to a combo box control: |
| 95 | + |
| 96 | +```csharp |
| 97 | +// ComboBox ItemSource |
| 98 | +public List<DemoEnumLocalized> AllDemoEnums { get; } = DemoEnumLocalized.GetValues(); |
| 99 | + |
| 100 | +// ComboBox SelectedValue |
| 101 | +public DemoEnum SelectedDemoEnum { get; set; } |
| 102 | +``` |
| 103 | + |
| 104 | +In your XAML, bind as follows: |
| 105 | + |
| 106 | +```xml |
| 107 | +<ComboBox |
| 108 | + DisplayMemberPath="Display" |
| 109 | + ItemsSource="{Binding AllDemoEnums}" |
| 110 | + SelectedValue="{Binding SelectedDemoEnum}" |
| 111 | + SelectedValuePath="Value" /> |
| 112 | +``` |
| 113 | + |
| 114 | +To update localization strings when the language changes, you can call: |
| 115 | + |
| 116 | +```csharp |
| 117 | +DemoEnumLocalize.UpdateLabels(AllDemoEnums); |
| 118 | +``` |
0 commit comments