Browse Source

Introduce ILanguageProvider, UseAbpRequestLocalization

pull/395/head
Halil ibrahim Kalkan 8 years ago
parent
commit
2d8d2075cd
  1. 2
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Components/Toolbar/LanguageSwitch/Default.cshtml
  2. 11
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Components/Toolbar/LanguageSwitch/LanguageInfo.cs
  3. 51
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Components/Toolbar/LanguageSwitch/LanguageSwitchViewComponent.cs
  4. 8
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Components/Toolbar/LanguageSwitch/LanguageSwitchViewComponentModel.cs
  5. 11
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Toolbars/BasicThemeMainTopToolbarContributor.cs
  6. 73
      framework/src/Volo.Abp.AspNetCore/Microsoft/AspNetCore/Builder/AbpApplicationBuilderExtensions.cs
  7. 1
      framework/src/Volo.Abp.AspNetCore/Volo.Abp.AspNetCore.csproj
  8. 4
      framework/src/Volo.Abp.Localization/Volo.Abp.Localization.csproj
  9. 11
      framework/src/Volo.Abp.Localization/Volo/Abp/Localization/AbpLocalizationModule.cs
  10. 6
      framework/src/Volo.Abp.Localization/Volo/Abp/Localization/AbpLocalizationOptions.cs
  11. 22
      framework/src/Volo.Abp.Localization/Volo/Abp/Localization/DefaultLanguageProvider.cs
  12. 10
      framework/src/Volo.Abp.Localization/Volo/Abp/Localization/ILanguageProvider.cs
  13. 48
      framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LanguageInfo.cs
  14. 13
      framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LanguageProviderExtensions.cs
  15. 7
      framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizationSettingNames.cs
  16. 14
      framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizationSettingProvider.cs

2
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Components/Toolbar/LanguageSwitch/Default.cshtml

@ -8,7 +8,7 @@
<div class="dropdown-menu" aria-labelledby="dropdownMenuLink"> <div class="dropdown-menu" aria-labelledby="dropdownMenuLink">
@foreach (var language in Model.OtherLanguages) @foreach (var language in Model.OtherLanguages)
{ {
<a class="dropdown-item" href="/Abp/Languages/Switch?culture=@(language.Name)&uiCulture=@(language.Name)">@language.DisplayName</a> <a class="dropdown-item" href="/Abp/Languages/Switch?culture=@(language.CultureName)&uiCulture=@(language.UiCultureName)">@language.DisplayName</a>
} }
</div> </div>
</div> </div>

11
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Components/Toolbar/LanguageSwitch/LanguageInfo.cs

@ -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; }
}
}

51
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.Builder;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options; using Microsoft.Extensions.Options;
using Volo.Abp.Localization;
namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Themes.Basic.Components.Toolbar.LanguageSwitch namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Themes.Basic.Components.Toolbar.LanguageSwitch
{ {
public class LanguageSwitchViewComponent : AbpViewComponent public class LanguageSwitchViewComponent : AbpViewComponent
{ {
private readonly RequestLocalizationOptions _options; private readonly ILanguageProvider _languageProvider;
public LanguageSwitchViewComponent(IOptions<RequestLocalizationOptions> options) public LanguageSwitchViewComponent(ILanguageProvider languageProvider)
{ {
_options = options.Value; _languageProvider = languageProvider;
} }
public IViewComponentResult Invoke() public async Task<IViewComponentResult> InvokeAsync()
{ {
//TODO: Better handle culture & uiculture separation! var languages = await _languageProvider.GetLanguagesAsync();
var currentLanguage = FindCurrentLanguage(languages);
var model = new LanguageSwitchViewComponentModel var model = new LanguageSwitchViewComponentModel
{ {
CurrentLanguage = new LanguageInfo CurrentLanguage = currentLanguage,
{ OtherLanguages = languages.Where(l => l != currentLanguage).ToList()
Name = CultureInfo.CurrentUICulture.Name,
DisplayName = CultureInfo.CurrentUICulture.DisplayName,
Icon = null //TODO!
}
}; };
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); return View("~/Themes/Basic/Components/Toolbar/LanguageSwitch/Default.cshtml", model);
} }
private LanguageInfo FindCurrentLanguage(IReadOnlyList<LanguageInfo> 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);
}
} }
} }

8
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 System.Collections.Generic;
using Volo.Abp.Localization;
namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Themes.Basic.Components.Toolbar.LanguageSwitch 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 LanguageInfo CurrentLanguage { get; set; }
public List<LanguageInfo> OtherLanguages { get; } public List<LanguageInfo> OtherLanguages { get; set; }
public LanguageSwitchViewComponentModel()
{
OtherLanguages = new List<LanguageInfo>();
}
} }
} }

11
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Toolbars/BasicThemeMainTopToolbarContributor.cs

@ -1,11 +1,9 @@
using System.Linq; using System.Threading.Tasks;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection; 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.LanguageSwitch;
using Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Themes.Basic.Components.Toolbar.UserMenu; 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.AspNetCore.Mvc.UI.Theme.Shared.Toolbars;
using Volo.Abp.Localization;
using Volo.Abp.Users; using Volo.Abp.Users;
namespace Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic.Toolbars 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; return Task.CompletedTask;
} }
var requestLocalizationOptions = context.ServiceProvider.GetService<IOptions<RequestLocalizationOptions>>(); var languageProvider = context.ServiceProvider.GetService<ILanguageProvider>();
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))); context.Toolbar.Items.Add(new ToolbarItem(typeof(LanguageSwitchViewComponent)));
} }

73
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 Microsoft.Extensions.DependencyInjection;
using Volo.Abp; using Volo.Abp;
using Volo.Abp.AspNetCore.Auditing; using Volo.Abp.AspNetCore.Auditing;
using Volo.Abp.AspNetCore.Mvc.ExceptionHandling; using Volo.Abp.AspNetCore.Mvc.ExceptionHandling;
using Volo.Abp.AspNetCore.Uow; using Volo.Abp.AspNetCore.Uow;
using Volo.Abp.DependencyInjection; using Volo.Abp.DependencyInjection;
using Volo.Abp.Localization;
using Volo.Abp.Settings;
using Volo.Abp.Threading;
namespace Microsoft.AspNetCore.Builder namespace Microsoft.AspNetCore.Builder
{ {
public static class AbpApplicationBuilderExtensions public static class AbpApplicationBuilderExtensions
{ {
private const string ExceptionHandlingMiddlewareMarker = "_AbpExceptionHandlingMiddleware_Added";
public static void InitializeApplication([NotNull] this IApplicationBuilder app) public static void InitializeApplication([NotNull] this IApplicationBuilder app)
{ {
Check.NotNull(app, nameof(app)); Check.NotNull(app, nameof(app));
@ -31,16 +40,72 @@ namespace Microsoft.AspNetCore.Builder
.UseMiddleware<AbpUnitOfWorkMiddleware>(); .UseMiddleware<AbpUnitOfWorkMiddleware>();
} }
public static IApplicationBuilder UseAbpRequestLocalization(this IApplicationBuilder app)
{
IReadOnlyList<LanguageInfo> languages;
string defaultLanguage;
using (var scope = app.ApplicationServices.CreateScope())
{
var languageProvider = scope.ServiceProvider.GetRequiredService<ILanguageProvider>();
var settingManager = scope.ServiceProvider.GetRequiredService<ISettingManager>();
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) public static IApplicationBuilder UseAbpExceptionHandling(this IApplicationBuilder app)
{ {
//Prevent multiple add if (app.Properties.ContainsKey(ExceptionHandlingMiddlewareMarker))
if (app.Properties.ContainsKey("_AbpExceptionHandlingMiddleware_Added")) //TODO: Constant
{ {
return app; return app;
} }
app.Properties["_AbpExceptionHandlingMiddleware_Added"] = true; app.Properties[ExceptionHandlingMiddlewareMarker] = true;
return app.UseMiddleware<AbpExceptionHandlingMiddleware>(); return app.UseMiddleware<AbpExceptionHandlingMiddleware>();
} }
private static RequestCulture DefaultGetRequestCulture(string defaultLanguage, IReadOnlyList<LanguageInfo> 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]);
}
} }
} }

1
framework/src/Volo.Abp.AspNetCore/Volo.Abp.AspNetCore.csproj

@ -32,6 +32,7 @@
<PackageReference Include="Microsoft.AspNetCore.Http" Version="2.1.0" /> <PackageReference Include="Microsoft.AspNetCore.Http" Version="2.1.0" />
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.1.0" /> <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.1.0" />
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.1.0" /> <PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.1.0" />
<PackageReference Include="Microsoft.AspNetCore.Localization" Version="2.1.0" />
</ItemGroup> </ItemGroup>
</Project> </Project>

4
framework/src/Volo.Abp.Localization/Volo.Abp.Localization.csproj

@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk"> <Project Sdk="Microsoft.NET.Sdk">
<Import Project="..\..\..\common.props" /> <Import Project="..\..\..\common.props" />
@ -22,7 +22,7 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\Volo.Abp.Core\Volo.Abp.Core.csproj" /> <ProjectReference Include="..\Volo.Abp.Settings\Volo.Abp.Settings.csproj" />
<ProjectReference Include="..\Volo.Abp.VirtualFileSystem\Volo.Abp.VirtualFileSystem.csproj" /> <ProjectReference Include="..\Volo.Abp.VirtualFileSystem\Volo.Abp.VirtualFileSystem.csproj" />
</ItemGroup> </ItemGroup>

11
framework/src/Volo.Abp.Localization/Volo/Abp/Localization/AbpLocalizationModule.cs

@ -1,11 +1,15 @@
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
using Volo.Abp.Localization.Resources.AbpValidation; using Volo.Abp.Localization.Resources.AbpValidation;
using Volo.Abp.Modularity; using Volo.Abp.Modularity;
using Volo.Abp.Settings;
using Volo.Abp.VirtualFileSystem; using Volo.Abp.VirtualFileSystem;
namespace Volo.Abp.Localization namespace Volo.Abp.Localization
{ {
[DependsOn(typeof(AbpVirtualFileSystemModule))] [DependsOn(
typeof(AbpVirtualFileSystemModule),
typeof(AbpSettingsModule)
)]
public class AbpLocalizationModule : AbpModule public class AbpLocalizationModule : AbpModule
{ {
public override void ConfigureServices(ServiceConfigurationContext context) public override void ConfigureServices(ServiceConfigurationContext context)
@ -24,6 +28,11 @@ namespace Volo.Abp.Localization
.AddVirtualJson("/Localization/Resources/AbpValidation"); .AddVirtualJson("/Localization/Resources/AbpValidation");
}); });
context.Services.Configure<SettingOptions>(options =>
{
options.DefinitionProviders.Add<LocalizationSettingProvider>();
});
context.Services.AddAssemblyOf<AbpLocalizationModule>(); context.Services.AddAssemblyOf<AbpLocalizationModule>();
} }
} }

6
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 namespace Volo.Abp.Localization
{ {
@ -8,10 +9,13 @@ namespace Volo.Abp.Localization
public ITypeList<ILocalizationResourceContributor> GlobalContributors { get; } public ITypeList<ILocalizationResourceContributor> GlobalContributors { get; }
public List<LanguageInfo> Languages { get; }
public AbpLocalizationOptions() public AbpLocalizationOptions()
{ {
Resources = new LocalizationResourceDictionary(); Resources = new LocalizationResourceDictionary();
GlobalContributors = new TypeList<ILocalizationResourceContributor>(); GlobalContributors = new TypeList<ILocalizationResourceContributor>();
Languages = new List<LanguageInfo>();
} }
} }
} }

22
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<AbpLocalizationOptions> options)
{
Options = options.Value;
}
public Task<IReadOnlyList<LanguageInfo>> GetLanguagesAsync()
{
return Task.FromResult((IReadOnlyList<LanguageInfo>)Options.Languages);
}
}
}

10
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<IReadOnlyList<LanguageInfo>> GetLanguagesAsync();
}
}

48
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;
}
}
}

13
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<LanguageInfo> GetLanguages(this ILanguageProvider languageProvider)
{
return AsyncHelper.RunSync(() => languageProvider.GetLanguagesAsync());
}
}
}

7
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";
}
}

14
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)
);
}
}
}
Loading…
Cancel
Save