├── .github └── workflows │ ├── build-ci.yml │ └── build-pr.yml ├── .gitignore ├── BlazorJsonLocalization.sln ├── LICENSE ├── README.md ├── coverlet.runsettings ├── documents ├── BreakingChanges.md └── LocalizationGen.md └── src ├── SharedProperties.props ├── examples ├── SoloX.BlazorJsonLocalization.Example.Components.Embedded │ ├── ComponentsEmbeddedExtensions.cs │ ├── Pages │ │ ├── Index.razor │ │ └── Index.razor.cs │ ├── Resources │ │ ├── Pages │ │ │ ├── Index.fr.json │ │ │ └── Index.json │ │ ├── SharedResource.fr.json │ │ └── SharedResource.json │ ├── SharedResource.cs │ ├── SoloX.BlazorJsonLocalization.Example.Components.Embedded.csproj │ └── _Imports.razor ├── SoloX.BlazorJsonLocalization.Example.Components.Embedded2 │ ├── ComponentsEmbeddedExtensions.cs │ ├── Pages │ │ ├── Component1.razor │ │ └── Component1.razor.cs │ ├── Resources │ │ └── Pages │ │ │ ├── Component1.fr.json │ │ │ └── Component1.json │ ├── SoloX.BlazorJsonLocalization.Example.Components.Embedded2.csproj │ └── _Imports.razor ├── SoloX.BlazorJsonLocalization.Example.Components.Embedded3 │ ├── ComponentsEmbeddedExtensions.cs │ ├── Pages │ │ ├── Component2.razor │ │ ├── Component2.razor.cs │ │ ├── Component2.razor.fr.json │ │ ├── Component2.razor.json │ │ └── test.json │ ├── SoloX.BlazorJsonLocalization.Example.Components.Embedded3.csproj │ └── _Imports.razor ├── SoloX.BlazorJsonLocalization.Example.Components.SharedLocalization │ ├── IGlobal.cs │ ├── Resources │ │ ├── Fallback.fr.json │ │ ├── Fallback.json │ │ ├── IGlobal.fr.json │ │ └── IGlobal.json │ ├── SharedLocalizationExtensions.cs │ └── SoloX.BlazorJsonLocalization.Example.Components.SharedLocalization.csproj ├── SoloX.BlazorJsonLocalization.Example.Components.StaticAssets │ ├── ComponentsStaticAssetsExtensions.cs │ ├── Pages │ │ ├── Counter.razor │ │ └── Counter.razor.cs │ ├── SoloX.BlazorJsonLocalization.Example.Components.StaticAssets.csproj │ ├── _Imports.razor │ └── wwwroot │ │ └── Resources │ │ └── Pages │ │ ├── Counter-en.json │ │ ├── Counter-fr.json │ │ └── Counter.json ├── SoloX.BlazorJsonLocalization.Example.ServerSide │ ├── App.razor │ ├── Controllers │ │ └── CultureController.cs │ ├── Pages │ │ ├── Error.cshtml │ │ ├── Error.cshtml.cs │ │ └── _Host.cshtml │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Shared │ │ ├── MainLayout.razor │ │ ├── MainLayout.razor.css │ │ ├── NavMenu.razor │ │ └── NavMenu.razor.css │ ├── SoloX.BlazorJsonLocalization.Example.ServerSide.csproj │ ├── Startup.cs │ ├── _Imports.razor │ ├── appsettings.Development.json │ ├── appsettings.json │ └── wwwroot │ │ ├── css │ │ ├── bootstrap │ │ │ ├── bootstrap.min.css │ │ │ └── bootstrap.min.css.map │ │ ├── open-iconic │ │ │ ├── FONT-LICENSE │ │ │ ├── ICON-LICENSE │ │ │ ├── README.md │ │ │ └── font │ │ │ │ ├── css │ │ │ │ └── open-iconic-bootstrap.min.css │ │ │ │ └── fonts │ │ │ │ ├── open-iconic.eot │ │ │ │ ├── open-iconic.otf │ │ │ │ ├── open-iconic.svg │ │ │ │ ├── open-iconic.ttf │ │ │ │ └── open-iconic.woff │ │ └── site.css │ │ └── favicon.ico ├── SoloX.BlazorJsonLocalization.Example.Wasm │ ├── App.razor │ ├── Program.cs │ ├── Properties │ │ └── launchSettings.json │ ├── Shared │ │ ├── MainLayout.razor │ │ ├── MainLayout.razor.css │ │ ├── NavMenu.razor │ │ └── NavMenu.razor.css │ ├── SoloX.BlazorJsonLocalization.Example.Wasm.csproj │ ├── _Imports.razor │ └── wwwroot │ │ ├── css │ │ ├── app.css │ │ └── bootstrap │ │ │ ├── bootstrap.min.css │ │ │ └── bootstrap.min.css.map │ │ ├── favicon.ico │ │ └── index.html └── SoloX.BlazorJsonLocalization.Example.WebApp │ ├── SoloX.BlazorJsonLocalization.Example.WebApp.Client │ ├── Pages │ │ └── Counter.razor │ ├── Program.cs │ ├── SoloX.BlazorJsonLocalization.Example.WebApp.Client.csproj │ ├── _Imports.razor │ └── wwwroot │ │ ├── Resources │ │ ├── Fallback.en.json │ │ ├── Fallback.fr.json │ │ ├── Fallback.json │ │ └── Pages │ │ │ ├── Counter.en.json │ │ │ ├── Counter.fr.json │ │ │ └── Counter.json │ │ ├── appsettings.Development.json │ │ └── appsettings.json │ └── SoloX.BlazorJsonLocalization.Example.WebApp │ ├── Components │ ├── App.razor │ ├── Layout │ │ ├── MainLayout.razor │ │ ├── MainLayout.razor.css │ │ ├── NavMenu.razor │ │ └── NavMenu.razor.css │ ├── Pages │ │ ├── Error.razor │ │ ├── Home.razor │ │ └── Weather.razor │ ├── Routes.razor │ └── _Imports.razor │ ├── Program.cs │ ├── Properties │ └── launchSettings.json │ ├── SoloX.BlazorJsonLocalization.Example.WebApp.csproj │ ├── appsettings.Development.json │ ├── appsettings.json │ └── wwwroot │ ├── Resources │ └── Components │ │ └── Pages │ │ ├── Home.en.json │ │ ├── Home.fr.json │ │ └── Home.json │ ├── app.css │ ├── bootstrap │ ├── bootstrap.min.css │ └── bootstrap.min.css.map │ └── favicon.png ├── libs ├── SoloX.BlazorJsonLocalization.Attributes │ ├── .gitignore │ ├── LocalizerAttribute.cs │ ├── SoloX.BlazorJsonLocalization.Attributes.csproj │ ├── SubLocalizerAttribute.cs │ ├── TranslateArgAttribute.cs │ ├── TranslateAttribute.cs │ └── TranslateSubAttribute.cs ├── SoloX.BlazorJsonLocalization.ServerSide │ ├── .gitignore │ ├── JsonLocalizationOptionsBuilderExtensions.cs │ ├── LoggingExtensions.cs │ ├── Properties │ │ └── launchSettings.json │ ├── ServiceCollectionExtensions.cs │ ├── Services │ │ └── Impl │ │ │ └── HttpHostedJsonLocalizationExtensionService.cs │ └── SoloX.BlazorJsonLocalization.ServerSide.csproj ├── SoloX.BlazorJsonLocalization.WebAssembly │ ├── .gitignore │ ├── JsonLocalizationOptionsBuilderExtensions.cs │ ├── ServiceCollectionExtensions.cs │ └── SoloX.BlazorJsonLocalization.WebAssembly.csproj └── SoloX.BlazorJsonLocalization │ ├── .gitignore │ ├── AssemblyProperties.cs │ ├── Core │ ├── AExtensionOptions.cs │ ├── AJsonExtensionOptions.cs │ ├── IExtensionOptionsContainer.cs │ ├── IJsonStringLocalizerFactoryInternal.cs │ └── Impl │ │ ├── AStringLocalizerInternal.cs │ │ ├── ConstStringLocalizer.cs │ │ ├── ExtensionOptionsContainer.cs │ │ ├── JsonStringLocalizer.cs │ │ ├── JsonStringLocalizerAsync.cs │ │ ├── JsonStringLocalizerFactory.cs │ │ ├── NullStringLocalizer.cs │ │ ├── SatelliteFileProviderFactory.cs │ │ ├── StringLocalizerProxy.cs │ │ ├── StringLocalizerResourceSource.cs │ │ └── SubStringLocalizer.cs │ ├── EmbeddedJsonLocalizationOptions.cs │ ├── Helpers │ ├── ArgumentNullExceptionLegacy.cs │ ├── CultureInfoHelper.cs │ ├── Impl │ │ ├── AJsonMapData.cs │ │ ├── JsonLocalizationOptionsExtensions.cs │ │ ├── JsonMapDataConverter.cs │ │ ├── JsonMapDataDictionary.cs │ │ └── JsonMapDataValue.cs │ ├── JsonHelper.cs │ ├── NameHelper.cs │ └── ResourcePathHelper.cs │ ├── Http │ └── JsonLocalizationOptionsBuilderExtensions.cs │ ├── HttpClientJsonLocalizationOptions.cs │ ├── HttpHostedJsonLocalizationOptions.cs │ ├── JsonLocalizationOptions.cs │ ├── JsonLocalizationOptionsBuilder.cs │ ├── JsonLocalizationOptionsBuilderExtensions.cs │ ├── Key.cs │ ├── LoggingExtensions.cs │ ├── ServiceCollectionExtensions.cs │ ├── Services │ ├── ICacheService.cs │ ├── ICultureInfoService.cs │ ├── IExtensionResolverService.cs │ ├── IHttpCacheService.cs │ ├── IJsonLocalizationExtensionService.cs │ └── Impl │ │ ├── AHttpHostedJsonLocalizationExtensionService.cs │ │ ├── CacheService.cs │ │ ├── CultureInfoService.cs │ │ ├── EmbeddedJsonLocalizationExtensionService.cs │ │ ├── ExtensionResolverService.cs │ │ ├── HttpCacheService.cs │ │ └── HttpClientJsonLocalizationExtensionService.cs │ ├── SoloX.BlazorJsonLocalization.csproj │ └── StringLocalizerExtensions.cs ├── tests ├── SoloX.BlazorJsonLocalization.ITests │ ├── .gitignore │ ├── Global.cs │ ├── IGlobal.cs │ ├── ISpecific.cs │ ├── JsonLocalyserFallbackTest.cs │ ├── JsonLocalyserInheritTest.cs │ ├── JsonLocalyserServerSideSetupTest.cs │ ├── JsonLocalyserSetupTest.cs │ ├── JsonLocalyserWebAssemblySetupTest.cs │ ├── Resources │ │ ├── Fallback.fr.json │ │ ├── Fallback.json │ │ ├── Global.json │ │ ├── IGlobal.fr.json │ │ ├── IGlobal.json │ │ ├── ISpecific.fr.json │ │ ├── ISpecific.json │ │ ├── JsonLocalyserSetupTest.fr.json │ │ ├── JsonLocalyserSetupTest.json │ │ └── Specific.json │ ├── SoloX.BlazorJsonLocalization.ITests.csproj │ ├── Specific.cs │ └── Utils │ │ └── SetupHelper.cs ├── SoloX.BlazorJsonLocalization.ServerSide.UTests │ ├── .gitignore │ ├── Services │ │ └── HttpHostedJsonLocalizationExtensionServiceTest.cs │ └── SoloX.BlazorJsonLocalization.ServerSide.UTests.csproj ├── SoloX.BlazorJsonLocalization.UTests │ ├── .gitignore │ ├── Core │ │ ├── ConstStringLocalizerTest.cs │ │ ├── JsonStringLocalizerAsyncTest.cs │ │ ├── JsonStringLocalizerFactoryInternalTest.cs │ │ ├── JsonStringLocalizerFactoryTest.cs │ │ ├── JsonStringLocalizerTest.cs │ │ ├── NullStringLocalizerTest.cs │ │ ├── SatelliteFileProviderFactoryTest.cs │ │ ├── StringLocalizerProxyTest.cs │ │ └── SubStringLocalizerTest.cs │ ├── Helpers │ │ ├── CultureInfoHelperTest.cs │ │ ├── JsonHelperTest.cs │ │ └── ResourcePathHelperTest.cs │ ├── Resources │ │ ├── EmbeddedJsonLocalizationExtensionServiceTest.fr.json │ │ ├── EmbeddedJsonLocalizationExtensionServiceTest.json │ │ ├── EmbeddedJsonLocalizationExtensionUsingAccentsTest.json │ │ └── SatelliteFileProvider │ │ │ ├── Test.fr.json │ │ │ └── Test.json │ ├── Samples │ │ └── Extension │ │ │ ├── MyExtensionService.cs │ │ │ └── MyOptions.cs │ ├── Services │ │ ├── CacheServiceTest.cs │ │ ├── CultureInfoServiceTest.cs │ │ ├── EmbeddedJsonLocalizationExtensionServiceTest.cs │ │ ├── EmbeddedJsonLocalizationExtensionUsingAccentsTest.cs │ │ ├── ExtensionResolverServiceTest.cs │ │ ├── HttpCacheServiceTest.cs │ │ └── HttpClientJsonLocalizationExtensionServiceTest.cs │ └── SoloX.BlazorJsonLocalization.UTests.csproj └── SoloX.BlazorJsonLocalization.WebAssembly.UTests │ ├── .gitignore │ └── SoloX.BlazorJsonLocalization.WebAssembly.UTests.csproj ├── tools.examples └── SoloX.BlazorJsonLocalization.Generator.Sample │ ├── .gitignore │ ├── Components │ ├── IMyComponentStringLocalizer.cs │ └── MyComponent.cs │ ├── ITestStringLocalizer.cs │ ├── Program.cs │ ├── SoloX.BlazorJsonLocalization.Generator.Sample.csproj │ └── Test.cs ├── tools.tests ├── SoloX.BlazorJsonLocalization.Generator.ITests │ ├── .gitignore │ ├── Snapshots │ │ └── GenerateBasicLocalizerISimpleLocalizer.snapshot │ ├── SoloX.BlazorJsonLocalization.Generator.ITests.csproj │ ├── ToolsGeneratorTest.cs │ └── Usings.cs ├── SoloX.BlazorJsonLocalization.Tools.Core.ITests │ ├── .gitignore │ ├── Snapshots │ │ ├── GenerateBasicLocalizerISimpleLocalizer0.snapshot │ │ ├── GenerateBasicLocalizerWithTranslateAndMultiLineIMultiLineLocalizer0.snapshot │ │ ├── GenerateBasicLocalizerWithTranslateAndMultiLineIMultiLineLocalizer1.snapshot │ │ ├── GenerateBasicLocalizerWithTranslateAndMultiLineIMultiLineLocalizer2.snapshot │ │ ├── GenerateBasicLocalizerWithTranslateAndMultiLineIMultiLineLocalizer3.snapshot │ │ ├── GenerateBasicLocalizerWithTranslateAndMultiLineIMultiLineLocalizer4.snapshot │ │ ├── GenerateBasicLocalizerWithTranslateAndMultiLineIMultiLineLocalizer5.snapshot │ │ ├── GenerateBasicLocalizerWithTranslateAndSpecialCharsISimpleLocalizer0.snapshot │ │ ├── GenerateSubLocalizerISimpleLocalizer0.snapshot │ │ ├── GenerateSubLocalizerISimpleLocalizer1.snapshot │ │ ├── GenerateSubLocalizerISimpleLocalizer2.snapshot │ │ ├── GenerateSubLocalizerISimpleLocalizer3.snapshot │ │ ├── GenerateSubLocalizerNameISimple0.snapshot │ │ ├── GenerateSubLocalizerWithTranslateISimpleLocalizer0.snapshot │ │ └── GenerateSubLocalizerWithTranslateISimpleLocalizer1.snapshot │ ├── SoloX.BlazorJsonLocalization.Tools.Core.ITests.csproj │ ├── ToolsGeneratorTest.cs │ └── Usings.cs ├── SoloX.BlazorJsonLocalization.Tools.Core.Samples │ ├── Component.cs │ ├── SampleBasic │ │ └── ISimpleLocalizer.cs │ ├── SampleSubLocalizerName │ │ ├── ISimple.cs │ │ └── ISimpleSub.cs │ ├── SampleWithMultiLine │ │ └── IMultiLineLocalizer.cs │ ├── SampleWithSubLocalizer │ │ ├── ISimpleLocalizer.cs │ │ └── ISimpleSubLocalizer.cs │ ├── SampleWithSubLocalizerTranslate │ │ ├── ISimpleLocalizer.cs │ │ └── ISimpleSubLocalizer.cs │ ├── SampleWithTranslate │ │ └── ISimpleLocalizer.cs │ └── SoloX.BlazorJsonLocalization.Tools.Core.Samples.csproj └── SoloX.BlazorJsonLocalization.Tools.Core.UTests │ ├── .gitignore │ ├── FileReaderTest.cs │ ├── LocalizationMapTest.cs │ ├── PatternsTest.cs │ ├── SoloX.BlazorJsonLocalization.Tools.Core.UTests.csproj │ └── Usings.cs └── tools ├── SoloX.BlazorJsonLocalization.Generator ├── .gitignore ├── GeneratorHandler.cs └── SoloX.BlazorJsonLocalization.Generator.csproj ├── SoloX.BlazorJsonLocalization.Tools.Command ├── .gitignore ├── GeneratorCommand.cs ├── Program.cs ├── Properties │ └── launchSettings.json └── SoloX.BlazorJsonLocalization.Tools.Command.csproj ├── SoloX.BlazorJsonLocalization.Tools.Core ├── .gitignore ├── AssemblyProperties.cs ├── Handlers │ └── TypeReplaceHandler.cs ├── ILocalizationGenerator.cs ├── ILocalizationGeneratorResults.cs ├── IReader.cs ├── Impl │ ├── FileReader.cs │ ├── JsonFileGenerator.cs │ ├── Localization │ │ ├── ALocalizationData.cs │ │ ├── LocalizationMap.cs │ │ ├── LocalizationMapConverter.cs │ │ └── LocalizationValue.cs │ ├── LocalizationGenerator.cs │ └── LocalizationGeneratorResults.cs ├── Patterns │ ├── Impl │ │ ├── MyObjectStringLocalizerPattern.cs │ │ ├── MyObjectStringLocalizerPatternExtensions.cs │ │ ├── MyObjectSub2StringLocalizerPattern.cs │ │ └── MyObjectSubStringLocalizerPattern.cs │ ├── Itf │ │ ├── IMyObjectStringLocalizerPattern.cs │ │ ├── IMyObjectSub2StringLocalizerPattern.cs │ │ ├── IMyObjectSubStringLocalizerPattern.cs │ │ └── MyObject.cs │ └── LocalizerExtensions.cs ├── Selectors │ ├── ALocalizerSelector.cs │ ├── LocalizerArgumentSelector.cs │ ├── LocalizerPropertySelector.cs │ ├── SelectorResolver.cs │ └── SubLocalizerPropertySelector.cs └── SoloX.BlazorJsonLocalization.Tools.Core.csproj └── SoloX.BlazorJsonLocalization.Tools.Extensions ├── .gitignore ├── SoloX.BlazorJsonLocalization.Tools.Extensions.csproj └── ToolsGeneratorExtensions.cs /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Xavier Solau 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /coverlet.runsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | cobertura 8 | false 9 | false 10 | false 11 | true 12 | true 13 | **/LoggerMessage.g.cs, 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /src/SharedProperties.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 3.0.0-alpha.1 5 | Xavier Solau 6 | Copyright © 2021 Xavier Solau 7 | MIT 8 | https://github.com/xaviersolau/BlazorJsonLocalization 9 | https://github.com/xaviersolau/BlazorJsonLocalization.git 10 | git 11 | 12 | $(Authors) 13 | $(Copyright) 14 | $(PackageLicenseExpression) 15 | LICENSE 16 | 17 | true 18 | 19 | enable 20 | 21 | false 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.Components.Embedded/ComponentsEmbeddedExtensions.cs: -------------------------------------------------------------------------------- 1 | using SoloX.BlazorJsonLocalization; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace SoloX.BlazorJsonLocalization.Example.Components.Embedded 9 | { 10 | public static class ComponentsEmbeddedExtensions 11 | { 12 | public static JsonLocalizationOptionsBuilder UseComponentsEmbedded(this JsonLocalizationOptionsBuilder builder) 13 | { 14 | return builder.UseEmbeddedJson(options => 15 | { 16 | options.Assemblies = new[] { typeof(ComponentsEmbeddedExtensions).Assembly }; 17 | options.ResourcesPath = "Resources"; 18 | }); 19 | } 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.Components.Embedded/Pages/Index.razor: -------------------------------------------------------------------------------- 1 | @page "/" 2 | 3 |

@L["Hello"]

4 | 5 |

6 | @L["Welcome"] 7 |

8 | 9 | 10 |

11 | @L["Global"] 12 |

13 | 14 |

15 | @L["FallBackMessage"] 16 |

17 | 18 | 19 |

20 | @L["Here is an example with accents"] 21 |

22 | 23 |

24 | @L.GetSubLocalizer("Dashboard")["TITLE"] 25 |

26 | 27 |

28 | @L.GetSubLocalizer("Dashboard").GetSubLocalizer("List")["MESSAGES"] 29 |

30 | 31 |

32 | @L[Key.Path("Dashboard", "TITLE")] 33 |

34 | 35 |

36 | @L[Key.Path("Dashboard", "List", "MESSAGES")] 37 |

38 | 39 |

40 | @L["Dashboard:TITLE"] 41 |

42 | 43 |

44 | @L["Dashboard:List:MESSAGES"] 45 |

46 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.Components.Embedded/Pages/Index.razor.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Components; 2 | using Microsoft.Extensions.Localization; 3 | using SoloX.BlazorJsonLocalization.Example.Components.SharedLocalization; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Linq; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace SoloX.BlazorJsonLocalization.Example.Components.Embedded.Pages 11 | { 12 | public partial class Index : IGlobal 13 | { 14 | [Inject] 15 | private IStringLocalizer L { get; set; } 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.Components.Embedded/Resources/Pages/Index.fr.json: -------------------------------------------------------------------------------- 1 | { 2 | "Hello": "Bonjour tout le monde!", 3 | "Welcome": "Bienvenue dans votre nouvelle application.", 4 | "Here is an example with accents": "Voici quelques accents : é è à ô ä....", 5 | "Dashboard": { 6 | "TITLE": "Tableau des messages", 7 | "List": { 8 | "MESSAGES": "Des messages" 9 | } 10 | } 11 | } -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.Components.Embedded/Resources/Pages/Index.json: -------------------------------------------------------------------------------- 1 | { 2 | "Hello": "Hello world!", 3 | "Welcome": "Welcome to your new app.", 4 | "Here is an example with accents": "Here are some accents: é è à ô ä....", 5 | "Dashboard": { 6 | "TITLE": "Message Dashboard", 7 | "List": { 8 | "MESSAGES": "Messages" 9 | } 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.Components.Embedded/Resources/SharedResource.fr.json: -------------------------------------------------------------------------------- 1 | { 2 | "About": "Info", 3 | "Home": "Acceuil", 4 | "Counter": "Compteur", 5 | "Title": "Localisation Json", 6 | "Component1": "Component1 (Fr)", 7 | "Component2": "Component2 (Fr)" 8 | } -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.Components.Embedded/Resources/SharedResource.json: -------------------------------------------------------------------------------- 1 | { 2 | "About": "About", 3 | "Home": "Home", 4 | "Counter": "Counter", 5 | "Title": "Json Localizer", 6 | "Component1": "Component1", 7 | "Component2": "Component2" 8 | } 9 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.Components.Embedded/SharedResource.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace SoloX.BlazorJsonLocalization.Example.Components.Embedded 8 | { 9 | /// 10 | /// This class is just here to provide an entry point for the shared localization resources. 11 | /// It must be inject with the type IStringLocalizer. 12 | /// 13 | public class SharedResource 14 | { 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.Components.Embedded/SoloX.BlazorJsonLocalization.Example.Components.Embedded.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net9.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.Components.Embedded/_Imports.razor: -------------------------------------------------------------------------------- 1 |  2 | @using Microsoft.AspNetCore.Components.Web 3 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.Components.Embedded2/ComponentsEmbeddedExtensions.cs: -------------------------------------------------------------------------------- 1 | using SoloX.BlazorJsonLocalization; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.Linq; 5 | using System.Text; 6 | using System.Threading.Tasks; 7 | 8 | namespace An.Other.Name.Embedded 9 | { 10 | public static class ComponentsEmbeddedExtensions 11 | { 12 | public static JsonLocalizationOptionsBuilder UseComponentsEmbedded2(this JsonLocalizationOptionsBuilder builder) 13 | { 14 | return builder.UseEmbeddedJson(options => 15 | { 16 | options.Assemblies = new[] { typeof(ComponentsEmbeddedExtensions).Assembly }; 17 | options.ResourcesPath = "Resources"; 18 | options.RootNameSpaceResolver = _ => typeof(ComponentsEmbeddedExtensions).Namespace; 19 | }); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.Components.Embedded2/Pages/Component1.razor: -------------------------------------------------------------------------------- 1 | @page "/component1" 2 | 3 |

Component1

4 | 5 |

6 | @L["Component1Hello"] 7 |

8 | 9 | 10 | @code { 11 | 12 | } 13 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.Components.Embedded2/Pages/Component1.razor.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Components; 2 | using Microsoft.Extensions.Localization; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace An.Other.Name.Embedded.Pages 10 | { 11 | public partial class Component1 12 | { 13 | [Inject] 14 | private IStringLocalizer L { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.Components.Embedded2/Resources/Pages/Component1.fr.json: -------------------------------------------------------------------------------- 1 | { 2 | "Component1Hello": "Bonjour de Component1" 3 | } -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.Components.Embedded2/Resources/Pages/Component1.json: -------------------------------------------------------------------------------- 1 | { 2 | "Component1Hello": "Hello from component1" 3 | } 4 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.Components.Embedded2/SoloX.BlazorJsonLocalization.Example.Components.Embedded2.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net9.0 5 | enable 6 | enable 7 | An.Other.Name.Embedded 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.Components.Embedded2/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using Microsoft.AspNetCore.Components.Web 2 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.Components.Embedded3/ComponentsEmbeddedExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace SoloX.BlazorJsonLocalization.Example.Components.Embedded3 8 | { 9 | public static class ComponentsEmbeddedExtensions 10 | { 11 | public static JsonLocalizationOptionsBuilder UseComponentsEmbedded3(this JsonLocalizationOptionsBuilder builder) 12 | { 13 | return builder.UseEmbeddedJson(options => 14 | { 15 | options.Assemblies = new[] { typeof(ComponentsEmbeddedExtensions).Assembly }; 16 | options.NamingPolicy = (basePath, cultureName) => $"{basePath}.razor{(string.IsNullOrEmpty(cultureName) ? string.Empty : $".{cultureName}")}.json"; 17 | }); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.Components.Embedded3/Pages/Component2.razor: -------------------------------------------------------------------------------- 1 | @page "/component2" 2 | 3 |

Component2

4 | 5 |

6 | @L["Component2Hello"] 7 |

8 | 9 | @code { 10 | 11 | } 12 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.Components.Embedded3/Pages/Component2.razor.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Components; 2 | using Microsoft.Extensions.Localization; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace SoloX.BlazorJsonLocalization.Example.Components.Embedded3.Pages 10 | { 11 | public partial class Component2 12 | { 13 | [Inject] 14 | private IStringLocalizer L { get; set; } 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.Components.Embedded3/Pages/Component2.razor.fr.json: -------------------------------------------------------------------------------- 1 | { 2 | "Component2Hello": "Bonjour de Component2" 3 | } -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.Components.Embedded3/Pages/Component2.razor.json: -------------------------------------------------------------------------------- 1 | { 2 | "Component2Hello": "Hello from component2" 3 | } 4 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.Components.Embedded3/Pages/test.json: -------------------------------------------------------------------------------- 1 | { 2 | "Component2Hello": "Bonjour de Component2" 3 | } -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.Components.Embedded3/SoloX.BlazorJsonLocalization.Example.Components.Embedded3.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net9.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.Components.Embedded3/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using Microsoft.AspNetCore.Components.Web 2 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.Components.SharedLocalization/IGlobal.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace SoloX.BlazorJsonLocalization.Example.Components.SharedLocalization 8 | { 9 | public interface IGlobal 10 | { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.Components.SharedLocalization/Resources/Fallback.fr.json: -------------------------------------------------------------------------------- 1 | { 2 | "FallBackMessage": "C’est un message fallback utilisable via configuration..." 3 | } 4 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.Components.SharedLocalization/Resources/Fallback.json: -------------------------------------------------------------------------------- 1 | { 2 | "FallBackMessage": "This is fallback message usable through configuration..." 3 | } 4 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.Components.SharedLocalization/Resources/IGlobal.fr.json: -------------------------------------------------------------------------------- 1 | { 2 | "Global": "C’est un message global utilisable via héritage..." 3 | } 4 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.Components.SharedLocalization/Resources/IGlobal.json: -------------------------------------------------------------------------------- 1 | { 2 | "Global": "This is global message usable through inheritance..." 3 | } 4 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.Components.SharedLocalization/SharedLocalizationExtensions.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace SoloX.BlazorJsonLocalization.Example.Components.SharedLocalization 8 | { 9 | public static class SharedLocalizationExtensions 10 | { 11 | public static JsonLocalizationOptionsBuilder UseSharedLocalization(this JsonLocalizationOptionsBuilder builder) 12 | { 13 | return builder.UseEmbeddedJson(options => 14 | { 15 | options.Assemblies = new[] { typeof(SharedLocalizationExtensions).Assembly }; 16 | options.ResourcesPath = "Resources"; 17 | }); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.Components.SharedLocalization/SoloX.BlazorJsonLocalization.Example.Components.SharedLocalization.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net9.0 5 | enable 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.Components.StaticAssets/ComponentsStaticAssetsExtensions.cs: -------------------------------------------------------------------------------- 1 | using SoloX.BlazorJsonLocalization; 2 | using SoloX.BlazorJsonLocalization.Http; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Reflection; 7 | using System.Text; 8 | using System.Threading.Tasks; 9 | 10 | namespace SoloX.BlazorJsonLocalization.Example.Components.StaticAssets 11 | { 12 | public static class ComponentsStaticAssetsExtensions 13 | { 14 | /// 15 | /// Setup for Http hosted static asserts. 16 | /// 17 | /// HttpClientJsonLocalizationOptions must be use for web assembly projects and 18 | /// HttpHostedJsonLocalizationOptions for server side (if loading directly resource files) 19 | /// 20 | /// 21 | /// 22 | public static JsonLocalizationOptionsBuilder UseComponentsStaticAssets(this JsonLocalizationOptionsBuilder builder) 23 | where TOptions : HttpHostedJsonLocalizationOptions, new() 24 | { 25 | return builder.UseHttpHostedJson(options => 26 | { 27 | options.Assemblies = new[] { typeof(ComponentsStaticAssetsExtensions).Assembly }; 28 | 29 | // we don't need to setup the applicationAssembly because this options focuses only on this component that will be a component of the application. 30 | //options.ApplicationAssembly = null; 31 | 32 | options.NamingPolicy = (basePath, cultureName) => new Uri($"{basePath}{(string.IsNullOrEmpty(cultureName) ? string.Empty : $"-{cultureName}")}.json", UriKind.Relative); 33 | options.ResourcesPath = "Resources"; 34 | }); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.Components.StaticAssets/Pages/Counter.razor: -------------------------------------------------------------------------------- 1 | @page "/counter" 2 | 3 |

@L["Counter"]

4 | 5 |

@L["Current count", currentCount]

6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.Components.StaticAssets/Pages/Counter.razor.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Components; 2 | using Microsoft.Extensions.Localization; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | using SoloX.BlazorJsonLocalization; 9 | 10 | namespace SoloX.BlazorJsonLocalization.Example.Components.StaticAssets.Pages 11 | { 12 | public partial class Counter 13 | { 14 | [Inject] 15 | private IStringLocalizer L { get; set; } 16 | 17 | private int currentCount = 0; 18 | 19 | private void IncrementCount() 20 | { 21 | currentCount++; 22 | } 23 | 24 | protected override async Task OnInitializedAsync() 25 | { 26 | await L.LoadAsync(); 27 | await base.OnInitializedAsync(); 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.Components.StaticAssets/SoloX.BlazorJsonLocalization.Example.Components.StaticAssets.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net9.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.Components.StaticAssets/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using Microsoft.AspNetCore.Components.Web 2 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.Components.StaticAssets/wwwroot/Resources/Pages/Counter-en.json: -------------------------------------------------------------------------------- 1 | { 2 | "Counter": "Counter", 3 | "Current count": "Current count : {0}.", 4 | "Click": "Click me" 5 | } 6 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.Components.StaticAssets/wwwroot/Resources/Pages/Counter-fr.json: -------------------------------------------------------------------------------- 1 | { 2 | "Counter": "Compteur", 3 | "Current count": "Compte courant : {0}.", 4 | "Click": "Cliquez ici" 5 | } -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.Components.StaticAssets/wwwroot/Resources/Pages/Counter.json: -------------------------------------------------------------------------------- 1 | { 2 | "Counter": "Counter", 3 | "Current count": "Current count : {0}.", 4 | "Click": "Click me" 5 | } 6 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.ServerSide/App.razor: -------------------------------------------------------------------------------- 1 | 2 | 9 | 10 | 11 | 12 | 13 | 14 |

Sorry, there's nothing at this address.

15 |
16 |
17 |
18 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.ServerSide/Controllers/CultureController.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Threading.Tasks; 5 | using Microsoft.AspNetCore.Http; 6 | using Microsoft.AspNetCore.Localization; 7 | using Microsoft.AspNetCore.Mvc; 8 | 9 | namespace SoloX.BlazorJsonLocalization.Example.ServerSide.Controllers 10 | { 11 | /// 12 | /// This controller is dedicated to setup the current culture in a Browser cookie. 13 | /// See https://docs.microsoft.com/fr-fr/aspnet/core/blazor/globalization-localization?view=aspnetcore-5.0#provide-ui-to-choose-the-culture 14 | /// for more informations. 15 | /// 16 | [Route("[controller]/[action]")] 17 | public class CultureController : Controller 18 | { 19 | public IActionResult SetCulture(string culture, string redirectUri) 20 | { 21 | if (culture != null) 22 | { 23 | HttpContext.Response.Cookies.Append( 24 | CookieRequestCultureProvider.DefaultCookieName, 25 | CookieRequestCultureProvider.MakeCookieValue( 26 | new RequestCulture(culture))); 27 | } 28 | 29 | return LocalRedirect(redirectUri); 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.ServerSide/Pages/Error.cshtml: -------------------------------------------------------------------------------- 1 | @page 2 | @model SoloX.BlazorJsonLocalization.Example.ServerSide.Pages.ErrorModel 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Error 11 | 12 | 13 | 14 | 15 | 16 |
17 |
18 |

Error.

19 |

An error occurred while processing your request.

20 | 21 | @if (Model.ShowRequestId) 22 | { 23 |

24 | Request ID: @Model.RequestId 25 |

26 | } 27 | 28 |

Development Mode

29 |

30 | Swapping to the Development environment displays detailed information about the error that occurred. 31 |

32 |

33 | The Development environment shouldn't be enabled for deployed applications. 34 | It can result in displaying sensitive information from exceptions to end users. 35 | For local debugging, enable the Development environment by setting the ASPNETCORE_ENVIRONMENT environment variable to Development 36 | and restarting the app. 37 |

38 |
39 |
40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.ServerSide/Pages/Error.cshtml.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Mvc; 2 | using Microsoft.AspNetCore.Mvc.RazorPages; 3 | using Microsoft.Extensions.Logging; 4 | using System; 5 | using System.Collections.Generic; 6 | using System.Diagnostics; 7 | using System.Linq; 8 | using System.Threading.Tasks; 9 | 10 | namespace SoloX.BlazorJsonLocalization.Example.ServerSide.Pages 11 | { 12 | [ResponseCache(Duration = 0, Location = ResponseCacheLocation.None, NoStore = true)] 13 | [IgnoreAntiforgeryToken] 14 | public class ErrorModel : PageModel 15 | { 16 | public string RequestId { get; set; } 17 | 18 | public bool ShowRequestId => !string.IsNullOrEmpty(RequestId); 19 | 20 | private readonly ILogger _logger; 21 | 22 | public ErrorModel(ILogger logger) 23 | { 24 | _logger = logger; 25 | } 26 | 27 | public void OnGet() 28 | { 29 | RequestId = Activity.Current?.Id ?? HttpContext.TraceIdentifier; 30 | } 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.ServerSide/Pages/_Host.cshtml: -------------------------------------------------------------------------------- 1 | @page "/" 2 | @namespace SoloX.BlazorJsonLocalization.Example.ServerSide.Pages 3 | @addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers 4 | @{ 5 | Layout = null; 6 | } 7 | 8 | 9 | 10 | 11 | 12 | 13 | SoloX.BlazorJsonLocalization.Example.ServerSide 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | An error has occurred. This application may no longer respond until reloaded. 25 | 26 | 27 | An unhandled exception has occurred. See browser dev tools for details. 28 | 29 | Reload 30 | 🗙 31 |
32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.ServerSide/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.AspNetCore.Hosting; 2 | using Microsoft.Extensions.Configuration; 3 | using Microsoft.Extensions.Hosting; 4 | using Microsoft.Extensions.Logging; 5 | using System; 6 | using System.Collections.Generic; 7 | using System.Linq; 8 | using System.Threading.Tasks; 9 | 10 | namespace SoloX.BlazorJsonLocalization.Example.ServerSide 11 | { 12 | public class Program 13 | { 14 | public static void Main(string[] args) 15 | { 16 | CreateHostBuilder(args).Build().Run(); 17 | } 18 | 19 | public static IHostBuilder CreateHostBuilder(string[] args) => 20 | Host.CreateDefaultBuilder(args) 21 | .ConfigureWebHostDefaults(webBuilder => 22 | { 23 | webBuilder.UseStartup(); 24 | }); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.ServerSide/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:11777", 7 | "sslPort": 44316 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "environmentVariables": { 15 | "ASPNETCORE_ENVIRONMENT": "Development" 16 | } 17 | }, 18 | "SoloX.BlazorJsonLocalization.Example.ServerSide": { 19 | "commandName": "Project", 20 | "dotnetRunMessages": "true", 21 | "launchBrowser": true, 22 | "applicationUrl": "https://localhost:5001;http://localhost:5000", 23 | "environmentVariables": { 24 | "ASPNETCORE_ENVIRONMENT": "Development" 25 | } 26 | } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.ServerSide/Shared/MainLayout.razor: -------------------------------------------------------------------------------- 1 | @using System.Globalization 2 | @using System.Threading 3 | 4 | @inherits LayoutComponentBase 5 | 6 | @inject IStringLocalizer shared 7 | 8 | @inject NavigationManager NavigationManager 9 | 10 |
11 | 12 | @if (reload) 13 | { 14 |
15 | Loading... 16 |
17 | } 18 | else 19 | { 20 | 23 | 24 |
25 |
26 |
27 | 28 |
29 |
30 | 31 |
32 |
33 | @shared["About"] 34 |
35 |
36 | 37 |
38 | @Body 39 |
40 |
41 | } 42 |
43 | 44 | @code 45 | { 46 | private Task SetCultureInfoFr() 47 | { 48 | return SetCultureInfo("fr-FR"); 49 | } 50 | 51 | private Task SetCultureInfoEn() 52 | { 53 | return SetCultureInfo("en-US"); 54 | } 55 | 56 | bool reload = false; 57 | 58 | private Task SetCultureInfo(string culture) 59 | { 60 | var uri = new Uri(NavigationManager.Uri) 61 | .GetComponents(UriComponents.PathAndQuery, UriFormat.Unescaped); 62 | var query = $"?culture={Uri.EscapeDataString(culture)}&" + 63 | $"redirectUri={Uri.EscapeDataString(uri)}"; 64 | 65 | NavigationManager.NavigateTo("/Culture/SetCulture" + query, forceLoad: true); 66 | 67 | return Task.CompletedTask; 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.ServerSide/Shared/MainLayout.razor.css: -------------------------------------------------------------------------------- 1 | .page { 2 | position: relative; 3 | display: flex; 4 | flex-direction: column; 5 | } 6 | 7 | .main { 8 | flex: 1; 9 | } 10 | 11 | .sidebar { 12 | background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%); 13 | } 14 | 15 | .top-row { 16 | background-color: #f7f7f7; 17 | border-bottom: 1px solid #d6d5d5; 18 | justify-content: flex-end; 19 | height: 3.5rem; 20 | display: flex; 21 | align-items: center; 22 | } 23 | 24 | .top-row ::deep a, .top-row .btn-link { 25 | white-space: nowrap; 26 | margin-left: 1.5rem; 27 | } 28 | 29 | .top-row a:first-child { 30 | overflow: hidden; 31 | text-overflow: ellipsis; 32 | } 33 | 34 | @media (max-width: 640.98px) { 35 | .top-row:not(.auth) { 36 | display: none; 37 | } 38 | 39 | .top-row.auth { 40 | justify-content: space-between; 41 | } 42 | 43 | .top-row a, .top-row .btn-link { 44 | margin-left: 0; 45 | } 46 | } 47 | 48 | @media (min-width: 641px) { 49 | .page { 50 | flex-direction: row; 51 | } 52 | 53 | .sidebar { 54 | width: 250px; 55 | height: 100vh; 56 | position: sticky; 57 | top: 0; 58 | } 59 | 60 | .top-row { 61 | position: sticky; 62 | top: 0; 63 | z-index: 1; 64 | } 65 | 66 | .main > div { 67 | padding-left: 2rem !important; 68 | padding-right: 1.5rem !important; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.ServerSide/Shared/NavMenu.razor: -------------------------------------------------------------------------------- 1 |  2 | @inject IStringLocalizer shared 3 | 4 | 10 | 11 |
12 | 34 |
35 | 36 | @code { 37 | private bool collapseNavMenu = true; 38 | 39 | private string NavMenuCssClass => collapseNavMenu ? "collapse" : null; 40 | 41 | private void ToggleNavMenu() 42 | { 43 | collapseNavMenu = !collapseNavMenu; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.ServerSide/Shared/NavMenu.razor.css: -------------------------------------------------------------------------------- 1 | .navbar-toggler { 2 | background-color: rgba(255, 255, 255, 0.1); 3 | } 4 | 5 | .top-row { 6 | height: 3.5rem; 7 | background-color: rgba(0,0,0,0.4); 8 | } 9 | 10 | .navbar-brand { 11 | font-size: 1.1rem; 12 | } 13 | 14 | .oi { 15 | width: 2rem; 16 | font-size: 1.1rem; 17 | vertical-align: text-top; 18 | top: -2px; 19 | } 20 | 21 | .nav-item { 22 | font-size: 0.9rem; 23 | padding-bottom: 0.5rem; 24 | } 25 | 26 | .nav-item:first-of-type { 27 | padding-top: 1rem; 28 | } 29 | 30 | .nav-item:last-of-type { 31 | padding-bottom: 1rem; 32 | } 33 | 34 | .nav-item ::deep a { 35 | color: #d7d7d7; 36 | border-radius: 4px; 37 | height: 3rem; 38 | display: flex; 39 | align-items: center; 40 | line-height: 3rem; 41 | } 42 | 43 | .nav-item ::deep a.active { 44 | background-color: rgba(255,255,255,0.25); 45 | color: white; 46 | } 47 | 48 | .nav-item ::deep a:hover { 49 | background-color: rgba(255,255,255,0.1); 50 | color: white; 51 | } 52 | 53 | @media (min-width: 641px) { 54 | .navbar-toggler { 55 | display: none; 56 | } 57 | 58 | .collapse { 59 | /* Never collapse the sidebar for wide screens */ 60 | display: block; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.ServerSide/SoloX.BlazorJsonLocalization.Example.ServerSide.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net9.0 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.ServerSide/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using System.Net.Http 2 | @using Microsoft.AspNetCore.Authorization 3 | @using Microsoft.AspNetCore.Components.Authorization 4 | @using Microsoft.AspNetCore.Components.Forms 5 | @using Microsoft.AspNetCore.Components.Routing 6 | @using Microsoft.AspNetCore.Components.Web 7 | @using Microsoft.AspNetCore.Components.Web.Virtualization 8 | @using Microsoft.JSInterop 9 | @using SoloX.BlazorJsonLocalization.Example.Components.Embedded 10 | @using SoloX.BlazorJsonLocalization.Example.Components.Embedded.Pages 11 | @using SoloX.BlazorJsonLocalization.Example.Components.StaticAssets 12 | @using SoloX.BlazorJsonLocalization.Example.Components.StaticAssets.Pages 13 | @using SoloX.BlazorJsonLocalization.Example.ServerSide 14 | @using SoloX.BlazorJsonLocalization.Example.ServerSide.Shared 15 | @using Microsoft.Extensions.Localization -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.ServerSide/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "DetailedErrors": true, 3 | "Logging": { 4 | "LogLevel": { 5 | "Default": "Information", 6 | "Microsoft": "Warning", 7 | "Microsoft.Hosting.Lifetime": "Information" 8 | } 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.ServerSide/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft": "Warning", 6 | "Microsoft.Hosting.Lifetime": "Information" 7 | } 8 | }, 9 | "AllowedHosts": "*" 10 | } 11 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.ServerSide/wwwroot/css/open-iconic/ICON-LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Waybury 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.ServerSide/wwwroot/css/open-iconic/font/fonts/open-iconic.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xaviersolau/BlazorJsonLocalization/d1acab63181a492b87441b02459988be6b719c1d/src/examples/SoloX.BlazorJsonLocalization.Example.ServerSide/wwwroot/css/open-iconic/font/fonts/open-iconic.eot -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.ServerSide/wwwroot/css/open-iconic/font/fonts/open-iconic.otf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xaviersolau/BlazorJsonLocalization/d1acab63181a492b87441b02459988be6b719c1d/src/examples/SoloX.BlazorJsonLocalization.Example.ServerSide/wwwroot/css/open-iconic/font/fonts/open-iconic.otf -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.ServerSide/wwwroot/css/open-iconic/font/fonts/open-iconic.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xaviersolau/BlazorJsonLocalization/d1acab63181a492b87441b02459988be6b719c1d/src/examples/SoloX.BlazorJsonLocalization.Example.ServerSide/wwwroot/css/open-iconic/font/fonts/open-iconic.ttf -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.ServerSide/wwwroot/css/open-iconic/font/fonts/open-iconic.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xaviersolau/BlazorJsonLocalization/d1acab63181a492b87441b02459988be6b719c1d/src/examples/SoloX.BlazorJsonLocalization.Example.ServerSide/wwwroot/css/open-iconic/font/fonts/open-iconic.woff -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.ServerSide/wwwroot/css/site.css: -------------------------------------------------------------------------------- 1 | @import url('open-iconic/font/css/open-iconic-bootstrap.min.css'); 2 | 3 | html, body { 4 | font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif; 5 | } 6 | 7 | a, .btn-link { 8 | color: #0366d6; 9 | } 10 | 11 | .btn-primary { 12 | color: #fff; 13 | background-color: #1b6ec2; 14 | border-color: #1861ac; 15 | } 16 | 17 | .content { 18 | padding-top: 1.1rem; 19 | } 20 | 21 | .valid.modified:not([type=checkbox]) { 22 | outline: 1px solid #26b050; 23 | } 24 | 25 | .invalid { 26 | outline: 1px solid red; 27 | } 28 | 29 | .validation-message { 30 | color: red; 31 | } 32 | 33 | #blazor-error-ui { 34 | background: lightyellow; 35 | bottom: 0; 36 | box-shadow: 0 -1px 2px rgba(0, 0, 0, 0.2); 37 | display: none; 38 | left: 0; 39 | padding: 0.6rem 1.25rem 0.7rem 1.25rem; 40 | position: fixed; 41 | width: 100%; 42 | z-index: 1000; 43 | } 44 | 45 | #blazor-error-ui .dismiss { 46 | cursor: pointer; 47 | position: absolute; 48 | right: 0.75rem; 49 | top: 0.5rem; 50 | } 51 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.ServerSide/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xaviersolau/BlazorJsonLocalization/d1acab63181a492b87441b02459988be6b719c1d/src/examples/SoloX.BlazorJsonLocalization.Example.ServerSide/wwwroot/favicon.ico -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.Wasm/App.razor: -------------------------------------------------------------------------------- 1 | 8 | 9 | 10 | 11 | 12 | 13 | Not found 14 | 15 |

Sorry, there's nothing at this address.

16 |
17 |
18 |
19 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.Wasm/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:52779", 7 | "sslPort": 44347 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", 15 | "environmentVariables": { 16 | "ASPNETCORE_ENVIRONMENT": "Development" 17 | } 18 | }, 19 | "SoloX.BlazorJsonLocalization.Example.Wasm": { 20 | "commandName": "Project", 21 | "dotnetRunMessages": "true", 22 | "launchBrowser": true, 23 | "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", 24 | "applicationUrl": "https://localhost:5001;http://localhost:5000", 25 | "environmentVariables": { 26 | "ASPNETCORE_ENVIRONMENT": "Development" 27 | } 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.Wasm/Shared/MainLayout.razor: -------------------------------------------------------------------------------- 1 | @using System.Globalization 2 | 3 | @inherits LayoutComponentBase 4 | 5 | @inject IStringLocalizer shared 6 | 7 |
8 | 9 | @if (reload) 10 | { 11 |
12 | Loading... 13 |
14 | } 15 | else 16 | { 17 | 20 | 21 |
22 |
23 |
24 | 25 |
26 |
27 | 28 |
29 |
30 | @shared["About"] 31 |
32 |
33 |
34 | @Body 35 |
36 |
37 | } 38 | 39 |
40 | 41 | @inject Blazored.LocalStorage.ISyncLocalStorageService localStorage 42 | 43 | @code 44 | { 45 | private Task SetCultureInfoFr() 46 | { 47 | return SetCultureInfo("fr-FR"); 48 | } 49 | 50 | private Task SetCultureInfoEn() 51 | { 52 | return SetCultureInfo("en-US"); 53 | } 54 | 55 | bool reload = false; 56 | 57 | private async Task SetCultureInfo(string name) 58 | { 59 | var ci = CultureInfo.GetCultureInfo(name); 60 | 61 | CultureInfo.DefaultThreadCurrentUICulture = ci; 62 | 63 | localStorage.SetItemAsString(Program.LanguageKey, name); 64 | 65 | reload = true; 66 | StateHasChanged(); 67 | 68 | await Task.Yield(); 69 | 70 | reload = false; 71 | StateHasChanged(); 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.Wasm/Shared/MainLayout.razor.css: -------------------------------------------------------------------------------- 1 | .page { 2 | position: relative; 3 | display: flex; 4 | flex-direction: column; 5 | } 6 | 7 | .main { 8 | flex: 1; 9 | } 10 | 11 | .sidebar { 12 | background-image: linear-gradient(180deg, rgb(5, 39, 103) 0%, #3a0647 70%); 13 | } 14 | 15 | .top-row { 16 | background-color: #f7f7f7; 17 | border-bottom: 1px solid #d6d5d5; 18 | justify-content: flex-end; 19 | height: 3.5rem; 20 | display: flex; 21 | align-items: center; 22 | } 23 | 24 | .top-row ::deep a, .top-row .btn-link { 25 | white-space: nowrap; 26 | margin-left: 1.5rem; 27 | } 28 | 29 | .top-row a:first-child { 30 | overflow: hidden; 31 | text-overflow: ellipsis; 32 | } 33 | 34 | @media (max-width: 640.98px) { 35 | .top-row:not(.auth) { 36 | display: none; 37 | } 38 | 39 | .top-row.auth { 40 | justify-content: space-between; 41 | } 42 | 43 | .top-row a, .top-row .btn-link { 44 | margin-left: 0; 45 | } 46 | } 47 | 48 | @media (min-width: 641px) { 49 | .page { 50 | flex-direction: row; 51 | } 52 | 53 | .sidebar { 54 | width: 250px; 55 | height: 100vh; 56 | position: sticky; 57 | top: 0; 58 | } 59 | 60 | .top-row { 61 | position: sticky; 62 | top: 0; 63 | z-index: 1; 64 | } 65 | 66 | .main > div { 67 | padding-left: 2rem !important; 68 | padding-right: 1.5rem !important; 69 | } 70 | } 71 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.Wasm/Shared/NavMenu.razor: -------------------------------------------------------------------------------- 1 | @inject IStringLocalizer shared 2 | 3 | 9 | 10 |
11 | 33 |
34 | 35 | @code { 36 | private bool collapseNavMenu = true; 37 | 38 | private string NavMenuCssClass => collapseNavMenu ? "collapse" : null; 39 | 40 | private void ToggleNavMenu() 41 | { 42 | collapseNavMenu = !collapseNavMenu; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.Wasm/Shared/NavMenu.razor.css: -------------------------------------------------------------------------------- 1 | .navbar-toggler { 2 | background-color: rgba(255, 255, 255, 0.1); 3 | } 4 | 5 | .top-row { 6 | height: 3.5rem; 7 | background-color: rgba(0,0,0,0.4); 8 | } 9 | 10 | .navbar-brand { 11 | font-size: 1.1rem; 12 | } 13 | 14 | .oi { 15 | width: 2rem; 16 | font-size: 1.1rem; 17 | vertical-align: text-top; 18 | top: -2px; 19 | } 20 | 21 | .nav-item { 22 | font-size: 0.9rem; 23 | padding-bottom: 0.5rem; 24 | } 25 | 26 | .nav-item:first-of-type { 27 | padding-top: 1rem; 28 | } 29 | 30 | .nav-item:last-of-type { 31 | padding-bottom: 1rem; 32 | } 33 | 34 | .nav-item ::deep a { 35 | color: #d7d7d7; 36 | border-radius: 4px; 37 | height: 3rem; 38 | display: flex; 39 | align-items: center; 40 | line-height: 3rem; 41 | } 42 | 43 | .nav-item ::deep a.active { 44 | background-color: rgba(255,255,255,0.25); 45 | color: white; 46 | } 47 | 48 | .nav-item ::deep a:hover { 49 | background-color: rgba(255,255,255,0.1); 50 | color: white; 51 | } 52 | 53 | @media (min-width: 641px) { 54 | .navbar-toggler { 55 | display: none; 56 | } 57 | 58 | .collapse { 59 | /* Never collapse the sidebar for wide screens */ 60 | display: block; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.Wasm/SoloX.BlazorJsonLocalization.Example.Wasm.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net9.0 5 | true 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.Wasm/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using System.Net.Http 2 | @using System.Net.Http.Json 3 | @using Microsoft.AspNetCore.Components.Forms 4 | @using Microsoft.AspNetCore.Components.Routing 5 | @using Microsoft.AspNetCore.Components.Web 6 | @using Microsoft.AspNetCore.Components.Web.Virtualization 7 | @using Microsoft.AspNetCore.Components.WebAssembly.Http 8 | @using Microsoft.JSInterop 9 | @using SoloX.BlazorJsonLocalization.Example.Components.Embedded 10 | @using SoloX.BlazorJsonLocalization.Example.Components.Embedded.Pages 11 | @using SoloX.BlazorJsonLocalization.Example.Components.StaticAssets 12 | @using SoloX.BlazorJsonLocalization.Example.Components.StaticAssets.Pages 13 | @using SoloX.BlazorJsonLocalization.Example.Wasm 14 | @using SoloX.BlazorJsonLocalization.Example.Wasm.Shared 15 | @using Microsoft.Extensions.Localization 16 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.Wasm/wwwroot/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xaviersolau/BlazorJsonLocalization/d1acab63181a492b87441b02459988be6b719c1d/src/examples/SoloX.BlazorJsonLocalization.Example.Wasm/wwwroot/favicon.ico -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.Wasm/wwwroot/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | SoloX.BlazorJsonLocalization.Example.Wasm 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 |
22 |
23 | 24 |
25 | An unhandled error has occurred. 26 | Reload 27 | 🗙 28 |
29 | 30 | 31 | 32 | 33 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.WebApp/SoloX.BlazorJsonLocalization.Example.WebApp.Client/Pages/Counter.razor: -------------------------------------------------------------------------------- 1 | @page "/counter" 2 | 3 | @rendermode InteractiveAuto 4 | 5 | @using Microsoft.Extensions.Localization 6 | 7 | @inject IStringLocalizer Localizer 8 | 9 |

@Localizer["KeyInFallback"]

10 | 11 | @Localizer["Counter"] 12 | 13 |

@Localizer["Counter"]

14 | 15 |

@Localizer["Current count", currentCount]

16 | 17 | 18 | 19 | @code { 20 | private int currentCount = 0; 21 | 22 | private void IncrementCount() 23 | { 24 | currentCount++; 25 | } 26 | 27 | protected override async Task OnInitializedAsync() 28 | { 29 | await Localizer.LoadAsync(); 30 | 31 | await base.OnInitializedAsync(); 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.WebApp/SoloX.BlazorJsonLocalization.Example.WebApp.Client/Program.cs: -------------------------------------------------------------------------------- 1 | 2 | using Microsoft.AspNetCore.Components.WebAssembly.Hosting; 3 | using SoloX.BlazorJsonLocalization.Example.WebApp.Client; 4 | using SoloX.BlazorJsonLocalization; 5 | 6 | var builder = WebAssemblyHostBuilder.CreateDefault(args); 7 | 8 | builder.Services.AddHttpClient( 9 | "Host", 10 | (sp, c) => 11 | { 12 | var hostEnv = sp.GetRequiredService(); 13 | c.BaseAddress = new Uri(hostEnv.BaseAddress); 14 | }); 15 | 16 | //builder.Services.AddScoped(sp => 17 | // new HttpClient 18 | // { 19 | // BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) 20 | // }); 21 | 22 | builder.Services.AddJsonLocalization(b => 23 | { 24 | b 25 | #if DEBUG 26 | .EnableLogger() 27 | #endif 28 | .AddFallback("Fallback", typeof(_Imports).Assembly) 29 | .UseHttpClientJson(options => 30 | { 31 | options.ResourcesPath = "Resources"; 32 | options.NamingPolicy = HttpHostedJsonNamingPolicy; 33 | options.ApplicationAssembly = typeof(_Imports).Assembly; 34 | options.HttpClientBuilder = sp => 35 | { 36 | var httpClientFactory = sp.GetRequiredService(); 37 | return httpClientFactory.CreateClient("Host"); 38 | }; 39 | }); 40 | }); 41 | 42 | await builder.Build().RunAsync(); 43 | 44 | 45 | static Uri HttpHostedJsonNamingPolicy(string basePath, string cultureName) 46 | { 47 | return string.IsNullOrEmpty(cultureName) 48 | ? new Uri($"{basePath}.json?v=1.0.0", UriKind.Relative) 49 | : new Uri($"{basePath}.{cultureName}.json?v=1.0.0", UriKind.Relative); 50 | } -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.WebApp/SoloX.BlazorJsonLocalization.Example.WebApp.Client/SoloX.BlazorJsonLocalization.Example.WebApp.Client.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net9.0 5 | enable 6 | enable 7 | true 8 | Default 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | true 23 | PreserveNewest 24 | 25 | 26 | true 27 | PreserveNewest 28 | 29 | 30 | true 31 | PreserveNewest 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.WebApp/SoloX.BlazorJsonLocalization.Example.WebApp.Client/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using System.Net.Http 2 | @using System.Net.Http.Json 3 | @using Microsoft.AspNetCore.Components.Forms 4 | @using Microsoft.AspNetCore.Components.Routing 5 | @using Microsoft.AspNetCore.Components.Web 6 | @using static Microsoft.AspNetCore.Components.Web.RenderMode 7 | @using Microsoft.AspNetCore.Components.Web.Virtualization 8 | @using Microsoft.JSInterop 9 | @using SoloX.BlazorJsonLocalization.Example.WebApp.Client 10 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.WebApp/SoloX.BlazorJsonLocalization.Example.WebApp.Client/wwwroot/Resources/Fallback.en.json: -------------------------------------------------------------------------------- 1 | { 2 | "KeyInFallback": "Fallback from EN file" 3 | } 4 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.WebApp/SoloX.BlazorJsonLocalization.Example.WebApp.Client/wwwroot/Resources/Fallback.fr.json: -------------------------------------------------------------------------------- 1 | { 2 | "KeyInFallback": "Fallback depuis le fichier FR" 3 | } -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.WebApp/SoloX.BlazorJsonLocalization.Example.WebApp.Client/wwwroot/Resources/Fallback.json: -------------------------------------------------------------------------------- 1 | { 2 | "KeyInFallback": "Fallback from root file" 3 | } 4 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.WebApp/SoloX.BlazorJsonLocalization.Example.WebApp.Client/wwwroot/Resources/Pages/Counter.en.json: -------------------------------------------------------------------------------- 1 | { 2 | "Counter": "Counter", 3 | "Current count": "Current count : {0}.", 4 | "Click": "Click me" 5 | } 6 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.WebApp/SoloX.BlazorJsonLocalization.Example.WebApp.Client/wwwroot/Resources/Pages/Counter.fr.json: -------------------------------------------------------------------------------- 1 | { 2 | "Counter": "Compteur", 3 | "Current count": "Compte courant : {0}.", 4 | "Click": "Cliquez ici" 5 | } -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.WebApp/SoloX.BlazorJsonLocalization.Example.WebApp.Client/wwwroot/Resources/Pages/Counter.json: -------------------------------------------------------------------------------- 1 | { 2 | "Counter": "Counter", 3 | "Current count": "Current count : {0}.", 4 | "Click": "Click me" 5 | } 6 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.WebApp/SoloX.BlazorJsonLocalization.Example.WebApp.Client/wwwroot/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.WebApp/SoloX.BlazorJsonLocalization.Example.WebApp.Client/wwwroot/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.WebApp/SoloX.BlazorJsonLocalization.Example.WebApp/Components/App.razor: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.WebApp/SoloX.BlazorJsonLocalization.Example.WebApp/Components/Layout/MainLayout.razor: -------------------------------------------------------------------------------- 1 | @inherits LayoutComponentBase 2 | 3 |
4 | 7 | 8 |
9 |
10 | About 11 |
12 | 13 |
14 | @Body 15 |
16 |
17 |
18 | 19 |
20 | An unhandled error has occurred. 21 | Reload 22 | 🗙 23 |
24 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.WebApp/SoloX.BlazorJsonLocalization.Example.WebApp/Components/Layout/NavMenu.razor: -------------------------------------------------------------------------------- 1 |  6 | 7 | 8 | 9 | 30 | 31 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.WebApp/SoloX.BlazorJsonLocalization.Example.WebApp/Components/Pages/Error.razor: -------------------------------------------------------------------------------- 1 | @page "/Error" 2 | @using System.Diagnostics 3 | 4 | Error 5 | 6 |

Error.

7 |

An error occurred while processing your request.

8 | 9 | @if (ShowRequestId) 10 | { 11 |

12 | Request ID: @RequestId 13 |

14 | } 15 | 16 |

Development Mode

17 |

18 | Swapping to Development environment will display more detailed information about the error that occurred. 19 |

20 |

21 | The Development environment shouldn't be enabled for deployed applications. 22 | It can result in displaying sensitive information from exceptions to end users. 23 | For local debugging, enable the Development environment by setting the ASPNETCORE_ENVIRONMENT environment variable to Development 24 | and restarting the app. 25 |

26 | 27 | @code{ 28 | [CascadingParameter] 29 | private HttpContext? HttpContext { get; set; } 30 | 31 | private string? RequestId { get; set; } 32 | private bool ShowRequestId => !string.IsNullOrEmpty(RequestId); 33 | 34 | protected override void OnInitialized() => 35 | RequestId = Activity.Current?.Id ?? HttpContext?.TraceIdentifier; 36 | } 37 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.WebApp/SoloX.BlazorJsonLocalization.Example.WebApp/Components/Pages/Home.razor: -------------------------------------------------------------------------------- 1 | @page "/" 2 | @rendermode InteractiveServer 3 | 4 | @using Microsoft.Extensions.Localization 5 | 6 | @inject IStringLocalizer Localizer 7 | 8 | @Localizer["Home"] 9 | 10 |

@Localizer["Hello"]

11 | 12 | @Localizer["Welcome"] 13 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.WebApp/SoloX.BlazorJsonLocalization.Example.WebApp/Components/Pages/Weather.razor: -------------------------------------------------------------------------------- 1 | @page "/weather" 2 | @attribute [StreamRendering] 3 | 4 | Weather 5 | 6 |

Weather

7 | 8 |

This component demonstrates showing data.

9 | 10 | @if (forecasts == null) 11 | { 12 |

Loading...

13 | } 14 | else 15 | { 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | @foreach (var forecast in forecasts) 27 | { 28 | 29 | 30 | 31 | 32 | 33 | 34 | } 35 | 36 |
DateTemp. (C)Temp. (F)Summary
@forecast.Date.ToShortDateString()@forecast.TemperatureC@forecast.TemperatureF@forecast.Summary
37 | } 38 | 39 | @code { 40 | private WeatherForecast[]? forecasts; 41 | 42 | protected override async Task OnInitializedAsync() 43 | { 44 | // Simulate asynchronous loading to demonstrate streaming rendering 45 | await Task.Delay(500); 46 | 47 | var startDate = DateOnly.FromDateTime(DateTime.Now); 48 | var summaries = new[] { "Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching" }; 49 | forecasts = Enumerable.Range(1, 5).Select(index => new WeatherForecast 50 | { 51 | Date = startDate.AddDays(index), 52 | TemperatureC = Random.Shared.Next(-20, 55), 53 | Summary = summaries[Random.Shared.Next(summaries.Length)] 54 | }).ToArray(); 55 | } 56 | 57 | private class WeatherForecast 58 | { 59 | public DateOnly Date { get; set; } 60 | public int TemperatureC { get; set; } 61 | public string? Summary { get; set; } 62 | public int TemperatureF => 32 + (int)(TemperatureC / 0.5556); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.WebApp/SoloX.BlazorJsonLocalization.Example.WebApp/Components/Routes.razor: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.WebApp/SoloX.BlazorJsonLocalization.Example.WebApp/Components/_Imports.razor: -------------------------------------------------------------------------------- 1 | @using System.Net.Http 2 | @using System.Net.Http.Json 3 | @using Microsoft.AspNetCore.Components.Forms 4 | @using Microsoft.AspNetCore.Components.Routing 5 | @using Microsoft.AspNetCore.Components.Web 6 | @using static Microsoft.AspNetCore.Components.Web.RenderMode 7 | @using Microsoft.AspNetCore.Components.Web.Virtualization 8 | @using Microsoft.JSInterop 9 | @using SoloX.BlazorJsonLocalization.Example.WebApp 10 | @using SoloX.BlazorJsonLocalization.Example.WebApp.Client 11 | @using SoloX.BlazorJsonLocalization.Example.WebApp.Components 12 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.WebApp/SoloX.BlazorJsonLocalization.Example.WebApp/Program.cs: -------------------------------------------------------------------------------- 1 | using SoloX.BlazorJsonLocalization.Example.WebApp.Components; 2 | using SoloX.BlazorJsonLocalization.ServerSide; 3 | 4 | var builder = WebApplication.CreateBuilder(args); 5 | 6 | // Add services to the container. 7 | builder.Services.AddRazorComponents() 8 | .AddInteractiveServerComponents() 9 | .AddInteractiveWebAssemblyComponents(); 10 | 11 | builder.Services.AddServerSideJsonLocalization(builder => 12 | { 13 | builder 14 | #if DEBUG 15 | .EnableLogger() 16 | #endif 17 | .AddFallback("Fallback", typeof(SoloX.BlazorJsonLocalization.Example.WebApp.Client._Imports).Assembly) 18 | .UseHttpHostedJson(options => 19 | { 20 | options.ResourcesPath = "Resources"; 21 | options.ApplicationAssemblies = [typeof(_Imports).Assembly, typeof(SoloX.BlazorJsonLocalization.Example.WebApp.Client._Imports).Assembly]; 22 | }); 23 | }); 24 | 25 | var app = builder.Build(); 26 | 27 | // Configure the HTTP request pipeline. 28 | if (app.Environment.IsDevelopment()) 29 | { 30 | app.UseWebAssemblyDebugging(); 31 | } 32 | else 33 | { 34 | app.UseExceptionHandler("/Error", createScopeForErrors: true); 35 | // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts. 36 | app.UseHsts(); 37 | } 38 | 39 | app.UseHttpsRedirection(); 40 | 41 | app.UseStaticFiles(); 42 | app.UseAntiforgery(); 43 | 44 | app.MapRazorComponents() 45 | .AddInteractiveServerRenderMode() 46 | .AddInteractiveWebAssemblyRenderMode() 47 | .AddAdditionalAssemblies(typeof(SoloX.BlazorJsonLocalization.Example.WebApp.Client._Imports).Assembly); 48 | 49 | app.Run(); 50 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.WebApp/SoloX.BlazorJsonLocalization.Example.WebApp/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "$schema": "http://json.schemastore.org/launchsettings.json", 3 | "iisSettings": { 4 | "windowsAuthentication": false, 5 | "anonymousAuthentication": true, 6 | "iisExpress": { 7 | "applicationUrl": "http://localhost:43772", 8 | "sslPort": 44343 9 | } 10 | }, 11 | "profiles": { 12 | "http": { 13 | "commandName": "Project", 14 | "dotnetRunMessages": true, 15 | "launchBrowser": true, 16 | "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", 17 | "applicationUrl": "http://localhost:5084", 18 | "environmentVariables": { 19 | "ASPNETCORE_ENVIRONMENT": "Development" 20 | } 21 | }, 22 | "https": { 23 | "commandName": "Project", 24 | "dotnetRunMessages": true, 25 | "launchBrowser": true, 26 | "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", 27 | "applicationUrl": "https://localhost:7117;http://localhost:5084", 28 | "environmentVariables": { 29 | "ASPNETCORE_ENVIRONMENT": "Development" 30 | } 31 | }, 32 | "IIS Express": { 33 | "commandName": "IISExpress", 34 | "launchBrowser": true, 35 | "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}", 36 | "environmentVariables": { 37 | "ASPNETCORE_ENVIRONMENT": "Development" 38 | } 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.WebApp/SoloX.BlazorJsonLocalization.Example.WebApp/SoloX.BlazorJsonLocalization.Example.WebApp.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | net9.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.WebApp/SoloX.BlazorJsonLocalization.Example.WebApp/appsettings.Development.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.WebApp/SoloX.BlazorJsonLocalization.Example.WebApp/appsettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "Logging": { 3 | "LogLevel": { 4 | "Default": "Information", 5 | "Microsoft.AspNetCore": "Warning" 6 | } 7 | }, 8 | "AllowedHosts": "*" 9 | } 10 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.WebApp/SoloX.BlazorJsonLocalization.Example.WebApp/wwwroot/Resources/Components/Pages/Home.en.json: -------------------------------------------------------------------------------- 1 | { 2 | "Home": "Home", 3 | "Hello": "Hello, world!", 4 | "Welcome": "Welcome to your new app." 5 | } 6 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.WebApp/SoloX.BlazorJsonLocalization.Example.WebApp/wwwroot/Resources/Components/Pages/Home.fr.json: -------------------------------------------------------------------------------- 1 | { 2 | "Home": "Accueil", 3 | "Hello": "Bonjour, tout monde!", 4 | "Welcome": "Bienvenue dans votre nouvelle application." 5 | } -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.WebApp/SoloX.BlazorJsonLocalization.Example.WebApp/wwwroot/Resources/Components/Pages/Home.json: -------------------------------------------------------------------------------- 1 | { 2 | "Home": "Home", 3 | "Hello": "Hello, world!", 4 | "Welcome": "Welcome to your new app." 5 | } 6 | -------------------------------------------------------------------------------- /src/examples/SoloX.BlazorJsonLocalization.Example.WebApp/SoloX.BlazorJsonLocalization.Example.WebApp/wwwroot/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/xaviersolau/BlazorJsonLocalization/d1acab63181a492b87441b02459988be6b719c1d/src/examples/SoloX.BlazorJsonLocalization.Example.WebApp/SoloX.BlazorJsonLocalization.Example.WebApp/wwwroot/favicon.png -------------------------------------------------------------------------------- /src/libs/SoloX.BlazorJsonLocalization.Attributes/.gitignore: -------------------------------------------------------------------------------- 1 | SoloX.BlazorJsonLocalization.Attributes.xml 2 | /.editorconfig 3 | -------------------------------------------------------------------------------- /src/libs/SoloX.BlazorJsonLocalization.Attributes/LocalizerAttribute.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using System; 10 | 11 | namespace SoloX.BlazorJsonLocalization.Attributes 12 | { 13 | /// 14 | /// Localizer attribute used for localization helper and data files. 15 | /// 16 | [AttributeUsage(AttributeTargets.Interface)] 17 | public sealed class LocalizerAttribute : Attribute 18 | { 19 | /// 20 | /// Setup attribute with target path for Json files and the language list of files to generate. 21 | /// 22 | /// Target path where to generate the Json files. 23 | /// The language list of files to generate 24 | public LocalizerAttribute(string path, string[] languages) 25 | { 26 | Path = path; 27 | Languages = languages; 28 | } 29 | 30 | /// 31 | /// Languages to generate. 32 | /// 33 | public string[] Languages { get; } 34 | 35 | /// 36 | /// Path where to generate Json files. 37 | /// 38 | public string Path { get; } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/libs/SoloX.BlazorJsonLocalization.Attributes/SoloX.BlazorJsonLocalization.Attributes.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | netstandard2.0 7 | latest 8 | 9 | true 10 | 11 | 12 | 13 | 14 | all 15 | runtime; build; native; contentfiles; analyzers; buildtransitive 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /src/libs/SoloX.BlazorJsonLocalization.Attributes/SubLocalizerAttribute.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using System; 10 | 11 | namespace SoloX.BlazorJsonLocalization.Attributes 12 | { 13 | /// 14 | /// Sub-localizer attribute. 15 | /// 16 | [AttributeUsage(AttributeTargets.Interface)] 17 | public sealed class SubLocalizerAttribute : Attribute 18 | { 19 | /// 20 | /// Setup attribute. (no parameters) 21 | /// 22 | public SubLocalizerAttribute() 23 | { 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/libs/SoloX.BlazorJsonLocalization.Attributes/TranslateArgAttribute.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using System; 10 | 11 | namespace SoloX.BlazorJsonLocalization.Attributes 12 | { 13 | /// 14 | /// Translate attribute to define translation from code. 15 | /// 16 | [AttributeUsage(AttributeTargets.Property)] 17 | public sealed class TranslateArgAttribute : Attribute 18 | { 19 | /// 20 | /// Setup translation attribute. 21 | /// 22 | public TranslateArgAttribute() 23 | { 24 | Translation = string.Empty; 25 | } 26 | 27 | /// 28 | /// Setup translation attribute. 29 | /// 30 | /// Translation to use by default. 31 | public TranslateArgAttribute(string translation) 32 | { 33 | Translation = translation; 34 | } 35 | 36 | /// 37 | /// Translation to use. 38 | /// 39 | public string Translation { get; } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/libs/SoloX.BlazorJsonLocalization.Attributes/TranslateAttribute.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using System; 10 | 11 | namespace SoloX.BlazorJsonLocalization.Attributes 12 | { 13 | /// 14 | /// Translate attribute to define translation from code. 15 | /// 16 | [AttributeUsage(AttributeTargets.Property | AttributeTargets.Method)] 17 | public sealed class TranslateAttribute : Attribute 18 | { 19 | /// 20 | /// Setup translation attribute. 21 | /// 22 | /// Translation to use. 23 | public TranslateAttribute(string translation) 24 | { 25 | Translation = translation; 26 | } 27 | 28 | /// 29 | /// Translation to use. 30 | /// 31 | public string Translation { get; } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/libs/SoloX.BlazorJsonLocalization.Attributes/TranslateSubAttribute.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using System; 10 | 11 | namespace SoloX.BlazorJsonLocalization.Attributes 12 | { 13 | /// 14 | /// Translate attribute to define translation from code. 15 | /// 16 | [AttributeUsage(AttributeTargets.Property, AllowMultiple = true)] 17 | public sealed class TranslateSubAttribute : Attribute 18 | { 19 | /// 20 | /// Setup translation attribute. 21 | /// 22 | /// Translate argument name. 23 | /// Translation to use. 24 | public TranslateSubAttribute(string argumentName, string translation) 25 | { 26 | Translation = translation; 27 | ArgumentName = argumentName; 28 | } 29 | 30 | /// 31 | /// Sub-property path. 32 | /// 33 | public string ArgumentName { get; } 34 | 35 | /// 36 | /// Translation to use. 37 | /// 38 | public string Translation { get; } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/libs/SoloX.BlazorJsonLocalization.ServerSide/.gitignore: -------------------------------------------------------------------------------- 1 | SoloX.BlazorJsonLocalization.ServerSide.xml 2 | /.editorconfig 3 | -------------------------------------------------------------------------------- /src/libs/SoloX.BlazorJsonLocalization.ServerSide/JsonLocalizationOptionsBuilderExtensions.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using System; 10 | 11 | namespace SoloX.BlazorJsonLocalization.ServerSide 12 | { 13 | /// 14 | /// Extension methods to setup Http hosted Json file support. 15 | /// 16 | public static class JsonLocalizationOptionsBuilderExtensions 17 | { 18 | /// 19 | /// Setup default Http hosted Json support. 20 | /// 21 | /// The builder to setup. 22 | /// The given builder updated with the Json Http hosted options. 23 | public static JsonLocalizationOptionsBuilder UseHttpHostedJson( 24 | this JsonLocalizationOptionsBuilder builder) 25 | => Http.JsonLocalizationOptionsBuilderExtensions.UseHttpHostedJson(builder); 26 | 27 | /// 28 | /// Setup Http hosted Json support with the given setup action. 29 | /// 30 | /// The builder to setup. 31 | /// The setup action. 32 | /// The given builder updated with the Json http hosted options. 33 | public static JsonLocalizationOptionsBuilder UseHttpHostedJson( 34 | this JsonLocalizationOptionsBuilder builder, 35 | Action? setup) 36 | => Http.JsonLocalizationOptionsBuilderExtensions.UseHttpHostedJson(builder, setup); 37 | } 38 | } -------------------------------------------------------------------------------- /src/libs/SoloX.BlazorJsonLocalization.ServerSide/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "iisSettings": { 3 | "windowsAuthentication": false, 4 | "anonymousAuthentication": true, 5 | "iisExpress": { 6 | "applicationUrl": "http://localhost:56651/", 7 | "sslPort": 44341 8 | } 9 | }, 10 | "profiles": { 11 | "IIS Express": { 12 | "commandName": "IISExpress", 13 | "launchBrowser": true, 14 | "environmentVariables": { 15 | "ASPNETCORE_ENVIRONMENT": "Development" 16 | } 17 | }, 18 | "SoloX.BlazorJsonLocalization.ServerSide": { 19 | "commandName": "Project", 20 | "launchBrowser": true, 21 | "environmentVariables": { 22 | "ASPNETCORE_ENVIRONMENT": "Development" 23 | }, 24 | "applicationUrl": "https://localhost:5001;http://localhost:5000" 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /src/libs/SoloX.BlazorJsonLocalization.ServerSide/ServiceCollectionExtensions.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using Microsoft.Extensions.DependencyInjection; 10 | using SoloX.BlazorJsonLocalization.ServerSide.Services.Impl; 11 | using SoloX.BlazorJsonLocalization.Services; 12 | using System; 13 | 14 | namespace SoloX.BlazorJsonLocalization.ServerSide 15 | { 16 | /// 17 | /// Extension methods to setup the server side Json localization. 18 | /// 19 | public static class ServiceCollectionExtensions 20 | { 21 | /// 22 | /// Add server side Json localization services. 23 | /// 24 | /// The service collection to setup. 25 | /// The action delegate to fine tune the Json localizer behavior 26 | /// (Use embedded Json resource files if null). 27 | /// The given service collection updated with the Json localization services. 28 | public static IServiceCollection AddServerSideJsonLocalization( 29 | this IServiceCollection services, 30 | Action setupAction) 31 | { 32 | services 33 | .AddJsonLocalization(setupAction, ServiceLifetime.Singleton); 34 | 35 | services.AddSingleton< 36 | IJsonLocalizationExtensionService, 37 | HttpHostedJsonLocalizationExtensionService>(); 38 | 39 | return services; 40 | } 41 | } 42 | } -------------------------------------------------------------------------------- /src/libs/SoloX.BlazorJsonLocalization.ServerSide/SoloX.BlazorJsonLocalization.ServerSide.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | net9.0;net8.0;net7.0;net6.0;net5.0;netcoreapp3.1 7 | latest 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | all 39 | runtime; build; native; contentfiles; analyzers; buildtransitive 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /src/libs/SoloX.BlazorJsonLocalization.WebAssembly/.gitignore: -------------------------------------------------------------------------------- 1 | SoloX.BlazorJsonLocalization.WebAssembly.xml 2 | /.editorconfig 3 | -------------------------------------------------------------------------------- /src/libs/SoloX.BlazorJsonLocalization.WebAssembly/JsonLocalizationOptionsBuilderExtensions.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using System; 10 | 11 | namespace SoloX.BlazorJsonLocalization.WebAssembly 12 | { 13 | /// 14 | /// Extension methods to setup Http hosted Json file support. 15 | /// 16 | public static class JsonLocalizationOptionsBuilderExtensions 17 | { 18 | /// 19 | /// Setup default Http hosted Json support. 20 | /// 21 | /// The builder to setup. 22 | /// The given builder updated with the Json Http hosted options. 23 | [Obsolete("UseHttpHostedJson from the WebAssembly project is now obsolete. Use UseHttpClientJson instead (using SoloX.BlazorJsonLocalization).")] 24 | public static JsonLocalizationOptionsBuilder UseHttpHostedJson( 25 | this JsonLocalizationOptionsBuilder builder) 26 | => SoloX.BlazorJsonLocalization.JsonLocalizationOptionsBuilderExtensions.UseHttpClientJson(builder); 27 | 28 | /// 29 | /// Setup Http hosted Json support with the given setup action. 30 | /// 31 | /// The builder to setup. 32 | /// The setup action. 33 | /// The given builder updated with the Json http hosted options. 34 | [Obsolete("UseHttpHostedJson from the WebAssembly project is now obsolete. Use UseHttpClientJson instead (using SoloX.BlazorJsonLocalization).")] 35 | public static JsonLocalizationOptionsBuilder UseHttpHostedJson( 36 | this JsonLocalizationOptionsBuilder builder, 37 | Action? setup) 38 | => SoloX.BlazorJsonLocalization.JsonLocalizationOptionsBuilderExtensions.UseHttpClientJson(builder, setup); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/libs/SoloX.BlazorJsonLocalization.WebAssembly/ServiceCollectionExtensions.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using Microsoft.Extensions.DependencyInjection; 10 | using System; 11 | 12 | namespace SoloX.BlazorJsonLocalization.WebAssembly 13 | { 14 | /// 15 | /// Extension methods to setup the WebAssembly Json localization. 16 | /// 17 | public static class ServiceCollectionExtensions 18 | { 19 | /// 20 | /// Add WebAssembly Json localization services. 21 | /// 22 | /// The service collection to setup. 23 | /// The action delegate to fine tune the Json localizer behavior 24 | /// (Use embedded Json resource files if null). 25 | /// The given service collection updated with the Json localization services. 26 | [Obsolete("AddWebAssemblyJsonLocalization is now obsolete. You can use directly AddJsonLocalization (using SoloX.BlazorJsonLocalization).")] 27 | public static IServiceCollection AddWebAssemblyJsonLocalization(this IServiceCollection services, Action setupAction) 28 | { 29 | services 30 | .AddJsonLocalization(setupAction, ServiceLifetime.Scoped); 31 | 32 | return services; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/libs/SoloX.BlazorJsonLocalization.WebAssembly/SoloX.BlazorJsonLocalization.WebAssembly.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | net9.0;net8.0;net7.0;net6.0;net5.0 7 | latest 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | all 30 | runtime; build; native; contentfiles; analyzers; buildtransitive 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | -------------------------------------------------------------------------------- /src/libs/SoloX.BlazorJsonLocalization/.gitignore: -------------------------------------------------------------------------------- 1 | SoloX.BlazorJsonLocalization.xml 2 | /.editorconfig 3 | -------------------------------------------------------------------------------- /src/libs/SoloX.BlazorJsonLocalization/AssemblyProperties.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using System.Runtime.CompilerServices; 10 | 11 | [assembly: InternalsVisibleTo("SoloX.BlazorJsonLocalization.UTests")] 12 | 13 | -------------------------------------------------------------------------------- /src/libs/SoloX.BlazorJsonLocalization/Core/AExtensionOptions.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using System; 10 | using System.Collections.Generic; 11 | using System.Reflection; 12 | 13 | namespace SoloX.BlazorJsonLocalization.Core 14 | { 15 | /// 16 | /// Base class for extension options. 17 | /// 18 | public abstract class AExtensionOptions 19 | { 20 | /// 21 | /// Assemblies to match when the extension is loading resources. The extension won't apply 22 | /// on other assemblies except if the list is empty. 23 | /// 24 | public IEnumerable Assemblies { get; set; } = Array.Empty(); 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/libs/SoloX.BlazorJsonLocalization/Core/AJsonExtensionOptions.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using System.Text.Json; 10 | 11 | namespace SoloX.BlazorJsonLocalization.Core 12 | { 13 | /// 14 | /// Base class for extension options using Json serialization. 15 | /// 16 | public abstract class AJsonExtensionOptions : AExtensionOptions 17 | { 18 | /// 19 | /// Gets/Sets JsonSerializer custom options. 20 | /// 21 | public JsonSerializerOptions? JsonSerializerOptions { get; set; } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/libs/SoloX.BlazorJsonLocalization/Core/IExtensionOptionsContainer.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using System; 10 | 11 | namespace SoloX.BlazorJsonLocalization.Core 12 | { 13 | /// 14 | /// Json localization extension options container. 15 | /// 16 | public interface IExtensionOptionsContainer 17 | { 18 | /// 19 | /// Get the extension options type. 20 | /// 21 | Type ExtensionOptionsType { get; } 22 | 23 | /// 24 | /// Get the extension service type. 25 | /// 26 | Type ExtensionServiceType { get; } 27 | 28 | /// 29 | /// Gets the generic options. 30 | /// 31 | AExtensionOptions Options { get; } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/libs/SoloX.BlazorJsonLocalization/Core/Impl/ExtensionOptionsContainer.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using SoloX.BlazorJsonLocalization.Services; 10 | using System; 11 | 12 | namespace SoloX.BlazorJsonLocalization.Core.Impl 13 | { 14 | /// 15 | /// Typed JsonLocalization extension options. 16 | /// 17 | /// The extension options type. 18 | public sealed class ExtensionOptionsContainer : IExtensionOptionsContainer 19 | where TOptions : AExtensionOptions 20 | { 21 | /// 22 | /// Setup the ExtensionOptionsContainer with the given options. 23 | /// 24 | /// The extension options 25 | public ExtensionOptionsContainer(TOptions options) 26 | { 27 | Options = options; 28 | } 29 | 30 | /// 31 | public Type ExtensionOptionsType => typeof(TOptions); 32 | 33 | /// 34 | public Type ExtensionServiceType => typeof(IJsonLocalizationExtensionService); 35 | 36 | /// 37 | /// Get the typed extension options. 38 | /// 39 | public TOptions Options { get; } 40 | 41 | /// 42 | AExtensionOptions IExtensionOptionsContainer.Options => Options; 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /src/libs/SoloX.BlazorJsonLocalization/Helpers/ArgumentNullExceptionLegacy.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | #if !NET6_0_OR_GREATER 10 | 11 | namespace SoloX.BlazorJsonLocalization.Helpers 12 | { 13 | /// 14 | /// 15 | /// 16 | public static class ArgumentNullExceptionLegacy 17 | { 18 | /// 19 | /// Throw if value is null. 20 | /// 21 | /// 22 | /// 23 | /// 24 | public static void ThrowIfNull(object value, string valueName) 25 | { 26 | if (value == null) 27 | { 28 | throw new System.ArgumentNullException(valueName); 29 | } 30 | } 31 | } 32 | } 33 | 34 | #endif 35 | -------------------------------------------------------------------------------- /src/libs/SoloX.BlazorJsonLocalization/Helpers/CultureInfoHelper.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using System; 10 | using System.Globalization; 11 | using System.Threading.Tasks; 12 | 13 | #if !NET6_0_OR_GREATER 14 | using ArgumentNullException = SoloX.BlazorJsonLocalization.Helpers.ArgumentNullExceptionLegacy; 15 | #endif 16 | 17 | namespace SoloX.BlazorJsonLocalization.Helpers 18 | { 19 | /// 20 | /// Culture info helpers. 21 | /// 22 | public static class CultureInfoHelper 23 | { 24 | /// 25 | /// Walk though CultureInfo Parents and try to load data. Stop as soon as Data is not null. 26 | /// 27 | /// Data type to load. 28 | /// The start CultureInfo to walk from. 29 | /// Asynchronous data loader. 30 | /// The loaded data or null if not fund/loaded. 31 | public static async ValueTask WalkThoughCultureInfoParentsAsync(CultureInfo cultureInfo, Func> loadDataAsync) where TData : class 32 | { 33 | ArgumentNullException.ThrowIfNull(cultureInfo, nameof(cultureInfo)); 34 | ArgumentNullException.ThrowIfNull(loadDataAsync, nameof(loadDataAsync)); 35 | 36 | TData? data; 37 | bool done; 38 | 39 | do 40 | { 41 | data = await loadDataAsync(cultureInfo).ConfigureAwait(false); 42 | 43 | done = data != null 44 | || ReferenceEquals(cultureInfo.Parent, cultureInfo); 45 | 46 | cultureInfo = cultureInfo.Parent; 47 | } 48 | while (!done); 49 | 50 | return data; 51 | } 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /src/libs/SoloX.BlazorJsonLocalization/Helpers/Impl/AJsonMapData.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using System.Collections.Generic; 10 | using System.Text.Json.Serialization; 11 | 12 | namespace SoloX.BlazorJsonLocalization.Helpers.Impl 13 | { 14 | [JsonConverter(typeof(JsonMapDataConverter))] 15 | internal abstract class AJsonMapData 16 | { 17 | public abstract void FillIn(string? prefix, Dictionary map); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/libs/SoloX.BlazorJsonLocalization/Helpers/Impl/JsonMapDataDictionary.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using System.Collections.Generic; 10 | 11 | namespace SoloX.BlazorJsonLocalization.Helpers.Impl 12 | { 13 | internal class JsonMapDataDictionary : AJsonMapData 14 | { 15 | public Dictionary? ValueMap { get; set; } 16 | 17 | public override void FillIn(string? prefix, Dictionary map) 18 | { 19 | foreach (var mapItem in ValueMap) 20 | { 21 | var itemPrefix = string.IsNullOrEmpty(prefix) ? mapItem.Key : prefix + Key.Separator + mapItem.Key; 22 | 23 | mapItem.Value.FillIn(itemPrefix, map); 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/libs/SoloX.BlazorJsonLocalization/Helpers/Impl/JsonMapDataValue.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using System.Collections.Generic; 10 | 11 | namespace SoloX.BlazorJsonLocalization.Helpers.Impl 12 | { 13 | internal class JsonMapDataValue : AJsonMapData 14 | { 15 | public string Value { get; set; } 16 | 17 | public override void FillIn(string? prefix, Dictionary map) 18 | { 19 | map.Add(prefix, Value); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/libs/SoloX.BlazorJsonLocalization/Helpers/JsonHelper.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using SoloX.BlazorJsonLocalization.Helpers.Impl; 10 | using System.Collections.Generic; 11 | using System.IO; 12 | using System.Text.Encodings.Web; 13 | using System.Text.Json; 14 | using System.Threading.Tasks; 15 | 16 | namespace SoloX.BlazorJsonLocalization.Helpers 17 | { 18 | /// 19 | /// Helper static class to provide Json serialization methods. 20 | /// 21 | public static class JsonHelper 22 | { 23 | private static readonly JsonSerializerOptions DefaultJsonOptions = new JsonSerializerOptions 24 | { 25 | Encoder = JavaScriptEncoder.Default, 26 | ReadCommentHandling = JsonCommentHandling.Skip, 27 | WriteIndented = true 28 | }; 29 | 30 | /// 31 | /// Deserialize Json data using provided options (or the one by default if null) 32 | /// 33 | /// The input stream. 34 | /// The options to use with the serializer (may be null). 35 | /// 36 | public static async ValueTask> DeserializeAsync(Stream stream, JsonSerializerOptions? jsonSerializerOptions) 37 | { 38 | var options = jsonSerializerOptions ?? DefaultJsonOptions; 39 | 40 | var jsonMapData = await JsonSerializer 41 | .DeserializeAsync(stream, options) 42 | .ConfigureAwait(false); 43 | 44 | var map = new Dictionary(); 45 | jsonMapData.FillIn(string.Empty, map); 46 | 47 | return map; 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/libs/SoloX.BlazorJsonLocalization/Helpers/NameHelper.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using System; 10 | 11 | namespace SoloX.BlazorJsonLocalization.Helpers 12 | { 13 | internal static class NameHelper 14 | { 15 | internal static string GetBaseName(this Type type) 16 | { 17 | return type.FullName ?? type.Name; 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/libs/SoloX.BlazorJsonLocalization/HttpClientJsonLocalizationOptions.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using System; 10 | using System.Net.Http; 11 | 12 | namespace SoloX.BlazorJsonLocalization 13 | { 14 | /// 15 | /// JsonLocalizer Http Client extension options 16 | /// 17 | public class HttpClientJsonLocalizationOptions : HttpHostedJsonLocalizationOptions 18 | { 19 | /// 20 | /// HttpClient builder handler. 21 | /// 22 | /// Service provider to get the HttpClient from. 23 | /// HttpClient to use to get Json localizer resources. 24 | public delegate HttpClient HttpClientBuilderHandler(IServiceProvider serviceProvider); 25 | 26 | /// 27 | /// Optional HttpClient builder. 28 | /// 29 | public HttpClientBuilderHandler? HttpClientBuilder { get; set; } 30 | 31 | /// 32 | /// Tells if the HttpClient provided by the HttpClientBuilder needs to be disposed. 33 | /// 34 | public bool IsDisposeHttpClientFromBuilderEnabled { get; set; } = true; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/libs/SoloX.BlazorJsonLocalization/JsonLocalizationOptions.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using SoloX.BlazorJsonLocalization.Core; 10 | using System; 11 | using System.Collections.Generic; 12 | using System.Reflection; 13 | 14 | namespace SoloX.BlazorJsonLocalization 15 | { 16 | /// 17 | /// Json localization options. 18 | /// 19 | public sealed class JsonLocalizationOptions 20 | { 21 | /// 22 | /// Get extension options collection. (set is used by the builder) 23 | /// 24 | public IEnumerable ExtensionOptions { get; internal set; } 25 | = Array.Empty(); 26 | 27 | /// 28 | /// Get localization fallback list. 29 | /// 30 | public IEnumerable<(string baseName, Assembly assembly)> Fallbacks { get; internal set; } 31 | = Array.Empty<(string baseName, Assembly assembly)>(); 32 | 33 | /// 34 | /// Tells if the keys must be displayed while resources are loading asynchronously. 35 | /// 36 | public bool IsDisplayKeysWhenResourceNotFoundEnabled { get; internal set; } 37 | 38 | /// 39 | /// Skip base name prefix to be loaded and prevent excessive loading error logs. 40 | /// 41 | public IEnumerable SkipBaseNamePrefix { get; internal set; } 42 | = Array.Empty(); 43 | 44 | /// 45 | /// Tells if logger must be used. 46 | /// 47 | public bool IsLoggerEnabled { get; internal set; } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /src/libs/SoloX.BlazorJsonLocalization/Key.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using System; 10 | 11 | #if !NET6_0_OR_GREATER 12 | using ArgumentNullException = SoloX.BlazorJsonLocalization.Helpers.ArgumentNullExceptionLegacy; 13 | #endif 14 | 15 | namespace SoloX.BlazorJsonLocalization 16 | { 17 | /// 18 | /// Localization Key handling class. 19 | /// 20 | public static class Key 21 | { 22 | /// 23 | /// Key separator use with structured Json object. 24 | /// 25 | public const char Separator = ':'; 26 | 27 | /// 28 | /// Build a key from the given structure Json path. 29 | /// 30 | /// 31 | /// 32 | /// 33 | /// 34 | public static string Path(params string[] structuredKey) 35 | { 36 | ArgumentNullException.ThrowIfNull(structuredKey, nameof(structuredKey)); 37 | 38 | if (structuredKey.Length == 0) 39 | { 40 | throw new ArgumentException("At least one key must be provided", nameof(structuredKey)); 41 | } 42 | 43 | return string.Join(Separator, structuredKey); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/libs/SoloX.BlazorJsonLocalization/Services/ICacheService.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using SoloX.BlazorJsonLocalization.Core; 10 | using System.Globalization; 11 | using System.Reflection; 12 | 13 | namespace SoloX.BlazorJsonLocalization.Services 14 | { 15 | /// 16 | /// Cache service interface. 17 | /// 18 | public interface ICacheService 19 | { 20 | /// 21 | /// Cache the given localizer instance. 22 | /// 23 | /// Resource assembly. 24 | /// Resource BaseName. 25 | /// Resource CultureInfo. 26 | /// Localizer instance to cache. 27 | /// The given localizer or the one from the cache if any. 28 | IStringLocalizerInternal Cache(Assembly assembly, string baseName, CultureInfo? cultureInfo, IStringLocalizerInternal localizer); 29 | 30 | /// 31 | /// Try to match the cache entry. 32 | /// 33 | /// Resource assembly. 34 | /// Resource BaseName. 35 | /// Resource CultureInfo. 36 | /// The localizer if cached or null otherwise. 37 | IStringLocalizerInternal? Match(Assembly assembly, string baseName, CultureInfo? cultureInfo); 38 | 39 | /// 40 | /// Reset the cache entry. 41 | /// 42 | /// Resource assembly. 43 | /// Resource BaseName. 44 | /// Resource CultureInfo. 45 | /// True if the cache entry was found. 46 | bool Reset(Assembly assembly, string baseName, CultureInfo cultureInfo); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/libs/SoloX.BlazorJsonLocalization/Services/ICultureInfoService.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using System.Globalization; 10 | 11 | namespace SoloX.BlazorJsonLocalization.Services 12 | { 13 | /// 14 | /// CultureInfo service to provide abstraction. 15 | /// 16 | public interface ICultureInfoService 17 | { 18 | /// 19 | /// Get the current UI cultureInfo. 20 | /// 21 | CultureInfo CurrentUICulture { get; } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/libs/SoloX.BlazorJsonLocalization/Services/IExtensionResolverService.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using SoloX.BlazorJsonLocalization.Core; 10 | 11 | namespace SoloX.BlazorJsonLocalization.Services 12 | { 13 | /// 14 | /// Extension resolver service that resolve the extension service from a given 15 | /// extension options type. 16 | /// 17 | public interface IExtensionResolverService 18 | { 19 | /// 20 | /// Get the Json Localization extension service. 21 | /// 22 | /// The extension options container to get the associated service 23 | /// from. 24 | /// The Json Localization extension service. 25 | IJsonLocalizationExtensionService GetExtensionService(IExtensionOptionsContainer optionsContainer); 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/libs/SoloX.BlazorJsonLocalization/Services/IHttpCacheService.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using System; 10 | using System.Collections.Generic; 11 | using System.Threading.Tasks; 12 | 13 | namespace SoloX.BlazorJsonLocalization.Services 14 | { 15 | /// 16 | /// Http loading task cache to prevent loading several times the same resources. 17 | /// 18 | public interface IHttpCacheService 19 | { 20 | /// 21 | /// Process loading task unless it is already loading. 22 | /// 23 | /// Uri to fetch. 24 | /// Loading task. 25 | /// The loading task. 26 | Task?> ProcessLoadingTask(Uri uri, Func?>> loadingHandler); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/libs/SoloX.BlazorJsonLocalization/Services/Impl/CultureInfoService.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using System.Globalization; 10 | 11 | namespace SoloX.BlazorJsonLocalization.Services.Impl 12 | { 13 | /// 14 | /// CultureInfo service implementation. 15 | /// 16 | public class CultureInfoService : ICultureInfoService 17 | { 18 | /// 19 | public CultureInfo CurrentUICulture 20 | { 21 | get 22 | { 23 | return CultureInfo.CurrentUICulture; 24 | } 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/libs/SoloX.BlazorJsonLocalization/Services/Impl/ExtensionResolverService.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using Microsoft.Extensions.DependencyInjection; 10 | using SoloX.BlazorJsonLocalization.Core; 11 | using System; 12 | 13 | #if !NET6_0_OR_GREATER 14 | using ArgumentNullException = SoloX.BlazorJsonLocalization.Helpers.ArgumentNullExceptionLegacy; 15 | #endif 16 | 17 | namespace SoloX.BlazorJsonLocalization.Services.Impl 18 | { 19 | /// 20 | /// ExtensionResolverService implementation. 21 | /// 22 | public class ExtensionResolverService : IExtensionResolverService 23 | { 24 | private readonly IServiceProvider serviceProvider; 25 | 26 | /// 27 | /// Setup the ExtensionResolverService with a service provider. 28 | /// 29 | /// The service provider to get the extension services from. 30 | public ExtensionResolverService(IServiceProvider serviceProvider) 31 | { 32 | this.serviceProvider = serviceProvider; 33 | } 34 | 35 | /// 36 | public IJsonLocalizationExtensionService GetExtensionService(IExtensionOptionsContainer optionsContainer) 37 | { 38 | ArgumentNullException.ThrowIfNull(optionsContainer, nameof(optionsContainer)); 39 | 40 | var extensionService = this.serviceProvider 41 | .GetRequiredService(optionsContainer.ExtensionServiceType); 42 | 43 | return (IJsonLocalizationExtensionService)extensionService; 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/libs/SoloX.BlazorJsonLocalization/Services/Impl/HttpCacheService.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using System; 10 | using System.Collections.Generic; 11 | using System.Threading.Tasks; 12 | 13 | #if !NET6_0_OR_GREATER 14 | using ArgumentNullException = SoloX.BlazorJsonLocalization.Helpers.ArgumentNullExceptionLegacy; 15 | #endif 16 | 17 | namespace SoloX.BlazorJsonLocalization.Services.Impl 18 | { 19 | /// 20 | /// IHttpCacheService implementation to prevent loading several times the same resources 21 | /// 22 | public class HttpCacheService : IHttpCacheService 23 | { 24 | /// 25 | /// Cache to avoid Json file reload. 26 | /// 27 | private readonly Dictionary?>> cache = new Dictionary?>>(); 28 | 29 | /// 30 | public Task?> ProcessLoadingTask(Uri uri, Func?>> loadingHandler) 31 | { 32 | ArgumentNullException.ThrowIfNull(loadingHandler, nameof(loadingHandler)); 33 | 34 | lock (this.cache) 35 | { 36 | if (!this.cache.TryGetValue(uri, out var loadingTask)) 37 | { 38 | loadingTask = loadingHandler(); 39 | this.cache.Add(uri, loadingTask); 40 | } 41 | else if (loadingTask.IsFaulted) 42 | { 43 | loadingTask = loadingHandler(); 44 | this.cache[uri] = loadingTask; 45 | } 46 | return loadingTask; 47 | } 48 | } 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /src/tests/SoloX.BlazorJsonLocalization.ITests/.gitignore: -------------------------------------------------------------------------------- 1 | SoloX.BlazorJsonLocalization.ITests.xml 2 | /.editorconfig 3 | -------------------------------------------------------------------------------- /src/tests/SoloX.BlazorJsonLocalization.ITests/Global.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | namespace SoloX.BlazorJsonLocalization.ITests 10 | { 11 | internal class Global 12 | { 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/tests/SoloX.BlazorJsonLocalization.ITests/IGlobal.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | namespace SoloX.BlazorJsonLocalization.ITests 10 | { 11 | internal interface IGlobal 12 | { 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/tests/SoloX.BlazorJsonLocalization.ITests/ISpecific.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | namespace SoloX.BlazorJsonLocalization.ITests 10 | { 11 | internal interface ISpecific : IGlobal 12 | { 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/tests/SoloX.BlazorJsonLocalization.ITests/Resources/Fallback.fr.json: -------------------------------------------------------------------------------- 1 | { 2 | "Fallback": "C'est un message de Fallback..." 3 | } 4 | -------------------------------------------------------------------------------- /src/tests/SoloX.BlazorJsonLocalization.ITests/Resources/Fallback.json: -------------------------------------------------------------------------------- 1 | { 2 | "Fallback": "This is a Fallback message..." 3 | } 4 | -------------------------------------------------------------------------------- /src/tests/SoloX.BlazorJsonLocalization.ITests/Resources/Global.json: -------------------------------------------------------------------------------- 1 | { 2 | "Global": "This is global message..." 3 | } 4 | -------------------------------------------------------------------------------- /src/tests/SoloX.BlazorJsonLocalization.ITests/Resources/IGlobal.fr.json: -------------------------------------------------------------------------------- 1 | { 2 | "Global": "C'est un message global..." 3 | } 4 | -------------------------------------------------------------------------------- /src/tests/SoloX.BlazorJsonLocalization.ITests/Resources/IGlobal.json: -------------------------------------------------------------------------------- 1 | { 2 | "Global": "This is global message..." 3 | } 4 | -------------------------------------------------------------------------------- /src/tests/SoloX.BlazorJsonLocalization.ITests/Resources/ISpecific.fr.json: -------------------------------------------------------------------------------- 1 | { 2 | "Specific": "C'est un message sp�cifique..." 3 | } 4 | -------------------------------------------------------------------------------- /src/tests/SoloX.BlazorJsonLocalization.ITests/Resources/ISpecific.json: -------------------------------------------------------------------------------- 1 | { 2 | "Specific": "This is specific message..." 3 | } 4 | -------------------------------------------------------------------------------- /src/tests/SoloX.BlazorJsonLocalization.ITests/Resources/JsonLocalyserSetupTest.fr.json: -------------------------------------------------------------------------------- 1 | { 2 | "Test": "C'est un test...", 3 | "TestWithArg": "C'est un test avec un argument: {0}...", 4 | "Structured": { 5 | "SubTest": "C'est un test structuré..." 6 | } 7 | } -------------------------------------------------------------------------------- /src/tests/SoloX.BlazorJsonLocalization.ITests/Resources/JsonLocalyserSetupTest.json: -------------------------------------------------------------------------------- 1 | { 2 | "Test": "This is a test...", 3 | "TestWithArg": "This is a test with an argument: {0}...", 4 | "Structured": { 5 | "SubTest": "This is a structured test..." 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /src/tests/SoloX.BlazorJsonLocalization.ITests/Resources/Specific.json: -------------------------------------------------------------------------------- 1 | { 2 | "Specific": "This is specific message..." 3 | } 4 | -------------------------------------------------------------------------------- /src/tests/SoloX.BlazorJsonLocalization.ITests/Specific.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | namespace SoloX.BlazorJsonLocalization.ITests 10 | { 11 | #pragma warning disable CA1812 // Internal class that is apparently never instantiated. 12 | internal sealed class Specific : Global 13 | { 14 | } 15 | #pragma warning restore CA1812 // Internal class that is apparently never instantiated. 16 | } 17 | -------------------------------------------------------------------------------- /src/tests/SoloX.BlazorJsonLocalization.ServerSide.UTests/.gitignore: -------------------------------------------------------------------------------- 1 | SoloX.BlazorJsonLocalization.ServerSide.UTests.xml 2 | /.editorconfig 3 | -------------------------------------------------------------------------------- /src/tests/SoloX.BlazorJsonLocalization.ServerSide.UTests/SoloX.BlazorJsonLocalization.ServerSide.UTests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | net9.0 7 | 8 | false 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | runtime; build; native; contentfiles; analyzers; buildtransitive 20 | all 21 | 22 | 23 | runtime; build; native; contentfiles; analyzers; buildtransitive 24 | all 25 | 26 | 27 | all 28 | runtime; build; native; contentfiles; analyzers; buildtransitive 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /src/tests/SoloX.BlazorJsonLocalization.UTests/.gitignore: -------------------------------------------------------------------------------- 1 | SoloX.BlazorJsonLocalization.UTests.xml 2 | /.editorconfig 3 | -------------------------------------------------------------------------------- /src/tests/SoloX.BlazorJsonLocalization.UTests/Core/ConstStringLocalizerTest.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using System.Globalization; 10 | using Moq; 11 | using SoloX.BlazorJsonLocalization.Core; 12 | using SoloX.BlazorJsonLocalization.Core.Impl; 13 | using Xunit; 14 | 15 | namespace SoloX.BlazorJsonLocalization.UTests.Core 16 | { 17 | public class ConstStringLocalizerTest 18 | { 19 | [Fact] 20 | public void IsShouldReturnTheGivenConstText() 21 | { 22 | var localizerFactoryMock = new Mock(); 23 | var cultureInfo = CultureInfo.GetCultureInfo("en"); 24 | 25 | var constText = "Some constant text..."; 26 | var resourceSource = new StringLocalizerResourceSource("test", typeof(ConstStringLocalizerTest).Assembly, null); 27 | var localizer = new ConstStringLocalizer(resourceSource, cultureInfo, localizerFactoryMock.Object, constText, false, null); 28 | 29 | Assert.Equal(constText, localizer["SomeInput"]); 30 | Assert.Equal(constText, localizer["SomeInput", "With some argument"]); 31 | Assert.Equal(constText, localizer.TryGet("SomeInput")!); 32 | Assert.Equal(constText, localizer.TryGet("SomeInput", ["With some argument"], cultureInfo)!); 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/tests/SoloX.BlazorJsonLocalization.UTests/Core/SatelliteFileProviderFactoryTest.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using FluentAssertions; 10 | using SoloX.BlazorJsonLocalization.Core.Impl; 11 | using System.Collections.Generic; 12 | using System.Globalization; 13 | using System.Text.Json; 14 | using Xunit; 15 | 16 | namespace SoloX.BlazorJsonLocalization.UTests.Core 17 | { 18 | public class SatelliteFileProviderFactoryTest 19 | { 20 | [Theory] 21 | [InlineData("fr", @"Resources/SatelliteFileProvider/Test.fr.json", "TestValueFromFr")] 22 | [InlineData("fr", @"Resources/SatelliteFileProvider/Test.json", "TestValue")] 23 | [InlineData("en", @"Resources/SatelliteFileProvider/Test.json", "TestValue")] 24 | public void ItShouldLoadResouvesFromSatelliteAssembly(string cultureName, string filePath, string exprectedValue) 25 | { 26 | var ci = CultureInfo.GetCultureInfo(cultureName); 27 | 28 | var factory = new SatelliteFileProviderFactory( 29 | typeof(SatelliteFileProviderFactoryTest).Assembly, 30 | "SoloX.BlazorJsonLocalization.UTests"); 31 | 32 | var fileProvider = factory.GetFileProvider(ci); 33 | 34 | var file = fileProvider.GetFileInfo(filePath); 35 | 36 | file.Exists.Should().BeTrue(); 37 | 38 | var map = JsonSerializer.Deserialize>(file.CreateReadStream()); 39 | 40 | map.Should().NotBeNull(); 41 | 42 | map["Test"].Should().Be(exprectedValue); 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /src/tests/SoloX.BlazorJsonLocalization.UTests/Helpers/CultureInfoHelperTest.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using SoloX.BlazorJsonLocalization.Helpers; 10 | using System.Collections.Generic; 11 | using System.Globalization; 12 | using System.Threading.Tasks; 13 | using Xunit; 14 | 15 | namespace SoloX.BlazorJsonLocalization.UTests.Helpers 16 | { 17 | public class CultureInfoHelperTest 18 | { 19 | [Fact] 20 | public async Task ItShouldCallTheDataLoaderWithTheCultureInfoNameAsync() 21 | { 22 | var cultureName = "fr-FR"; 23 | 24 | var cultureInfo = CultureInfo.GetCultureInfo(cultureName); 25 | 26 | var data = await CultureInfoHelper.WalkThoughCultureInfoParentsAsync( 27 | cultureInfo, 28 | culture => 29 | { 30 | return Task.FromResult(culture.Name); 31 | }).ConfigureAwait(false); 32 | 33 | Assert.Equal(cultureName, data); 34 | } 35 | 36 | [Fact] 37 | public async Task ItShouldWalkThroughTheCultureInfoParentAsync() 38 | { 39 | var cultureName = "fr-FR"; 40 | 41 | var cultureInfo = CultureInfo.GetCultureInfo(cultureName); 42 | 43 | var list = new List(); 44 | 45 | var data = await CultureInfoHelper.WalkThoughCultureInfoParentsAsync( 46 | cultureInfo, 47 | culture => 48 | { 49 | list.Add(culture.Name); 50 | return Task.FromResult(null); 51 | }).ConfigureAwait(false); 52 | 53 | Assert.Null(data); 54 | 55 | Assert.Equal(3, list.Count); 56 | Assert.Equal(cultureInfo.Name, list[0]); 57 | Assert.Equal(cultureInfo.Parent.Name, list[1]); 58 | Assert.Equal(cultureInfo.Parent.Parent.Name, list[2]); 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /src/tests/SoloX.BlazorJsonLocalization.UTests/Helpers/ResourcePathHelperTest.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using SoloX.BlazorJsonLocalization.Helpers; 10 | using System; 11 | using System.Reflection; 12 | using Xunit; 13 | 14 | namespace SoloX.BlazorJsonLocalization.UTests.Helpers 15 | { 16 | public class ResourcePathHelperTest 17 | { 18 | private static readonly string BaseName = typeof(ResourcePathHelperTest).FullName; 19 | 20 | private static readonly Assembly Assembly = typeof(ResourcePathHelperTest).Assembly; 21 | 22 | [Fact] 23 | public void ItShouldComputeTheResourcePath() 24 | { 25 | var path = ResourcePathHelper.ComputeBasePath(Assembly, BaseName, Assembly.GetName().Name); 26 | 27 | var expectedPath = BaseName 28 | .Replace(Assembly.GetName().Name + ".", string.Empty, StringComparison.Ordinal) 29 | .Replace('.', '/'); 30 | 31 | Assert.Equal(expectedPath, path); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /src/tests/SoloX.BlazorJsonLocalization.UTests/Resources/EmbeddedJsonLocalizationExtensionServiceTest.fr.json: -------------------------------------------------------------------------------- 1 | { 2 | "Test": "French test.", 3 | "Structured": { 4 | "Test": "French structured test." 5 | } 6 | } -------------------------------------------------------------------------------- /src/tests/SoloX.BlazorJsonLocalization.UTests/Resources/EmbeddedJsonLocalizationExtensionServiceTest.json: -------------------------------------------------------------------------------- 1 | { 2 | "Test": "English test.", 3 | "Structured": { 4 | "Test": "English structured test." 5 | } 6 | } 7 | -------------------------------------------------------------------------------- /src/tests/SoloX.BlazorJsonLocalization.UTests/Resources/EmbeddedJsonLocalizationExtensionUsingAccentsTest.json: -------------------------------------------------------------------------------- 1 | { 2 | "auswählen": "Text for auswählen", 3 | "été": "Text for été", 4 | "konnichiwa": "こんにちは", 5 | "Happiness": "سعادة" 6 | } 7 | -------------------------------------------------------------------------------- /src/tests/SoloX.BlazorJsonLocalization.UTests/Resources/SatelliteFileProvider/Test.fr.json: -------------------------------------------------------------------------------- 1 | { 2 | "Test" : "TestValueFromFr" 3 | } -------------------------------------------------------------------------------- /src/tests/SoloX.BlazorJsonLocalization.UTests/Resources/SatelliteFileProvider/Test.json: -------------------------------------------------------------------------------- 1 | { 2 | "Test" : "TestValue" 3 | } -------------------------------------------------------------------------------- /src/tests/SoloX.BlazorJsonLocalization.UTests/Samples/Extension/MyExtensionService.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using SoloX.BlazorJsonLocalization.Services; 10 | using System; 11 | using System.Collections.Generic; 12 | using System.Globalization; 13 | using System.Reflection; 14 | using System.Threading.Tasks; 15 | 16 | namespace SoloX.BlazorJsonLocalization.UTests.Samples.Extension 17 | { 18 | public class MyExtensionService : IJsonLocalizationExtensionService 19 | { 20 | public ValueTask> TryLoadAsync( 21 | MyOptions options, 22 | Assembly assembly, 23 | string baseName, 24 | CultureInfo cultureInfo) 25 | { 26 | throw new NotImplementedException(); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/tests/SoloX.BlazorJsonLocalization.UTests/Samples/Extension/MyOptions.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using SoloX.BlazorJsonLocalization.Core; 10 | 11 | namespace SoloX.BlazorJsonLocalization.UTests.Samples.Extension 12 | { 13 | public class MyOptions : AExtensionOptions 14 | { 15 | 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/tests/SoloX.BlazorJsonLocalization.UTests/Services/CultureInfoServiceTest.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using SoloX.BlazorJsonLocalization.Services.Impl; 10 | using System.Globalization; 11 | using Xunit; 12 | 13 | namespace SoloX.BlazorJsonLocalization.UTests.Services 14 | { 15 | public class CultureInfoServiceTest 16 | { 17 | [Fact] 18 | public void IsShouldGetCultureInfoFromStaticCurrentUICulture() 19 | { 20 | var service = new CultureInfoService(); 21 | 22 | Assert.Equal(CultureInfo.CurrentUICulture, service.CurrentUICulture); 23 | } 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/tests/SoloX.BlazorJsonLocalization.UTests/Services/ExtensionResolverServiceTest.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using Moq; 10 | using SoloX.BlazorJsonLocalization.Core.Impl; 11 | using SoloX.BlazorJsonLocalization.Services; 12 | using SoloX.BlazorJsonLocalization.Services.Impl; 13 | using SoloX.BlazorJsonLocalization.UTests.Samples.Extension; 14 | using System; 15 | using Xunit; 16 | 17 | namespace SoloX.BlazorJsonLocalization.UTests.Services 18 | { 19 | public class ExtensionResolverServiceTest 20 | { 21 | [Fact] 22 | public void ItShouldGetTheAppropriateExtensionService() 23 | { 24 | var serviceProviderMock = new Mock(); 25 | 26 | serviceProviderMock 27 | .Setup(p => p.GetService(typeof(IJsonLocalizationExtensionService))) 28 | .Returns(new MyExtensionService()); 29 | 30 | var extensionOptionsContainer = new ExtensionOptionsContainer(new MyOptions()); 31 | 32 | var extensionResolverService = new ExtensionResolverService(serviceProviderMock.Object); 33 | var extensionService = extensionResolverService.GetExtensionService(extensionOptionsContainer); 34 | 35 | Assert.NotNull(extensionService); 36 | 37 | serviceProviderMock.Verify(p => p.GetService(typeof(IJsonLocalizationExtensionService))); 38 | serviceProviderMock.VerifyNoOtherCalls(); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /src/tests/SoloX.BlazorJsonLocalization.UTests/SoloX.BlazorJsonLocalization.UTests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | net9.0 7 | 8 | false 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | runtime; build; native; contentfiles; analyzers; buildtransitive 28 | all 29 | 30 | 31 | runtime; build; native; contentfiles; analyzers; buildtransitive 32 | all 33 | 34 | 35 | all 36 | runtime; build; native; contentfiles; analyzers; buildtransitive 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /src/tests/SoloX.BlazorJsonLocalization.WebAssembly.UTests/.gitignore: -------------------------------------------------------------------------------- 1 | SoloX.BlazorJsonLocalization.WebAssembly.UTests.xml 2 | /.editorconfig 3 | -------------------------------------------------------------------------------- /src/tests/SoloX.BlazorJsonLocalization.WebAssembly.UTests/SoloX.BlazorJsonLocalization.WebAssembly.UTests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | net9.0 7 | 8 | false 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | runtime; build; native; contentfiles; analyzers; buildtransitive 20 | all 21 | 22 | 23 | runtime; build; native; contentfiles; analyzers; buildtransitive 24 | all 25 | 26 | 27 | all 28 | runtime; build; native; contentfiles; analyzers; buildtransitive 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /src/tools.examples/SoloX.BlazorJsonLocalization.Generator.Sample/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | *.g.cs 3 | /Resources/**/*.json -------------------------------------------------------------------------------- /src/tools.examples/SoloX.BlazorJsonLocalization.Generator.Sample/Components/IMyComponentStringLocalizer.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.Localization; 2 | using SoloX.BlazorJsonLocalization.Attributes; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace SoloX.BlazorJsonLocalization.Generator.Sample.Components 10 | { 11 | [Localizer("Resources", new[] { "fr", "en" })] 12 | public interface IMyComponentStringLocalizer : IStringLocalizer 13 | { 14 | ISubLocalizer SubLocalizer { get; } 15 | 16 | string MyProperty { get; } 17 | 18 | string MyString(); 19 | string MyStringWithArgs(int value1, string value2); 20 | } 21 | 22 | [SubLocalizer] 23 | public interface ISubLocalizer : IStringLocalizer 24 | { 25 | string SubProperty { get; } 26 | string MyString(); 27 | string MyStringWithArgs(int value1, string value2); 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/tools.examples/SoloX.BlazorJsonLocalization.Generator.Sample/Components/MyComponent.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace SoloX.BlazorJsonLocalization.Generator.Sample.Components 8 | { 9 | public class MyComponent 10 | { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/tools.examples/SoloX.BlazorJsonLocalization.Generator.Sample/ITestStringLocalizer.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.Localization; 2 | using SoloX.BlazorJsonLocalization.Attributes; 3 | using System; 4 | using System.Collections.Generic; 5 | using System.Linq; 6 | using System.Text; 7 | using System.Threading.Tasks; 8 | 9 | namespace SoloX.BlazorJsonLocalization.Generator.Sample 10 | { 11 | [Localizer("Resources", new[] { "fr", "en" })] 12 | public interface ITestStringLocalizer : IStringLocalizer 13 | { 14 | string MyProperty { get; } 15 | 16 | string MyString(); 17 | string MyStringWithArgs(int value1, string value2); 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/tools.examples/SoloX.BlazorJsonLocalization.Generator.Sample/Program.cs: -------------------------------------------------------------------------------- 1 | using Microsoft.Extensions.DependencyInjection; 2 | using Microsoft.Extensions.Localization; 3 | using Microsoft.Extensions.Logging; 4 | using SoloX.BlazorJsonLocalization.Generator.Sample.Components; 5 | 6 | namespace SoloX.BlazorJsonLocalization.Generator.Sample 7 | { 8 | public class Program 9 | { 10 | public static Task Main(string[] args) 11 | { 12 | var services = new ServiceCollection(); 13 | 14 | services.AddLogging(b => b.AddConsole(options => options.LogToStandardErrorThreshold = LogLevel.Warning)); 15 | 16 | services.AddJsonLocalization( 17 | builder => builder.UseEmbeddedJson( 18 | options => options.ResourcesPath = "Resources")); 19 | 20 | using var resolver = services.BuildServiceProvider(); 21 | 22 | var logger = resolver.GetRequiredService>(); 23 | 24 | var localizer = resolver.GetRequiredService>(); 25 | 26 | var typedLocalizer = localizer.ToMyComponentStringLocalizer(); 27 | 28 | logger.LogInformation("typedLocalizer.MyProperty: " + typedLocalizer.MyProperty); 29 | logger.LogInformation("typedLocalizer.SubLocalizer.SubProperty: " + typedLocalizer.SubLocalizer.SubProperty); 30 | logger.LogInformation("typedLocalizer.MyStringWithArgs: " + typedLocalizer.MyStringWithArgs(5, "five")); 31 | 32 | return Task.CompletedTask; 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/tools.examples/SoloX.BlazorJsonLocalization.Generator.Sample/Test.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Text; 5 | using System.Threading.Tasks; 6 | 7 | namespace SoloX.BlazorJsonLocalization.Generator.Sample 8 | { 9 | public class Test 10 | { 11 | } 12 | } 13 | -------------------------------------------------------------------------------- /src/tools.tests/SoloX.BlazorJsonLocalization.Generator.ITests/.gitignore: -------------------------------------------------------------------------------- 1 | SoloX.BlazorJsonLocalization.Generator.ITests.xml 2 | /.editorconfig 3 | -------------------------------------------------------------------------------- /src/tools.tests/SoloX.BlazorJsonLocalization.Generator.ITests/Usings.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | global using Xunit; -------------------------------------------------------------------------------- /src/tools.tests/SoloX.BlazorJsonLocalization.Tools.Core.ITests/.gitignore: -------------------------------------------------------------------------------- 1 | SoloX.BlazorJsonLocalization.Tools.Core.ITests.xml 2 | /.editorconfig 3 | -------------------------------------------------------------------------------- /src/tools.tests/SoloX.BlazorJsonLocalization.Tools.Core.ITests/Usings.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | global using Xunit; -------------------------------------------------------------------------------- /src/tools.tests/SoloX.BlazorJsonLocalization.Tools.Core.Samples/Component.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | namespace SoloX.BlazorJsonLocalization.Tools.Core.Samples 10 | { 11 | public class Component 12 | { 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /src/tools.tests/SoloX.BlazorJsonLocalization.Tools.Core.Samples/SampleBasic/ISimpleLocalizer.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using Microsoft.Extensions.Localization; 10 | using SoloX.BlazorJsonLocalization.Attributes; 11 | 12 | namespace SoloX.BlazorJsonLocalization.Tools.Core.Samples.SampleBasic 13 | { 14 | [Localizer("Resources", new[] { "fr", "en" })] 15 | public interface ISimpleLocalizer : IStringLocalizer 16 | { 17 | string BasicProperty { get; } 18 | string BasicMethod(); 19 | string BasicMethodArg(string arg); 20 | string BasicMethodArg1Arg2(string arg1, string arg2); 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/tools.tests/SoloX.BlazorJsonLocalization.Tools.Core.Samples/SampleSubLocalizerName/ISimple.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using Microsoft.Extensions.Localization; 10 | using SoloX.BlazorJsonLocalization.Attributes; 11 | 12 | namespace SoloX.BlazorJsonLocalization.Tools.Core.Samples.SampleSubLocalizerName 13 | { 14 | [Localizer("Resources", new[] { "fr", "en" })] 15 | public interface ISimple : IStringLocalizer 16 | { 17 | public ISimpleSub SubLocalizer1 { get; } 18 | 19 | public ISimpleSub SubLocalizer2 { get; } 20 | 21 | string BasicProperty { get; } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/tools.tests/SoloX.BlazorJsonLocalization.Tools.Core.Samples/SampleSubLocalizerName/ISimpleSub.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using Microsoft.Extensions.Localization; 10 | using SoloX.BlazorJsonLocalization.Attributes; 11 | 12 | namespace SoloX.BlazorJsonLocalization.Tools.Core.Samples.SampleSubLocalizerName 13 | { 14 | [SubLocalizer] 15 | public interface ISimpleSub : IStringLocalizer 16 | { 17 | string BasicSubProperty1 { get; } 18 | string BasicSubProperty2 { get; } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/tools.tests/SoloX.BlazorJsonLocalization.Tools.Core.Samples/SampleWithMultiLine/IMultiLineLocalizer.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using Microsoft.Extensions.Localization; 10 | using SoloX.BlazorJsonLocalization.Attributes; 11 | 12 | namespace SoloX.BlazorJsonLocalization.Tools.Core.Samples.SampleWithMultiLine 13 | { 14 | [Localizer("Resources", new[] { "fr", "en" })] 15 | public interface IMultiLineLocalizer : IStringLocalizer 16 | { 17 | [Translate(@" 18 | Basic property 19 | translation with 20 | multi lines.")] 21 | string BasicProperty { get; } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/tools.tests/SoloX.BlazorJsonLocalization.Tools.Core.Samples/SampleWithSubLocalizer/ISimpleLocalizer.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using Microsoft.Extensions.Localization; 10 | using SoloX.BlazorJsonLocalization.Attributes; 11 | 12 | namespace SoloX.BlazorJsonLocalization.Tools.Core.Samples.SampleWithSubLocalizer 13 | { 14 | [Localizer("Resources", new[] { "fr", "en" })] 15 | public interface ISimpleLocalizer : IStringLocalizer 16 | { 17 | public ISimpleSubLocalizer SubLocalizer1 { get; } 18 | 19 | public ISimpleSubLocalizer SubLocalizer2 { get; } 20 | 21 | string BasicProperty { get; } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /src/tools.tests/SoloX.BlazorJsonLocalization.Tools.Core.Samples/SampleWithSubLocalizer/ISimpleSubLocalizer.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using Microsoft.Extensions.Localization; 10 | using SoloX.BlazorJsonLocalization.Attributes; 11 | 12 | namespace SoloX.BlazorJsonLocalization.Tools.Core.Samples.SampleWithSubLocalizer 13 | { 14 | [SubLocalizer] 15 | public interface ISimpleSubLocalizer : IStringLocalizer 16 | { 17 | string BasicSubProperty1 { get; } 18 | string BasicSubProperty2 { get; } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/tools.tests/SoloX.BlazorJsonLocalization.Tools.Core.Samples/SampleWithSubLocalizerTranslate/ISimpleLocalizer.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using Microsoft.Extensions.Localization; 10 | using SoloX.BlazorJsonLocalization.Attributes; 11 | 12 | namespace SoloX.BlazorJsonLocalization.Tools.Core.Samples.SampleWithSubLocalizerTranslate 13 | { 14 | [Localizer("Resources", new[] { "fr", "en" })] 15 | public interface ISimpleLocalizer : IStringLocalizer 16 | { 17 | [TranslateSub(nameof(ISimpleSubLocalizer.Arg1), "Argument 1 translation from SubLocalizer1")] 18 | [TranslateSub(nameof(ISimpleSubLocalizer.Arg2), "Argument 2 translation from SubLocalizer1")] 19 | public ISimpleSubLocalizer SubLocalizer1 { get; } 20 | 21 | [TranslateSub(nameof(ISimpleSubLocalizer.Arg1), "Argument 1 translation from SubLocalizer2")] 22 | [TranslateSub(nameof(ISimpleSubLocalizer.Arg2), "Argument 2 translation from SubLocalizer2")] 23 | public ISimpleSubLocalizer SubLocalizer2 { get; } 24 | 25 | [Translate("Basic property translation.")] 26 | string BasicProperty { get; } 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/tools.tests/SoloX.BlazorJsonLocalization.Tools.Core.Samples/SampleWithSubLocalizerTranslate/ISimpleSubLocalizer.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using Microsoft.Extensions.Localization; 10 | using SoloX.BlazorJsonLocalization.Attributes; 11 | 12 | namespace SoloX.BlazorJsonLocalization.Tools.Core.Samples.SampleWithSubLocalizerTranslate 13 | { 14 | [SubLocalizer] 15 | public interface ISimpleSubLocalizer : IStringLocalizer 16 | { 17 | [TranslateArg("default arg1")] 18 | string Arg1 { get; } 19 | 20 | [TranslateArg("default arg2")] 21 | string Arg2 { get; } 22 | 23 | [Translate($"Basic sub property 1 translation. {nameof(Arg1)}")] 24 | string BasicSubProperty1 { get; } 25 | 26 | [Translate($"Basic sub property 2 translation. {nameof(Arg2)}")] 27 | string BasicSubProperty2 { get; } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/tools.tests/SoloX.BlazorJsonLocalization.Tools.Core.Samples/SampleWithTranslate/ISimpleLocalizer.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using Microsoft.Extensions.Localization; 10 | using SoloX.BlazorJsonLocalization.Attributes; 11 | 12 | namespace SoloX.BlazorJsonLocalization.Tools.Core.Samples.SampleWithTranslate 13 | { 14 | [Localizer("Resources", new[] { "fr", "en" })] 15 | public interface ISimpleLocalizer : IStringLocalizer 16 | { 17 | [Translate(@"Basic property translation with special .")] 18 | string BasicProperty { get; } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/tools.tests/SoloX.BlazorJsonLocalization.Tools.Core.Samples/SoloX.BlazorJsonLocalization.Tools.Core.Samples.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | net9.0 5 | enable 6 | enable 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | PreserveNewest 16 | 17 | 18 | PreserveNewest 19 | 20 | 21 | PreserveNewest 22 | 23 | 24 | PreserveNewest 25 | 26 | 27 | PreserveNewest 28 | 29 | 30 | PreserveNewest 31 | 32 | 33 | PreserveNewest 34 | 35 | 36 | PreserveNewest 37 | 38 | 39 | PreserveNewest 40 | 41 | 42 | PreserveNewest 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /src/tools.tests/SoloX.BlazorJsonLocalization.Tools.Core.UTests/.gitignore: -------------------------------------------------------------------------------- 1 | SoloX.BlazorJsonLocalization.Tools.Core.UTests.xml 2 | /.editorconfig 3 | -------------------------------------------------------------------------------- /src/tools.tests/SoloX.BlazorJsonLocalization.Tools.Core.UTests/FileReaderTest.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using FluentAssertions; 10 | using SoloX.BlazorJsonLocalization.Tools.Core.Impl; 11 | 12 | namespace SoloX.BlazorJsonLocalization.Tools.Core.UTests 13 | { 14 | public class FileReaderTest 15 | { 16 | [Fact] 17 | public void ItShouldReadTheFile() 18 | { 19 | var filePath = "./FileName.txt"; 20 | 21 | var someText = "Some text..."; 22 | 23 | File.WriteAllText(filePath, someText); 24 | 25 | var reader = new FileReader(".txt"); 26 | 27 | string? text = null; 28 | 29 | reader.Read(".", "FileName", stream => 30 | { 31 | using var textReader = new StreamReader(stream); 32 | 33 | text = textReader.ReadToEnd(); 34 | }); 35 | 36 | text.Should().NotBeNull().And.Be(someText); 37 | } 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/tools.tests/SoloX.BlazorJsonLocalization.Tools.Core.UTests/SoloX.BlazorJsonLocalization.Tools.Core.UTests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | net9.0 7 | enable 8 | enable 9 | 10 | false 11 | 12 | 13 | 14 | 15 | 16 | 17 | runtime; build; native; contentfiles; analyzers; buildtransitive 18 | all 19 | 20 | 21 | runtime; build; native; contentfiles; analyzers; buildtransitive 22 | all 23 | 24 | 25 | all 26 | runtime; build; native; contentfiles; analyzers; buildtransitive 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /src/tools.tests/SoloX.BlazorJsonLocalization.Tools.Core.UTests/Usings.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | global using Xunit; -------------------------------------------------------------------------------- /src/tools/SoloX.BlazorJsonLocalization.Generator/.gitignore: -------------------------------------------------------------------------------- 1 | SoloX.BlazorJsonLocalization.Generator.xml 2 | /.editorconfig 3 | -------------------------------------------------------------------------------- /src/tools/SoloX.BlazorJsonLocalization.Tools.Command/.gitignore: -------------------------------------------------------------------------------- 1 | SoloX.BlazorJsonLocalization.Tools.Command.xml 2 | /.editorconfig 3 | -------------------------------------------------------------------------------- /src/tools/SoloX.BlazorJsonLocalization.Tools.Command/Program.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | namespace SoloX.BlazorJsonLocalization.Tools 10 | { 11 | /// 12 | /// CLI Tools Generator. 13 | /// 14 | internal static class Program 15 | { 16 | /// 17 | /// Run the tools command. 18 | /// 19 | /// Error code. 20 | public static async Task Main(string[] args) 21 | { 22 | var generatorCommand = new GeneratorCommand(); 23 | 24 | await generatorCommand.RunGeneratorCommandAsync(args).ConfigureAwait(false); 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /src/tools/SoloX.BlazorJsonLocalization.Tools.Command/Properties/launchSettings.json: -------------------------------------------------------------------------------- 1 | { 2 | "profiles": { 3 | "SoloX.BlazorJsonLocalization.Tools.Command": { 4 | "commandName": "Project", 5 | "commandLineArgs": "SoloX.BlazorJsonLocalization.Generator.Sample.csproj --outputCode obj/cslist.output --outputResource obj/reslist.output", 6 | "workingDirectory": "C:\\Work\\Net\\BlazorJsonLocalization\\src\\tools.examples\\SoloX.BlazorJsonLocalization.Generator.Sample" 7 | }, 8 | "SoloX.BlazorJsonLocalization.Tools.Command Version": { 9 | "commandName": "Project", 10 | "commandLineArgs": "--version", 11 | "workingDirectory": "C:\\Work\\Net\\BlazorJsonLocalization\\src\\tools.examples\\SoloX.BlazorJsonLocalization.Generator.Sample" 12 | }, 13 | "SoloX.BlazorJsonLocalization.Tools.Command Help": { 14 | "commandName": "Project", 15 | "commandLineArgs": "--help", 16 | "workingDirectory": "C:\\Work\\Net\\BlazorJsonLocalization\\src\\tools.examples\\SoloX.BlazorJsonLocalization.Generator.Sample" 17 | }, 18 | "Command JudoPlessisBouchard": { 19 | "commandName": "Project", 20 | "commandLineArgs": "SoloX.JudoPlessisBouchard.Client.csproj --outputCode obj/cslist.output --outputResource obj/reslist.output --logDebug", 21 | "workingDirectory": "C:\\Work\\Net\\JudoPlessisBouchard\\SoloX.JudoPlessisBouchard\\SoloX.JudoPlessisBouchard.Client" 22 | }, 23 | "Command Sample": { 24 | "commandName": "Project", 25 | "commandLineArgs": "MyWebApp.Client\\MyWebApp.Client.csproj", 26 | "workingDirectory": "C:\\Work\\Web\\Temp\\MyWebApp" 27 | } 28 | } 29 | } -------------------------------------------------------------------------------- /src/tools/SoloX.BlazorJsonLocalization.Tools.Command/SoloX.BlazorJsonLocalization.Tools.Command.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | Exe 7 | net9.0 8 | enable 9 | enable 10 | latest 11 | 12 | true 13 | localizationgen 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | all 24 | runtime; build; native; contentfiles; analyzers; buildtransitive 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /src/tools/SoloX.BlazorJsonLocalization.Tools.Core/.gitignore: -------------------------------------------------------------------------------- 1 | SoloX.BlazorJsonLocalization.Tools.Core.xml 2 | /.editorconfig 3 | -------------------------------------------------------------------------------- /src/tools/SoloX.BlazorJsonLocalization.Tools.Core/AssemblyProperties.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using System.Runtime.CompilerServices; 10 | 11 | [assembly: InternalsVisibleTo("SoloX.BlazorJsonLocalization.Tools.Core.ITests")] 12 | -------------------------------------------------------------------------------- /src/tools/SoloX.BlazorJsonLocalization.Tools.Core/ILocalizationGeneratorResults.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using System.Collections.Generic; 10 | 11 | namespace SoloX.BlazorJsonLocalization.Tools.Core 12 | { 13 | /// 14 | /// Localization generator results. 15 | /// 16 | public interface ILocalizationGeneratorResults 17 | { 18 | /// 19 | /// Files listed as input. 20 | /// 21 | IEnumerable InputFiles { get; } 22 | 23 | /// 24 | /// Generated code files. 25 | /// 26 | IEnumerable GeneratedCodeFiles { get; } 27 | 28 | /// 29 | /// Generated Json resource files. 30 | /// 31 | IEnumerable GeneratedResourceFiles { get; } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/tools/SoloX.BlazorJsonLocalization.Tools.Core/IReader.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using System; 10 | using System.IO; 11 | 12 | namespace SoloX.BlazorJsonLocalization.Tools.Core 13 | { 14 | /// 15 | /// Stream Reader interface. 16 | /// 17 | public interface IReader 18 | { 19 | /// 20 | /// Read a Stream at the given location and with the given name. 21 | /// If the resource is not found, the reader delegate won't be called. 22 | /// 23 | /// Location of the stream to read. 24 | /// Name of the resource. 25 | /// Reader delegate. 26 | void Read(string location, string name, Action reader); 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /src/tools/SoloX.BlazorJsonLocalization.Tools.Core/Impl/FileReader.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using System; 10 | using System.IO; 11 | 12 | namespace SoloX.BlazorJsonLocalization.Tools.Core.Impl 13 | { 14 | /// 15 | /// File Reader implementation. 16 | /// 17 | public class FileReader : IReader 18 | { 19 | private readonly string fileSufix; 20 | 21 | /// 22 | /// Setup instance. 23 | /// 24 | /// File suffix to use to build the file path. 25 | public FileReader(string fileSufix) 26 | { 27 | this.fileSufix = fileSufix; 28 | } 29 | 30 | /// 31 | public void Read(string location, string name, Action reader) 32 | { 33 | if (reader == null) 34 | { 35 | throw new ArgumentNullException(nameof(reader)); 36 | } 37 | 38 | var path = name + this.fileSufix; 39 | 40 | var text = Path.Combine(location, path); 41 | 42 | if (File.Exists(text)) 43 | { 44 | using (var stream = File.Open(text, FileMode.Open, FileAccess.Read, FileShare.Read)) 45 | { 46 | reader(stream); 47 | } 48 | } 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /src/tools/SoloX.BlazorJsonLocalization.Tools.Core/Impl/Localization/ALocalizationData.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using System.Text.Json.Serialization; 10 | 11 | namespace SoloX.BlazorJsonLocalization.Tools.Core.Impl.Localization 12 | { 13 | /// 14 | /// Abstract class to describe localization data. 15 | /// 16 | [JsonConverter(typeof(LocalizationMapConverter))] 17 | public abstract class ALocalizationData 18 | { 19 | /// 20 | /// Set multi-line parameter. 21 | /// 22 | /// 23 | public abstract void SetMultiLine(bool multiLine); 24 | 25 | /// 26 | /// Set new line separator parameter. 27 | /// 28 | /// New line separator when Multi line is disabled ("\\r\\n" or "\\n") 29 | public abstract void SetNewLineSeparator(string? newLineSeparator = null); 30 | 31 | #pragma warning disable CA1021 // Avoid out parameters 32 | /// 33 | /// Merge the current LocalizationData with the source. 34 | /// 35 | /// Source localization data that may be customized by hand. 36 | /// Localization path key. 37 | /// Tells if the result is modified after merge or if it is same as the source. 38 | /// The merged localization data. 39 | public abstract ALocalizationData Merge(ALocalizationData source, string path, out bool dirty); 40 | #pragma warning restore CA1021 // Avoid out parameters 41 | 42 | /// 43 | /// Remove empty entries from data tree. 44 | /// 45 | /// True if the resulting tree is empty. 46 | public abstract bool Trim(); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /src/tools/SoloX.BlazorJsonLocalization.Tools.Core/Impl/LocalizationGeneratorResults.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using System.Collections.Generic; 10 | 11 | namespace SoloX.BlazorJsonLocalization.Tools.Core.Impl 12 | { 13 | internal class LocalizationGeneratorResults : ILocalizationGeneratorResults 14 | { 15 | /// 16 | /// Setup instance. 17 | /// 18 | public LocalizationGeneratorResults( 19 | IEnumerable inputFiles, 20 | IEnumerable generatedCodeFiles, 21 | IEnumerable generatedResourceFiles) 22 | { 23 | InputFiles = inputFiles; 24 | GeneratedCodeFiles = generatedCodeFiles; 25 | GeneratedResourceFiles = generatedResourceFiles; 26 | } 27 | 28 | /// 29 | public IEnumerable InputFiles { get; private set; } 30 | 31 | /// 32 | public IEnumerable GeneratedCodeFiles { get; private set; } 33 | 34 | /// 35 | public IEnumerable GeneratedResourceFiles { get; private set; } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/tools/SoloX.BlazorJsonLocalization.Tools.Core/Patterns/Impl/MyObjectSub2StringLocalizerPattern.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using Microsoft.Extensions.Localization; 10 | using SoloX.BlazorJsonLocalization.Tools.Core.Patterns.Itf; 11 | 12 | namespace SoloX.BlazorJsonLocalization.Tools.Core.Patterns.Impl 13 | { 14 | internal class MyObjectSub2StringLocalizerPattern : IMyObjectSub2StringLocalizerPattern 15 | { 16 | public MyObjectSub2StringLocalizerPattern(IStringLocalizer stringLocalizer, IStringLocalizer argumentStringLocalizer) 17 | { 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/tools/SoloX.BlazorJsonLocalization.Tools.Core/Patterns/Itf/IMyObjectStringLocalizerPattern.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using Microsoft.Extensions.Localization; 10 | using SoloX.BlazorJsonLocalization.Tools.Core.Selectors; 11 | using SoloX.GeneratorTools.Core.CSharp.Generator.Attributes; 12 | 13 | namespace SoloX.BlazorJsonLocalization.Tools.Core.Patterns.Itf 14 | { 15 | /// 16 | /// Code first string localizer definition pattern. 17 | /// 18 | public interface IMyObjectStringLocalizerPattern : IStringLocalizer 19 | { 20 | /// 21 | /// Get MyObjectSubStringLocalizerProperty Sub string localizer. 22 | /// 23 | [Pattern] 24 | IMyObjectSubStringLocalizerPattern MyObjectSubStringLocalizerProperty { get; } 25 | 26 | /// 27 | /// Get SomeProperty localized string. 28 | /// 29 | [Pattern] 30 | string SomeProperty { get; } 31 | 32 | /// 33 | /// Get SomeStringArgs localized string. 34 | /// 35 | string SomeStringArgs(object someParameter); 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/tools/SoloX.BlazorJsonLocalization.Tools.Core/Patterns/Itf/IMyObjectSub2StringLocalizerPattern.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | #pragma warning disable CA1040 // Avoid empty interfaces 10 | namespace SoloX.BlazorJsonLocalization.Tools.Core.Patterns.Itf 11 | { 12 | /// 13 | /// Code first sub string localizer definition pattern. 14 | /// 15 | public interface IMyObjectSub2StringLocalizerPattern 16 | { 17 | } 18 | } 19 | #pragma warning restore CA1040 // Avoid empty interfaces 20 | -------------------------------------------------------------------------------- /src/tools/SoloX.BlazorJsonLocalization.Tools.Core/Patterns/Itf/IMyObjectSubStringLocalizerPattern.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using Microsoft.Extensions.Localization; 10 | using SoloX.BlazorJsonLocalization.Tools.Core.Selectors; 11 | using SoloX.GeneratorTools.Core.CSharp.Generator.Attributes; 12 | 13 | namespace SoloX.BlazorJsonLocalization.Tools.Core.Patterns.Itf 14 | { 15 | /// 16 | /// Code first sub string localizer definition pattern. 17 | /// 18 | public interface IMyObjectSubStringLocalizerPattern : IStringLocalizer 19 | { 20 | /// 21 | /// Get Sub localized argument. 22 | /// 23 | [Pattern] 24 | string SomeArgument { get; } 25 | 26 | /// 27 | /// Get MyObjectSub2StringLocalizerProperty Sub string localizer. 28 | /// 29 | [Pattern] 30 | IMyObjectSub2StringLocalizerPattern MyObjectSub2StringLocalizerProperty { get; } 31 | 32 | /// 33 | /// Get SomeSubProperty localized string. 34 | /// 35 | [Pattern] 36 | string SomeSubProperty { get; } 37 | 38 | /// 39 | /// Get SomeSubStringArgs localized string. 40 | /// 41 | string SomeSubStringArgs(object someParameter); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/tools/SoloX.BlazorJsonLocalization.Tools.Core/Patterns/Itf/MyObject.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | namespace SoloX.BlazorJsonLocalization.Tools.Core.Patterns.Itf 10 | { 11 | /// 12 | /// MyObject sample used by the generator patterns. 13 | /// 14 | public class MyObject 15 | { 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/tools/SoloX.BlazorJsonLocalization.Tools.Core/Patterns/LocalizerExtensions.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using System; 10 | using System.Collections.Generic; 11 | using System.Linq; 12 | using Microsoft.Extensions.Localization; 13 | 14 | namespace SoloX.BlazorJsonLocalization.Tools.Core.Patterns.Impl 15 | { 16 | internal static class LocalizerExtensions 17 | { 18 | public static IStringLocalizer GetSubLocalizer(this IStringLocalizer localizer, params string[] structuredKey) 19 | { 20 | return new SubStringLocalizer(localizer, string.Join(":", structuredKey) + ":"); 21 | } 22 | } 23 | 24 | internal class SubStringLocalizer : IStringLocalizer 25 | { 26 | private readonly IStringLocalizer localizer; 27 | private readonly string structuredKeyPrefix; 28 | 29 | /// 30 | /// Setup instance. 31 | /// 32 | /// Base localizer reference. 33 | /// Structured key to use as prefix. 34 | public SubStringLocalizer(IStringLocalizer localizer, string structuredKeyPrefix) 35 | { 36 | this.localizer = localizer; 37 | this.structuredKeyPrefix = structuredKeyPrefix; 38 | } 39 | 40 | /// 41 | public LocalizedString this[string name] => this.localizer[this.structuredKeyPrefix + name]; 42 | 43 | /// 44 | public LocalizedString this[string name, params object[] arguments] => this.localizer[this.structuredKeyPrefix + name, arguments]; 45 | 46 | /// 47 | public IEnumerable GetAllStrings(bool includeParentCultures) 48 | { 49 | return this.localizer.GetAllStrings(includeParentCultures).Where(s => s.Name.StartsWith(this.structuredKeyPrefix, StringComparison.InvariantCulture)); 50 | } 51 | } 52 | } 53 | -------------------------------------------------------------------------------- /src/tools/SoloX.BlazorJsonLocalization.Tools.Core/Selectors/LocalizerArgumentSelector.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using Microsoft.CodeAnalysis; 10 | using SoloX.GeneratorTools.Core.CSharp.Model; 11 | using System; 12 | using System.Linq; 13 | using System.Collections.Generic; 14 | 15 | namespace SoloX.BlazorJsonLocalization.Tools.Core.Selectors 16 | { 17 | /// 18 | /// Custom PropertySelector to get string only properties. 19 | /// 20 | public class LocalizerArgumentSelector : ALocalizerSelector 21 | { 22 | /// 23 | public override IEnumerable GetProperties(IGenericDeclaration declaration) 24 | { 25 | if (declaration == null) 26 | { 27 | throw new ArgumentNullException(nameof(declaration)); 28 | } 29 | 30 | return declaration.Properties.Where(p => IsStringProperty(p) && IsLocalizerArgument(p)); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/tools/SoloX.BlazorJsonLocalization.Tools.Core/Selectors/LocalizerPropertySelector.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using Microsoft.CodeAnalysis; 10 | using SoloX.GeneratorTools.Core.CSharp.Model; 11 | using System; 12 | using System.Linq; 13 | using System.Collections.Generic; 14 | 15 | namespace SoloX.BlazorJsonLocalization.Tools.Core.Selectors 16 | { 17 | /// 18 | /// Custom PropertySelector to get string only properties. 19 | /// 20 | public class LocalizerPropertySelector : ALocalizerSelector 21 | { 22 | /// 23 | public override IEnumerable GetProperties(IGenericDeclaration declaration) 24 | { 25 | if (declaration == null) 26 | { 27 | throw new ArgumentNullException(nameof(declaration)); 28 | } 29 | 30 | return declaration.Properties.Where(p => IsStringProperty(p) && !IsLocalizerArgument(p)); 31 | } 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /src/tools/SoloX.BlazorJsonLocalization.Tools.Core/Selectors/SelectorResolver.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using SoloX.BlazorJsonLocalization.Attributes; 10 | using SoloX.GeneratorTools.Core.CSharp.Generator.Impl; 11 | 12 | namespace SoloX.BlazorJsonLocalization.Tools.Core.Selectors 13 | { 14 | internal class SelectorResolver : DefaultSelectorResolver 15 | { 16 | public SelectorResolver() 17 | : base(typeof(SubLocalizerPropertySelector), typeof(LocalizerPropertySelector), typeof(LocalizerArgumentSelector), typeof(LocalizerAttribute), typeof(SubLocalizerAttribute)) 18 | { } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/tools/SoloX.BlazorJsonLocalization.Tools.Extensions/.gitignore: -------------------------------------------------------------------------------- 1 | SoloX.BlazorJsonLocalization.Tools.Extensions.xml 2 | /.editorconfig 3 | -------------------------------------------------------------------------------- /src/tools/SoloX.BlazorJsonLocalization.Tools.Extensions/SoloX.BlazorJsonLocalization.Tools.Extensions.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | netstandard2.0 7 | latest 8 | 9 | 10 | 11 | 12 | 13 | all 14 | runtime; build; native; contentfiles; analyzers; buildtransitive 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/tools/SoloX.BlazorJsonLocalization.Tools.Extensions/ToolsGeneratorExtensions.cs: -------------------------------------------------------------------------------- 1 | // ---------------------------------------------------------------------- 2 | // 3 | // Copyright © 2021 Xavier Solau. 4 | // Licensed under the MIT license. 5 | // See LICENSE file in the project root for full license information. 6 | // 7 | // ---------------------------------------------------------------------- 8 | 9 | using Microsoft.Extensions.DependencyInjection; 10 | using Microsoft.Extensions.Logging; 11 | using SoloX.BlazorJsonLocalization.Tools.Core; 12 | using SoloX.BlazorJsonLocalization.Tools.Core.Impl; 13 | using SoloX.GeneratorTools.Core.CSharp.Extensions; 14 | 15 | namespace SoloX.BlazorJsonLocalization.Tools.Extensions 16 | { 17 | /// 18 | /// Extension methods to register the Tools generator. 19 | /// 20 | public static class ToolsGeneratorExtensions 21 | { 22 | /// 23 | /// Add dependency injections for the state generator. 24 | /// 25 | /// The service collection where to setup dependencies. 26 | /// 27 | /// The input services once setup is done. 28 | public static IServiceCollection AddToolsGenerator(this IServiceCollection services, ILoggerFactory loggerFactory = null) 29 | { 30 | return services 31 | .AddCSharpToolsGenerator(loggerFactory) 32 | .AddTransient(); 33 | } 34 | } 35 | } 36 | --------------------------------------------------------------------------------