Generate strong locales from JSON files
$ dotnet add package EntityLocalizerhttps://github.com/EntitySystems/EntityLocalizer
Easily create strong properties and methods from JSON localized translations, with optional arguments.
Install latest package EntityLocalizer
https://www.nuget.org/packages/EntityLocalizer/
Add this to .csproj.
<Project>
<Target Name="CodeGen" BeforeTargets="BeforeBuild;BeforeRebuild">
<EslGeneratorTask
InputPath="./StaticResources/Locales"
OutputPath="./GeneratedResources/Locales/"
OutputNamespace="Entity"
/>
</Target>
</Project>
InputPath is the directory from where to load the locales,OutputPath is the directory where the output C# resource file will be generated.OutputNamespace is the namespace for the generated C# file.Once you have setup your project, you can add locales by creating
*.loc.json files, the file names must end in .loc.json.
Format below:
{
"HelloWorld": {
"EN": "Hello generated world!",
"FR": "Bonjour monde!"
},
"Login": {
"EN": "Log in",
"FR": "Connexion",
"?": "Default case override"
}
}
Then you just run a build on consumer project, you can now access your locales/translations via C# using the following:
var locales = new EntityLocales()
{
InstanceLanguage = "EN"
};
Console.WriteLine(locales.HelloWorld); // outputs "Hello generated world!"
If you want to generate translations that accept parameters, you can do the following in the JSON file:
{
"LocaleWithArgument": {
"args": [
"string:name",
"number:amount",
"string:currency"
],
"EN": "Welcome {0}, your bill is of {1} {2}",
"FR": "Bienvenue {0}, votre facture est de {1} {2}"
}
}
Only the 2 following types are supported: string and number.
Supply a mandatory method argument name like so: [type]:[argName]
You can then access the locales and supply arguments like so:
var translated = locales.LocaleWithArgument("Jacob", 129.99m, "$");
// outputs "Welcome Jacob, your bill is of 129.99 $"
type Locale = 'EN' | 'FR'
type I18nSource = Record<string, Record<Locale, string>>
const i18nSource = {
HomeWelcome: {
EN: 'Welcome to App',
FR: 'Bienvenue',
},
Foo: {
EN: 'Foo EN',
FR: 'Foo FR',
},
} satisfies I18nSource
let currentLocale: Locale = 'EN'
const translation = {} as Record<keyof typeof i18nSource, string>
for (const key in i18nSource) {
Object.defineProperty(translation, key, {
get: () => i18nSource[key as never][currentLocale],
})
}
console.log(translation.HomeWelcome)
console.log(translation.Foo)
currentLocale = 'FR'
console.log(translation.HomeWelcome)
console.log(translation.Foo)