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">
@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>

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.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<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
{
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<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 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<LanguageInfo> OtherLanguages { get; }
public LanguageSwitchViewComponentModel()
{
OtherLanguages = new List<LanguageInfo>();
}
public List<LanguageInfo> OtherLanguages { get; set; }
}
}

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

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 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<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)
{
//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<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.Extensions.Configuration.Json" Version="2.1.0" />
<PackageReference Include="Microsoft.AspNetCore.StaticFiles" Version="2.1.0" />
<PackageReference Include="Microsoft.AspNetCore.Localization" Version="2.1.0" />
</ItemGroup>
</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" />
@ -22,7 +22,7 @@
</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" />
</ItemGroup>

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