Browse Source

Merge pull request #4360 from abpframework/maliming/LocalizationMap

Add Languages/LanguageFiles map feature.
pull/4453/head
Halil İbrahim Kalkan 6 years ago
committed by GitHub
parent
commit
f9260aa1b8
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ApplicationLocalizationConfigurationDto.cs
  2. 31
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/BundleConfigurationContext.cs
  3. 14
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/AbpAspNetCoreMvcUiPackagesModule.cs
  4. 21
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/BootstrapDatepicker/BootstrapDatepickerScriptContributor.cs
  5. 15
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/JQueryValidation/JQueryValidationScriptContributor.cs
  6. 30
      framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/bootstrap/dom-event-handlers.js
  7. 5
      framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationAppService.cs
  8. 6
      framework/src/Volo.Abp.Localization/Volo/Abp/Localization/AbpLocalizationOptions.cs
  9. 58
      framework/src/Volo.Abp.Localization/Volo/Abp/Localization/AbpLocalizationOptionsExtensions.cs
  10. 36
      npm/packs/core/src/abp.js

6
framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/ApplicationLocalizationConfigurationDto.cs

@ -16,10 +16,14 @@ namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations
public string DefaultResourceName { get; set; }
public Dictionary<string, List<NameValue>> LanguagesMap { get; set; }
public Dictionary<string, List<NameValue>> LanguageFilesMap { get; set; }
public ApplicationLocalizationConfigurationDto()
{
Values = new Dictionary<string, Dictionary<string, string>>();
Languages = new List<LanguageInfo>();
}
}
}
}

31
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Bundling/Volo/Abp/AspNetCore/Mvc/UI/Bundling/BundleConfigurationContext.cs

@ -1,6 +1,9 @@
using System;
using System.Collections.Generic;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Options;
using Volo.Abp.Localization;
namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling
{
@ -8,8 +11,6 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling
{
public List<string> Files { get; }
public IServiceProvider ServiceProvider { get; }
public IFileProvider FileProvider { get; }
public BundleConfigurationContext(IServiceProvider serviceProvider, IFileProvider fileProvider)
@ -18,5 +19,29 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Bundling
ServiceProvider = serviceProvider;
FileProvider = fileProvider;
}
public IServiceProvider ServiceProvider { get; }
private readonly object _serviceProviderLock = new object();
private TRef LazyGetRequiredService<TRef>(Type serviceType, ref TRef reference)
{
if (reference == null)
{
lock (_serviceProviderLock)
{
if (reference == null)
{
reference = (TRef)ServiceProvider.GetRequiredService(serviceType);
}
}
}
return reference;
}
private IOptions<AbpLocalizationOptions> _abpLocalizationOptions;
public AbpLocalizationOptions LocalizationOptions =>
LazyGetRequiredService(typeof(IOptions<AbpLocalizationOptions>), ref _abpLocalizationOptions).Value;
}
}
}

14
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/AbpAspNetCoreMvcUiPackagesModule.cs

@ -1,4 +1,6 @@
using Volo.Abp.AspNetCore.Mvc.UI.Bundling;
using Volo.Abp.AspNetCore.Mvc.UI.Packages.BootstrapDatepicker;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
namespace Volo.Abp.AspNetCore.Mvc.UI.Packages
@ -6,6 +8,18 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Packages
[DependsOn(typeof(AbpAspNetCoreMvcUiBundlingModule))]
public class AbpAspNetCoreMvcUiPackagesModule : AbpModule
{
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure<AbpLocalizationOptions>(options =>
{
options.AddLanguagesMapOrUpdate(BootstrapDatepickerScriptContributor.PackageName,
new NameValue("zh-Hans", "zh-CN"),
new NameValue("zh-Hant", "zh-TW"));
options.AddLanguageFilesMapOrUpdate(BootstrapDatepickerScriptContributor.PackageName,
new NameValue("zh-Hans", "zh-CN"),
new NameValue("zh-Hant", "zh-TW"));
});
}
}
}

21
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/BootstrapDatepicker/BootstrapDatepickerScriptContributor.cs

@ -1,7 +1,8 @@
using System.Collections.Generic;
using System.Collections.Generic;
using System.Globalization;
using Volo.Abp.AspNetCore.Mvc.UI.Bundling;
using Volo.Abp.AspNetCore.Mvc.UI.Packages.JQuery;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
namespace Volo.Abp.AspNetCore.Mvc.UI.Packages.BootstrapDatepicker
@ -9,11 +10,8 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Packages.BootstrapDatepicker
[DependsOn(typeof(JQueryScriptContributor))]
public class BootstrapDatepickerScriptContributor : BundleContributor
{
public static readonly Dictionary<string, string> CultureMap = new Dictionary<string, string>
{
{"zh-Hans", "zh-CN"}
};
public const string PackageName = "bootstrap-datepicker";
public override void ConfigureBundle(BundleConfigurationContext context)
{
context.Files.AddIfNotContains("/libs/bootstrap-datepicker/bootstrap-datepicker.min.js");
@ -26,12 +24,13 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Packages.BootstrapDatepicker
? "en"
: CultureInfo.CurrentUICulture.Name;
TryAddCultureFile(context, MapCultureName(cultureName));
TryAddCultureFile(context, cultureName);
}
protected virtual bool TryAddCultureFile(BundleConfigurationContext context, string cultureName)
{
var filePath = $"/libs/bootstrap-datepicker/locales/bootstrap-datepicker.{cultureName}.min.js";
var fileName = context.LocalizationOptions.GetLanguageFilesMap(PackageName, cultureName);
var filePath = $"/libs/bootstrap-datepicker/locales/bootstrap-datepicker.{fileName}.min.js";
if (!context.FileProvider.GetFileInfo(filePath).Exists)
{
@ -41,11 +40,5 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Packages.BootstrapDatepicker
context.Files.AddIfNotContains(filePath);
return true;
}
protected virtual string MapCultureName(string cultureName)
{
return CultureMap.GetOrDefault(cultureName) ??
cultureName;
}
}
}

15
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Packages/Volo/Abp/AspNetCore/Mvc/UI/Packages/JQueryValidation/JQueryValidationScriptContributor.cs

@ -2,6 +2,7 @@
using System.Globalization;
using Volo.Abp.AspNetCore.Mvc.UI.Bundling;
using Volo.Abp.AspNetCore.Mvc.UI.Packages.JQuery;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
namespace Volo.Abp.AspNetCore.Mvc.UI.Packages.JQueryValidation
@ -11,6 +12,8 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Packages.JQueryValidation
{
public const string DefaultLocalizationFolder = "/libs/jquery-validation/localization/";
public const string PackageName = "jquery-validation";
public override void ConfigureBundle(BundleConfigurationContext context)
{
context.Files.AddIfNotContains("/libs/jquery-validation/jquery.validate.js");
@ -25,7 +28,8 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Packages.JQueryValidation
var cultureName = CultureInfo.CurrentUICulture.TwoLetterISOLanguageName.Replace('-', '_');
if (TryAddCultureFile(context, MapCultureName(cultureName)))
var fileName = context.LocalizationOptions.GetLanguageFilesMap(PackageName, cultureName);
if (TryAddCultureFile(context, fileName))
{
return;
}
@ -35,7 +39,9 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Packages.JQueryValidation
return;
}
TryAddCultureFile(context, MapCultureName(cultureName.Substring(0, cultureName.IndexOf('_'))));
fileName = context.LocalizationOptions.GetLanguageFilesMap(PackageName,
cultureName.Substring(0, cultureName.IndexOf('_')));
TryAddCultureFile(context, fileName);
}
protected virtual bool TryAddCultureFile(BundleConfigurationContext context, string cultureName)
@ -51,10 +57,5 @@ namespace Volo.Abp.AspNetCore.Mvc.UI.Packages.JQueryValidation
context.Files.AddIfNotContains(filePath);
return true;
}
protected virtual string MapCultureName(string cultureName)
{
return cultureName;
}
}
}

30
framework/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Shared/wwwroot/libs/abp/aspnetcore-mvc-ui-theme-shared/bootstrap/dom-event-handlers.js

@ -1,4 +1,4 @@
(function ($) {
(function ($) {
abp.dom = abp.dom || {};
@ -73,25 +73,12 @@
abp.libs = abp.libs = abp.libs || {};
abp.libs.bootstrapDatepicker = {
languageMap: {
'zh-Hans': 'zh-CN'
},
mapLanguageName: function (name) {
return abp.libs.bootstrapDatepicker.languageMap[abp.localization.currentCulture.name] || name;
},
isLanguageMapped: function (name) {
return abp.libs.bootstrapDatepicker.languageMap[abp.localization.currentCulture.name] !== undefined;
},
getCurrentLanguageConfig: function () {
var mappedName = abp.libs.bootstrapDatepicker.mapLanguageName(abp.localization.currentCulture.name);
return $.fn.datepicker.dates[mappedName];
},
packageName: "bootstrap-datepicker",
normalizeLanguageConfig: function () {
var languageConfig = abp.libs.bootstrapDatepicker.getCurrentLanguageConfig();
if (languageConfig) {
if (!languageConfig.format || abp.libs.bootstrapDatepicker.isLanguageMapped(abp.localization.currentCulture.name)) {
languageConfig.format = abp.localization.currentCulture.dateTimeFormat.shortDatePattern.toLowerCase();
}
var language = abp.localization.getLanguagesMap(this.packageName);
var languageConfig = $.fn.datepicker.dates[language];
if (languageConfig && (!languageConfig.format || language !== abp.localization.currentCulture.name)) {
languageConfig.format = abp.localization.currentCulture.dateTimeFormat.shortDatePattern.toLowerCase();
}
},
getFormattedValue: function (isoFormattedValue) {
@ -108,7 +95,7 @@
return {
todayBtn: "linked",
autoclose: true,
language: abp.libs.bootstrapDatepicker.mapLanguageName(abp.localization.currentCulture.cultureName)
language: abp.localization.getLanguagesMap(this.packageName)
};
}
};
@ -132,7 +119,6 @@
abp.dom.initializers.initializeToolTips(args.$el.findWithSelf('[data-toggle="tooltip"]'));
abp.dom.initializers.initializePopovers(args.$el.findWithSelf('[data-toggle="popover"]'));
abp.dom.initializers.initializeTimeAgos(args.$el.findWithSelf('.timeago'));
abp.dom.initializers.initializeDatepickers(args.$el);
abp.dom.initializers.initializeForms(args.$el.findWithSelf('form'), true);
abp.dom.initializers.initializeScript(args.$el);
});
@ -156,4 +142,4 @@
$('[data-auto-focus="true"]').first().findWithSelf('input,select').focus();
});
})(jQuery);
})(jQuery);

5
framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationAppService.cs

@ -171,6 +171,9 @@ namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations
);
}
localizationConfig.LanguagesMap = _localizationOptions.LanguagesMap;
localizationConfig.LanguageFilesMap = _localizationOptions.LanguageFilesMap;
return localizationConfig;
}
@ -267,4 +270,4 @@ namespace Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations
};
}
}
}
}

6
framework/src/Volo.Abp.Localization/Volo/Abp/Localization/AbpLocalizationOptions.cs

@ -17,11 +17,17 @@ namespace Volo.Abp.Localization
public List<LanguageInfo> Languages { get; }
public Dictionary<string, List<NameValue>> LanguagesMap { get; }
public Dictionary<string, List<NameValue>> LanguageFilesMap { get; }
public AbpLocalizationOptions()
{
Resources = new LocalizationResourceDictionary();
GlobalContributors = new TypeList<ILocalizationResourceContributor>();
Languages = new List<LanguageInfo>();
LanguagesMap = new Dictionary<string, List<NameValue>>();
LanguageFilesMap = new Dictionary<string, List<NameValue>>();
}
}
}

58
framework/src/Volo.Abp.Localization/Volo/Abp/Localization/AbpLocalizationOptionsExtensions.cs

@ -0,0 +1,58 @@
using System.Collections.Generic;
using System.Linq;
namespace Volo.Abp.Localization
{
public static class AbpLocalizationOptionsExtensions
{
public static AbpLocalizationOptions AddLanguagesMapOrUpdate(this AbpLocalizationOptions localizationOptions,
string packageName, params NameValue[] maps)
{
foreach (var map in maps)
{
AddOrUpdate(localizationOptions.LanguagesMap, packageName, map);
}
return localizationOptions;
}
public static string GetLanguagesMap(this AbpLocalizationOptions localizationOptions, string packageName,
string language)
{
return localizationOptions.LanguagesMap.TryGetValue(packageName, out var maps)
? maps.FirstOrDefault(x => x.Name == language)?.Value ?? language
: language;
}
public static AbpLocalizationOptions AddLanguageFilesMapOrUpdate(this AbpLocalizationOptions localizationOptions,
string packageName, params NameValue[] maps)
{
foreach (var map in maps)
{
AddOrUpdate(localizationOptions.LanguageFilesMap, packageName, map);
}
return localizationOptions;
}
public static string GetLanguageFilesMap(this AbpLocalizationOptions localizationOptions, string packageName,
string language)
{
return localizationOptions.LanguageFilesMap.TryGetValue(packageName, out var maps)
? maps.FirstOrDefault(x => x.Name == language)?.Value ?? language
: language;
}
private static void AddOrUpdate(IDictionary<string, List<NameValue>> maps, string packageName, NameValue value)
{
if (maps.TryGetValue(packageName, out var existMaps))
{
existMaps.GetOrAdd(x => x.Name == value.Name, () => value).Value = value.Value;
}
else
{
maps.Add(packageName, new List<NameValue> {value});
}
}
}
}

36
npm/packs/core/src/abp.js

@ -136,6 +136,38 @@ var abp = abp || {};
};
abp.localization.defaultResourceName = undefined;
abp.localization.currentCulture = {
cultureName: undefined
};
var getMapValue = function (packageMaps, packageName, language) {
language = language || abp.localization.currentCulture.name;
if (!packageMaps || !packageName || !language) {
return language;
}
var packageMap = packageMaps[packageName];
if (!packageMap) {
return language;
}
for (var i = 0; i < packageMap.length; i++) {
var map = packageMap[i];
if (map.name === language){
return map.value;
}
}
return language;
};
abp.localization.getLanguagesMap = function (packageName, language) {
return getMapValue(abp.localization.languagesMap, packageName, language);
};
abp.localization.getLanguageFilesMap = function (packageName, language) {
return getMapValue(abp.localization.languageFilesMap, packageName, language);
};
/* AUTHORIZATION **********************************************/
@ -330,7 +362,7 @@ var abp = abp || {};
};
/* opts: {
*
*
* }
*/
abp.ui.unblock = function (opts) {
@ -584,7 +616,7 @@ var abp = abp || {};
* This is a simple implementation created to be used by ABP.
* Please use a complete cookie library if you need.
* @param {string} key
* @param {string} value
* @param {string} value
* @param {Date} expireDate (optional). If not specified the cookie will expire at the end of session.
* @param {string} path (optional)
*/

Loading…
Cancel
Save