From 6403aeac8c7677abfccd264a11ea4f0ca0b9fe07 Mon Sep 17 00:00:00 2001 From: Sebastian Stehle Date: Mon, 8 Jul 2019 20:54:48 +0200 Subject: [PATCH] Custom languages. --- src/Squidex.Infrastructure/Language.cs | 2 +- .../LanguagesInitializer.cs | 39 ++++++++++++ .../LanguagesOptions.cs | 15 +++++ .../Config/Domain/InfrastructureServices.cs | 4 ++ src/Squidex/WebStartup.cs | 3 + src/Squidex/appsettings.json | 7 +++ .../LanguagesInitializerTests.cs | 61 +++++++++++++++++++ 7 files changed, 130 insertions(+), 1 deletion(-) create mode 100644 src/Squidex.Infrastructure/LanguagesInitializer.cs create mode 100644 src/Squidex.Infrastructure/LanguagesOptions.cs create mode 100644 tests/Squidex.Infrastructure.Tests/LanguagesInitializerTests.cs diff --git a/src/Squidex.Infrastructure/Language.cs b/src/Squidex.Infrastructure/Language.cs index 981d7ee47..0d096fc31 100644 --- a/src/Squidex.Infrastructure/Language.cs +++ b/src/Squidex.Infrastructure/Language.cs @@ -16,7 +16,7 @@ namespace Squidex.Infrastructure private static readonly Regex CultureRegex = new Regex("^([a-z]{2})(\\-[a-z]{2})?$", RegexOptions.IgnoreCase); private static readonly Dictionary AllLanguagesField = new Dictionary(StringComparer.OrdinalIgnoreCase); - private static Language AddLanguage(string iso2Code, string englishName) + internal static Language AddLanguage(string iso2Code, string englishName) { return AllLanguagesField.GetOrAdd(iso2Code, englishName, (c, n) => new Language(c, n)); } diff --git a/src/Squidex.Infrastructure/LanguagesInitializer.cs b/src/Squidex.Infrastructure/LanguagesInitializer.cs new file mode 100644 index 000000000..214e7aa60 --- /dev/null +++ b/src/Squidex.Infrastructure/LanguagesInitializer.cs @@ -0,0 +1,39 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using System.Threading; +using System.Threading.Tasks; +using Microsoft.Extensions.Options; +using Squidex.Infrastructure.Tasks; + +namespace Squidex.Infrastructure +{ + public sealed class LanguagesInitializer : IInitializable + { + private readonly LanguagesOptions options; + + public LanguagesInitializer(IOptions options) + { + Guard.NotNull(options, nameof(options)); + + this.options = options.Value; + } + + public Task InitializeAsync(CancellationToken ct = default) + { + foreach (var kvp in options) + { + if (!string.IsNullOrWhiteSpace(kvp.Key) && !string.IsNullOrWhiteSpace(kvp.Value)) + { + Language.AddLanguage(kvp.Key, kvp.Value); + } + } + + return TaskHelper.Done; + } + } +} diff --git a/src/Squidex.Infrastructure/LanguagesOptions.cs b/src/Squidex.Infrastructure/LanguagesOptions.cs new file mode 100644 index 000000000..7a7e66ce3 --- /dev/null +++ b/src/Squidex.Infrastructure/LanguagesOptions.cs @@ -0,0 +1,15 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using System.Collections.Generic; + +namespace Squidex.Infrastructure +{ + public sealed class LanguagesOptions : Dictionary + { + } +} diff --git a/src/Squidex/Config/Domain/InfrastructureServices.cs b/src/Squidex/Config/Domain/InfrastructureServices.cs index 915dd035a..e47181641 100644 --- a/src/Squidex/Config/Domain/InfrastructureServices.cs +++ b/src/Squidex/Config/Domain/InfrastructureServices.cs @@ -16,6 +16,7 @@ using Squidex.Areas.Api.Controllers.News.Service; using Squidex.Domain.Apps.Entities.Apps.Diagnostics; using Squidex.Domain.Apps.Entities.Rules.UsageTracking; using Squidex.Domain.Users; +using Squidex.Infrastructure; using Squidex.Infrastructure.Caching; using Squidex.Infrastructure.Diagnostics; using Squidex.Infrastructure.EventSourcing.Grains; @@ -57,6 +58,9 @@ namespace Squidex.Config.Domain services.AddSingletonAs>() .AsSelf(); + services.AddSingletonAs() + .AsSelf(); + services.AddSingletonAs() .As(); diff --git a/src/Squidex/WebStartup.cs b/src/Squidex/WebStartup.cs index e85d489ed..8b2072990 100644 --- a/src/Squidex/WebStartup.cs +++ b/src/Squidex/WebStartup.cs @@ -29,6 +29,7 @@ using Squidex.Config.Startup; using Squidex.Config.Web; using Squidex.Domain.Apps.Entities.Assets; using Squidex.Domain.Apps.Entities.Contents; +using Squidex.Infrastructure; using Squidex.Infrastructure.Commands; using Squidex.Infrastructure.Diagnostics; using Squidex.Infrastructure.Translations; @@ -81,6 +82,8 @@ namespace Squidex config.GetSection("assets")); services.Configure( config.GetSection("translations:deepL")); + services.Configure( + config.GetSection("languages")); services.Configure( config.GetSection("mode")); services.Configure( diff --git a/src/Squidex/appsettings.json b/src/Squidex/appsettings.json index 773dffe65..be7ea89eb 100644 --- a/src/Squidex/appsettings.json +++ b/src/Squidex/appsettings.json @@ -32,6 +32,13 @@ "strong": false }, + "languages": { + /* + * Use custom langauges where the key is the language code and the value is the english name. + */ + "custom": "" + }, + "ui": { /* * Regex suggestions for the UI diff --git a/tests/Squidex.Infrastructure.Tests/LanguagesInitializerTests.cs b/tests/Squidex.Infrastructure.Tests/LanguagesInitializerTests.cs new file mode 100644 index 000000000..62cd813c5 --- /dev/null +++ b/tests/Squidex.Infrastructure.Tests/LanguagesInitializerTests.cs @@ -0,0 +1,61 @@ +// ========================================================================== +// Squidex Headless CMS +// ========================================================================== +// Copyright (c) Squidex UG (haftungsbeschraenkt) +// All rights reserved. Licensed under the MIT license. +// ========================================================================== + +using System.Threading.Tasks; +using Microsoft.Extensions.Options; +using Xunit; + +namespace Squidex.Infrastructure +{ + public sealed class LanguagesInitializerTests + { + [Fact] + public async Task Should_add_custom_languages() + { + var options = Options.Create(new LanguagesOptions + { + ["en-NO"] = "English (Norwegian)" + }); + + var sut = new LanguagesInitializer(options); + + await sut.InitializeAsync(); + + Assert.Equal("English (Norwegian)", Language.GetLanguage("en-NO").EnglishName); + } + + [Fact] + public async Task Should_not_add_invalid_languages() + { + var options = Options.Create(new LanguagesOptions + { + ["en-Error"] = null + }); + + var sut = new LanguagesInitializer(options); + + await sut.InitializeAsync(); + + Assert.False(Language.TryGetLanguage("en-Error", out _)); + } + + [Fact] + public async Task Should_not_override_existing_languages() + { + var options = Options.Create(new LanguagesOptions + { + ["de"] = "German (Germany)" + }); + + var sut = new LanguagesInitializer(options); + + await sut.InitializeAsync(); + + Assert.Equal("German", Language.GetLanguage("de").EnglishName); + } + } +}