RSCG – kli.Localize
| name | kli.Localize |
| nuget | https://www.nuget.org/packages/kli.Localize/ |
| link | https://github.com/kl1mm/localize |
| author | Tobias Klimm |
Generating localization files from json files
This is how you can use kli.Localize .
The code that you start with is
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<PropertyGroup>
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
<CompilerGeneratedFilesOutputPath>$(BaseIntermediateOutputPath)\GX</CompilerGeneratedFilesOutputPath>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="kli.Localize" Version="2.0.4" />
<Localize Include="TestData\AllText_*.json" NeutralCulture="en"/>
</ItemGroup>
<!--<ItemGroup>
<CompilerVisibleProperty Include="FileEmbed_MaxEmbedSize" />
</ItemGroup>
<PropertyGroup>
<FileEmbed_MaxEmbedSize>SIZE_IN_BYTES_GOES_HERE</FileEmbed_MaxEmbedSize>
</PropertyGroup>-->
</Project>
The code that you will use is
using EmbedDemo.TestData;
using System.Globalization;
using System.Text;
Console.WriteLine("Hello, World!");
CultureInfo.CurrentUICulture = new CultureInfo("en-US");
Console.WriteLine(AllText.Welcome);
CultureInfo.CurrentUICulture = new CultureInfo("ro-RO");
Console.WriteLine(AllText.Welcome);
Console.WriteLine(AllText.page1.Text);
{
"Welcome": "Welcome , user",
"page1": {
"Text": "List of Persons"
}
}
{
"Welcome": "Bine ai venit",
"page1": {
"Text": "Lista persoanelor"
}
}
The code that is generated is
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by kli.Localize.Generator.
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace EmbedDemo.TestData
{
using System;
using System.Globalization;
using System.Collections.Generic;
using Translations = System.Collections.Generic.Dictionary<string, string>;
///<summary>Localizations from "AllText_en.json"</summary>
public sealed partial class AllText
{
private static readonly LocalizationProvider provider = new LocalizationProvider();
/// <summary>
/// Retrieves all translations for the specified culture.
/// </summary>
/// <param name="cultureInfo">The culture for which translations are retrieved. Defaults to the current UI culture.</param>
/// <returns>A dictionary containing all translations for the specified culture.</returns>
public static IDictionary<string, string> GetAll(CultureInfo cultureInfo = null) => provider.GetValues(cultureInfo ?? CultureInfo.CurrentUICulture);
/// <summary>
/// Retrieves a localized string for the specified key and culture.
/// </summary>
/// <param name="key">The key of the string to retrieve.</param>
/// <param name="cultureInfo">The culture for which the string is retrieved. Defaults to the current UI culture.</param>
/// <returns>The localized string if found, traversing through parent cultures. Otherwise, the key itself.</returns>
public static string GetString(string key, CultureInfo cultureInfo = null) => provider.GetValue(key, cultureInfo ?? CultureInfo.CurrentUICulture);
private class LocalizationProvider
{
delegate bool SelectorFunc<T>(Translations translations, out T arg);
internal string GetValue(string key, CultureInfo cultureInfo)
{
bool ValueSelector(Translations translations, out string value)
{
if (translations.TryGetValue(key, out value))
return true;
value = key;
return false;
}
return TraverseCultures<string>(cultureInfo, ValueSelector);
}
internal IDictionary<string, string> GetValues(CultureInfo cultureInfo)
{
bool ValueSelector(Translations translations, out Translations value)
{
value = translations;
return true;
}
return TraverseCultures<Translations>(cultureInfo, ValueSelector);
}
private T TraverseCultures<T>(CultureInfo cultureInfo, SelectorFunc<T> selectorFunc)
{
if (resources.TryGetValue(cultureInfo, out Translations translations))
{
if (selectorFunc(translations, out T result) || cultureInfo == CultureInfo.InvariantCulture)
return result;
}
return TraverseCultures<T>(cultureInfo.Parent, selectorFunc);
}
private static readonly Translations invariant = new()
{
{
"Welcome",
"Welcome , user"
},
{
"page1::Text",
"List of Persons"
},
};
private static readonly Translations ro = new()
{
{
"Welcome",
"Bine ai venit"
},
{
"page1::Text",
"Lista persoanelor"
},
};
private static readonly Dictionary<CultureInfo, Translations> resources = new()
{
{
CultureInfo.InvariantCulture,
invariant
},
{
new CultureInfo("ro"),
ro
},
};
}
///<summary>Similar to: Welcome , user</summary>
public static string Welcome => provider.GetValue("Welcome", CultureInfo.CurrentUICulture);
///<summary>Localizations for "page1" from "AllText_en.json"</summary>
public static class page1
{
///<summary>Similar to: List of Persons</summary>
public static string Text => provider.GetValue("page1::Text", CultureInfo.CurrentUICulture);
}
}
}
Code and pdf at
https://ignatandrei.github.io/RSCG_Examples/v2/docs/kli.Localize