diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Components/Toolbar/LanguageSwitch/Default.cshtml b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Components/Toolbar/LanguageSwitch/Default.cshtml
index 7131fa1175..53d56ebfa3 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Components/Toolbar/LanguageSwitch/Default.cshtml
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Components/Toolbar/LanguageSwitch/Default.cshtml
@@ -8,7 +8,7 @@
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Components/Toolbar/LanguageSwitch/LanguageInfo.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Components/Toolbar/LanguageSwitch/LanguageInfo.cs
deleted file mode 100644
index 05af1040f9..0000000000
--- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Components/Toolbar/LanguageSwitch/LanguageInfo.cs
+++ /dev/null
@@ -1,11 +0,0 @@
-namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Themes.Basic.Components.Toolbar.LanguageSwitch
-{
- public class LanguageInfo
- {
- public string Name { get; set; }
-
- public string DisplayName { get; set; }
-
- public string Icon { get; set; }
- }
-}
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Components/Toolbar/LanguageSwitch/LanguageSwitchViewComponent.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Components/Toolbar/LanguageSwitch/LanguageSwitchViewComponent.cs
index 62f8fbc9b2..336dccecee 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Components/Toolbar/LanguageSwitch/LanguageSwitchViewComponent.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Components/Toolbar/LanguageSwitch/LanguageSwitchViewComponent.cs
@@ -1,49 +1,44 @@
-using System.Globalization;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
+using Volo.Abp.Localization;
namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Themes.Basic.Components.Toolbar.LanguageSwitch
{
public class LanguageSwitchViewComponent : AbpViewComponent
{
- private readonly RequestLocalizationOptions _options;
+ private readonly ILanguageProvider _languageProvider;
- public LanguageSwitchViewComponent(IOptions options)
+ public LanguageSwitchViewComponent(ILanguageProvider languageProvider)
{
- _options = options.Value;
+ _languageProvider = languageProvider;
}
- public IViewComponentResult Invoke()
+ public async Task InvokeAsync()
{
- //TODO: Better handle culture & uiculture separation!
+ var languages = await _languageProvider.GetLanguagesAsync();
+ var currentLanguage = FindCurrentLanguage(languages);
var model = new LanguageSwitchViewComponentModel
{
- CurrentLanguage = new LanguageInfo
- {
- Name = CultureInfo.CurrentUICulture.Name,
- DisplayName = CultureInfo.CurrentUICulture.DisplayName,
- Icon = null //TODO!
- }
+ CurrentLanguage = currentLanguage,
+ OtherLanguages = languages.Where(l => l != currentLanguage).ToList()
};
-
- foreach (var supportedUiCulture in _options.SupportedUICultures)
- {
- if (model.CurrentLanguage.Name == supportedUiCulture.Name)
- {
- continue;
- }
-
- model.OtherLanguages.Add(new LanguageInfo
- {
- Name = supportedUiCulture.Name,
- DisplayName = supportedUiCulture.DisplayName,
- Icon = null //TODO!
- });
- }
-
+
return View("~/Themes/Basic/Components/Toolbar/LanguageSwitch/Default.cshtml", model);
}
+
+ private LanguageInfo FindCurrentLanguage(IReadOnlyList languages)
+ {
+ return languages.FirstOrDefault(l =>
+ l.CultureName == CultureInfo.CurrentCulture.Name &&
+ l.UiCultureName == CultureInfo.CurrentUICulture.Name)
+ ?? languages.FirstOrDefault(l => l.CultureName == CultureInfo.CurrentCulture.Name)
+ ?? languages.FirstOrDefault(l => l.UiCultureName == CultureInfo.CurrentUICulture.Name);
+ }
}
}
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Components/Toolbar/LanguageSwitch/LanguageSwitchViewComponentModel.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Components/Toolbar/LanguageSwitch/LanguageSwitchViewComponentModel.cs
index 7f2eb7a9fd..248675dbe1 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Components/Toolbar/LanguageSwitch/LanguageSwitchViewComponentModel.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Components/Toolbar/LanguageSwitch/LanguageSwitchViewComponentModel.cs
@@ -1,4 +1,5 @@
using System.Collections.Generic;
+using Volo.Abp.Localization;
namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Themes.Basic.Components.Toolbar.LanguageSwitch
{
@@ -6,11 +7,6 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Themes.Basic.Components.Toolbar
{
public LanguageInfo CurrentLanguage { get; set; }
- public List OtherLanguages { get; }
-
- public LanguageSwitchViewComponentModel()
- {
- OtherLanguages = new List();
- }
+ public List OtherLanguages { get; set; }
}
}
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Toolbars/BasicThemeMainTopToolbarContributor.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Toolbars/BasicThemeMainTopToolbarContributor.cs
index dea0ea73d2..e0738d424f 100644
--- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Toolbars/BasicThemeMainTopToolbarContributor.cs
+++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Toolbars/BasicThemeMainTopToolbarContributor.cs
@@ -1,11 +1,9 @@
-using System.Linq;
-using System.Threading.Tasks;
-using Microsoft.AspNetCore.Builder;
+using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.Options;
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Themes.Basic.Components.Toolbar.LanguageSwitch;
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Themes.Basic.Components.Toolbar.UserMenu;
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared.Toolbars;
+using Volo.Abp.Localization;
using Volo.Abp.Users;
namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Toolbars
@@ -24,9 +22,10 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Toolbars
return Task.CompletedTask;
}
- var requestLocalizationOptions = context.ServiceProvider.GetService>();
+ var languageProvider = context.ServiceProvider.GetService();
- if (requestLocalizationOptions.Value.SupportedCultures.Count > 1)
+ //TODO: This duplicates GetLanguages() usage. Can we eleminate this?
+ if (languageProvider.GetLanguages().Count > 1)
{
context.Toolbar.Items.Add(new ToolbarItem(typeof(LanguageSwitchViewComponent)));
}
diff --git a/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/Builder/AbpApplicationBuilderExtensions.cs b/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/Builder/AbpApplicationBuilderExtensions.cs
index 61b5fc6455..9631e0aef2 100644
--- a/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/Builder/AbpApplicationBuilderExtensions.cs
+++ b/framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/Builder/AbpApplicationBuilderExtensions.cs
@@ -1,15 +1,24 @@
-using JetBrains.Annotations;
+using System.Collections.Generic;
+using System.Globalization;
+using System.Linq;
+using JetBrains.Annotations;
+using Microsoft.AspNetCore.Localization;
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp;
using Volo.Abp.AspNetCore.Auditing;
using Volo.Abp.AspNetCore.Mvc.ExceptionHandling;
using Volo.Abp.AspNetCore.Uow;
using Volo.Abp.DependencyInjection;
+using Volo.Abp.Localization;
+using Volo.Abp.Settings;
+using Volo.Abp.Threading;
namespace Microsoft.AspNetCore.Builder
{
public static class AbpApplicationBuilderExtensions
{
+ private const string ExceptionHandlingMiddlewareMarker = "_AbpExceptionHandlingMiddleware_Added";
+
public static void InitializeApplication([NotNull] this IApplicationBuilder app)
{
Check.NotNull(app, nameof(app));
@@ -31,16 +40,72 @@ namespace Microsoft.AspNetCore.Builder
.UseMiddleware();
}
+ public static IApplicationBuilder UseAbpRequestLocalization(this IApplicationBuilder app)
+ {
+ IReadOnlyList languages;
+ string defaultLanguage;
+
+ using (var scope = app.ApplicationServices.CreateScope())
+ {
+ var languageProvider = scope.ServiceProvider.GetRequiredService();
+ var settingManager = scope.ServiceProvider.GetRequiredService();
+
+ languages = AsyncHelper.RunSync(() => languageProvider.GetLanguagesAsync());
+ defaultLanguage = settingManager.GetOrNull(LocalizationSettingNames.DefaultLanguage);
+ }
+
+ if (!languages.Any())
+ {
+ return app.UseRequestLocalization();
+ }
+
+ var options = new RequestLocalizationOptions
+ {
+ DefaultRequestCulture = DefaultGetRequestCulture(defaultLanguage, languages),
+
+ SupportedCultures = languages
+ .Select(l => l.CultureName)
+ .Distinct()
+ .Select(c => new CultureInfo(c))
+ .ToArray(),
+
+ SupportedUICultures = languages
+ .Select(l => l.UiCultureName)
+ .Distinct()
+ .Select(c => new CultureInfo(c))
+ .ToArray()
+ };
+
+ return app.UseRequestLocalization(options);
+ }
+
public static IApplicationBuilder UseAbpExceptionHandling(this IApplicationBuilder app)
{
- //Prevent multiple add
- if (app.Properties.ContainsKey("_AbpExceptionHandlingMiddleware_Added")) //TODO: Constant
+ if (app.Properties.ContainsKey(ExceptionHandlingMiddlewareMarker))
{
return app;
}
- app.Properties["_AbpExceptionHandlingMiddleware_Added"] = true;
+ app.Properties[ExceptionHandlingMiddlewareMarker] = true;
return app.UseMiddleware();
}
+
+ private static RequestCulture DefaultGetRequestCulture(string defaultLanguage, IReadOnlyList languages)
+ {
+ if (defaultLanguage == null)
+ {
+ var firstLanguage = languages.First();
+ return new RequestCulture(firstLanguage.CultureName, firstLanguage.UiCultureName);
+ }
+
+ if (!defaultLanguage.Contains(";"))
+ {
+ return new RequestCulture(defaultLanguage, defaultLanguage);
+ }
+
+ var splitted = defaultLanguage.Split(';');
+ return new RequestCulture(splitted[0], splitted[1]);
+
+ }
}
}
diff --git a/framework/src/Volo.Abp.AspNetCore/Volo.Abp.AspNetCore.csproj b/framework/src/Volo.Abp.AspNetCore/Volo.Abp.AspNetCore.csproj
index 541e917198..52f7a106da 100644
--- a/framework/src/Volo.Abp.AspNetCore/Volo.Abp.AspNetCore.csproj
+++ b/framework/src/Volo.Abp.AspNetCore/Volo.Abp.AspNetCore.csproj
@@ -32,6 +32,7 @@
+
diff --git a/framework/src/Volo.Abp.Localization/Volo.Abp.Localization.csproj b/framework/src/Volo.Abp.Localization/Volo.Abp.Localization.csproj
index a85af92dc3..81042b0ce8 100644
--- a/framework/src/Volo.Abp.Localization/Volo.Abp.Localization.csproj
+++ b/framework/src/Volo.Abp.Localization/Volo.Abp.Localization.csproj
@@ -1,4 +1,4 @@
-
+
@@ -22,7 +22,7 @@
-
+
diff --git a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/AbpLocalizationModule.cs b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/AbpLocalizationModule.cs
index 9ceaf569ac..51cabbc821 100644
--- a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/AbpLocalizationModule.cs
+++ b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/AbpLocalizationModule.cs
@@ -1,11 +1,15 @@
using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Localization.Resources.AbpValidation;
using Volo.Abp.Modularity;
+using Volo.Abp.Settings;
using Volo.Abp.VirtualFileSystem;
namespace Volo.Abp.Localization
{
- [DependsOn(typeof(AbpVirtualFileSystemModule))]
+ [DependsOn(
+ typeof(AbpVirtualFileSystemModule),
+ typeof(AbpSettingsModule)
+ )]
public class AbpLocalizationModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
@@ -24,6 +28,11 @@ namespace Volo.Abp.Localization
.AddVirtualJson("/Localization/Resources/AbpValidation");
});
+ context.Services.Configure(options =>
+ {
+ options.DefinitionProviders.Add();
+ });
+
context.Services.AddAssemblyOf();
}
}
diff --git a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/AbpLocalizationOptions.cs b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/AbpLocalizationOptions.cs
index fd79a1ffb2..ea5232bb04 100644
--- a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/AbpLocalizationOptions.cs
+++ b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/AbpLocalizationOptions.cs
@@ -1,4 +1,5 @@
-using Volo.Abp.Collections;
+using System.Collections.Generic;
+using Volo.Abp.Collections;
namespace Volo.Abp.Localization
{
@@ -8,10 +9,13 @@ namespace Volo.Abp.Localization
public ITypeList GlobalContributors { get; }
+ public List Languages { get; }
+
public AbpLocalizationOptions()
{
Resources = new LocalizationResourceDictionary();
GlobalContributors = new TypeList();
+ Languages = new List();
}
}
}
diff --git a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/DefaultLanguageProvider.cs b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/DefaultLanguageProvider.cs
new file mode 100644
index 0000000000..23af572fd0
--- /dev/null
+++ b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/DefaultLanguageProvider.cs
@@ -0,0 +1,22 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Microsoft.Extensions.Options;
+using Volo.Abp.DependencyInjection;
+
+namespace Volo.Abp.Localization
+{
+ public class DefaultLanguageProvider : ILanguageProvider, ITransientDependency
+ {
+ protected AbpLocalizationOptions Options { get; }
+
+ public DefaultLanguageProvider(IOptions options)
+ {
+ Options = options.Value;
+ }
+
+ public Task> GetLanguagesAsync()
+ {
+ return Task.FromResult((IReadOnlyList)Options.Languages);
+ }
+ }
+}
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/ILanguageProvider.cs b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/ILanguageProvider.cs
new file mode 100644
index 0000000000..e3e32114f0
--- /dev/null
+++ b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/ILanguageProvider.cs
@@ -0,0 +1,10 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+
+namespace Volo.Abp.Localization
+{
+ public interface ILanguageProvider
+ {
+ Task> GetLanguagesAsync();
+ }
+}
diff --git a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LanguageInfo.cs b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LanguageInfo.cs
new file mode 100644
index 0000000000..05c243f92c
--- /dev/null
+++ b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LanguageInfo.cs
@@ -0,0 +1,48 @@
+using System;
+using JetBrains.Annotations;
+
+namespace Volo.Abp.Localization
+{
+ public class LanguageInfo
+ {
+ [NotNull]
+ public virtual string CultureName { get; protected set; }
+
+ [NotNull]
+ public virtual string UiCultureName { get; protected set; }
+
+ [NotNull]
+ public virtual string DisplayName { get; protected set; }
+
+ [CanBeNull]
+ public virtual string FlagIcon { get; set; }
+
+ public LanguageInfo(
+ string cultureName,
+ string uiCultureName = null,
+ string displayName = null,
+ string flagIcon = null)
+ {
+ ChangeCultureInternal(cultureName, uiCultureName, displayName);
+ FlagIcon = flagIcon;
+ }
+
+ public virtual void ChangeCulture(string cultureName, string uiCultureName = null, string displayName = null)
+ {
+ ChangeCultureInternal(cultureName, uiCultureName, displayName);
+ }
+
+ private void ChangeCultureInternal(string cultureName, string uiCultureName, string displayName)
+ {
+ CultureName = Check.NotNullOrWhiteSpace(cultureName, nameof(cultureName));
+
+ UiCultureName = !uiCultureName.IsNullOrWhiteSpace()
+ ? uiCultureName
+ : cultureName;
+
+ DisplayName = !displayName.IsNullOrWhiteSpace()
+ ? displayName
+ : cultureName;
+ }
+ }
+}
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LanguageProviderExtensions.cs b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LanguageProviderExtensions.cs
new file mode 100644
index 0000000000..5c7ffe6508
--- /dev/null
+++ b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LanguageProviderExtensions.cs
@@ -0,0 +1,13 @@
+using System.Collections.Generic;
+using Volo.Abp.Threading;
+
+namespace Volo.Abp.Localization
+{
+ public static class LanguageProviderExtensions
+ {
+ public static IReadOnlyList GetLanguages(this ILanguageProvider languageProvider)
+ {
+ return AsyncHelper.RunSync(() => languageProvider.GetLanguagesAsync());
+ }
+ }
+}
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizationSettingNames.cs b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizationSettingNames.cs
new file mode 100644
index 0000000000..1b53f8c3bb
--- /dev/null
+++ b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizationSettingNames.cs
@@ -0,0 +1,7 @@
+namespace Volo.Abp.Localization
+{
+ public static class LocalizationSettingNames
+ {
+ public const string DefaultLanguage = "Abp.Localization.DefaultLanguage";
+ }
+}
diff --git a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizationSettingProvider.cs b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizationSettingProvider.cs
new file mode 100644
index 0000000000..c748156506
--- /dev/null
+++ b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizationSettingProvider.cs
@@ -0,0 +1,14 @@
+using Volo.Abp.Settings;
+
+namespace Volo.Abp.Localization
+{
+ public class LocalizationSettingProvider : SettingDefinitionProvider
+ {
+ public override void Define(ISettingDefinitionContext context)
+ {
+ context.Add(
+ new SettingDefinition(LocalizationSettingNames.DefaultLanguage, "en", isVisibleToClients: true)
+ );
+ }
+ }
+}
\ No newline at end of file