From e3e16ffa0fd5f6455ea4ee09c45f564d16bde9c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Wed, 31 Aug 2022 16:02:05 +0300 Subject: [PATCH] MVC UI: Get localization from the new endpoint. Handle base resources in MVC UI. --- ...blyCachedApplicationConfigurationClient.cs | 6 +- ...pplicationConfigurationScriptController.cs | 12 +-- .../AbpApplicationLocalizationAppService.cs | 4 +- ...ApplicationLocalizationScriptController.cs | 45 ++++++++-- .../Themes/Basic/Layouts/Account.cshtml | 1 + .../Themes/Basic/Layouts/Application.cshtml | 1 + .../Themes/Basic/Layouts/Empty.cshtml | 1 + npm/packs/core/src/abp.js | 90 ++++++++++++------- 8 files changed, 116 insertions(+), 44 deletions(-) diff --git a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/WebAssemblyCachedApplicationConfigurationClient.cs b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/WebAssemblyCachedApplicationConfigurationClient.cs index 523a770a17..b362d70bd0 100644 --- a/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/WebAssemblyCachedApplicationConfigurationClient.cs +++ b/framework/src/Volo.Abp.AspNetCore.Components.WebAssembly/Volo/Abp/AspNetCore/Components/WebAssembly/WebAssemblyCachedApplicationConfigurationClient.cs @@ -27,7 +27,11 @@ public class WebAssemblyCachedApplicationConfigurationClient : ICachedApplicatio public virtual async Task InitializeAsync() { - var configurationDto = await ApplicationConfigurationAppService.GetAsync(); + var configurationDto = await ApplicationConfigurationAppService.GetAsync( + new ApplicationConfigurationRequestOptions { + IncludeLocalizationResources = false + } + ); Cache.Set(configurationDto); diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationScriptController.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationScriptController.cs index 645da03b56..791f5ca262 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationScriptController.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationConfigurationScriptController.cs @@ -41,11 +41,13 @@ public class AbpApplicationConfigurationScriptController : AbpController [Produces(MimeTypes.Application.Javascript, MimeTypes.Text.Plain)] public async Task Get() { - var script = CreateAbpExtendScript(await _configurationAppService.GetAsync( - new ApplicationConfigurationRequestOptions { - IncludeLocalizationResources = false - } - )); + var script = CreateAbpExtendScript( + await _configurationAppService.GetAsync( + new ApplicationConfigurationRequestOptions { + IncludeLocalizationResources = false + } + ) + ); _antiForgeryManager.SetCookie(); diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationLocalizationAppService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationLocalizationAppService.cs index 404186c254..5cfc96d8af 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationLocalizationAppService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/ApplicationConfigurations/AbpApplicationLocalizationAppService.cs @@ -48,8 +48,8 @@ public class AbpApplicationLocalizationAppService : { var localizedStrings = await localizer.GetAllStringsAsync( includeParentCultures: true, - includeBaseLocalizers: true, //TODO: Test this! - includeDynamicContributors: false + includeBaseLocalizers: false, + includeDynamicContributors: true ); foreach (var localizedString in localizedStrings) diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Localization/AbpApplicationLocalizationScriptController.cs b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Localization/AbpApplicationLocalizationScriptController.cs index 550d29e2c4..30a10b03ab 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Localization/AbpApplicationLocalizationScriptController.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc/Volo/Abp/AspNetCore/Mvc/Localization/AbpApplicationLocalizationScriptController.cs @@ -1,4 +1,5 @@ using System; +using System.Text; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Localization; @@ -6,7 +7,9 @@ using Microsoft.Extensions.Options; using Volo.Abp.AspNetCore.Mvc.ApplicationConfigurations; using Volo.Abp.Auditing; using Volo.Abp.Http; +using Volo.Abp.Json; using Volo.Abp.Localization; +using Volo.Abp.Minify.Scripts; namespace Volo.Abp.AspNetCore.Mvc.Localization; @@ -17,19 +20,51 @@ namespace Volo.Abp.AspNetCore.Mvc.Localization; [ApiExplorerSettings(IgnoreApi = true)] public class AbpApplicationLocalizationScriptController : AbpController { - protected IAbpApplicationLocalizationAppService LocalizationAppService { get; } + protected IAbpApplicationLocalizationAppService LocalizationAppService { get; } + protected AbpAspNetCoreMvcOptions Options { get; } + protected IJsonSerializer JsonSerializer { get; } + protected IJavascriptMinifier JavascriptMinifier { get; } public AbpApplicationLocalizationScriptController( - IAbpApplicationLocalizationAppService localizationAppService) + IAbpApplicationLocalizationAppService localizationAppService, + IOptions options, + IJsonSerializer jsonSerializer, + IJavascriptMinifier javascriptMinifier) { LocalizationAppService = localizationAppService; + JsonSerializer = jsonSerializer; + JavascriptMinifier = javascriptMinifier; + Options = options.Value; } - + [HttpGet] [Route("{culture}")] [Produces(MimeTypes.Application.Javascript, MimeTypes.Text.Plain)] - public async Task GetAsync(string culture) + public async Task GetAsync(string culture) { - throw new NotImplementedException(); + var script = CreateScript( + await LocalizationAppService.GetAsync(culture) + ); + + return Content( + Options.MinifyGeneratedScript == true + ? JavascriptMinifier.Minify(script) + : script, + MimeTypes.Application.Javascript + ); + } + + private string CreateScript(ApplicationLocalizationDto localizationDto) + { + var script = new StringBuilder(); + + script.AppendLine("(function(){"); + script.AppendLine(); + script.AppendLine( + $"$.extend(true, abp.localization, {JsonSerializer.Serialize(localizationDto, indented: true)})"); + script.AppendLine(); + script.Append("})();"); + + return script.ToString(); } } \ No newline at end of file diff --git a/modules/basic-theme/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Layouts/Account.cshtml b/modules/basic-theme/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Layouts/Account.cshtml index f71171912c..a4e73620b6 100644 --- a/modules/basic-theme/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Layouts/Account.cshtml +++ b/modules/basic-theme/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Layouts/Account.cshtml @@ -95,6 +95,7 @@ + diff --git a/modules/basic-theme/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Layouts/Application.cshtml b/modules/basic-theme/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Layouts/Application.cshtml index 539873ce4b..a29dea32dd 100644 --- a/modules/basic-theme/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Layouts/Application.cshtml +++ b/modules/basic-theme/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Layouts/Application.cshtml @@ -68,6 +68,7 @@ + diff --git a/modules/basic-theme/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Layouts/Empty.cshtml b/modules/basic-theme/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Layouts/Empty.cshtml index 70c7d5e1e8..9dd3cb4a21 100644 --- a/modules/basic-theme/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Layouts/Empty.cshtml +++ b/modules/basic-theme/src/Volo.Abp.AspNetCore.Mvc.UI.Theme.Basic/Themes/Basic/Layouts/Empty.cshtml @@ -63,6 +63,7 @@ + diff --git a/npm/packs/core/src/abp.js b/npm/packs/core/src/abp.js index 0348069bec..074d4f0f50 100644 --- a/npm/packs/core/src/abp.js +++ b/npm/packs/core/src/abp.js @@ -72,8 +72,61 @@ var abp = abp || {}; /* LOCALIZATION ***********************************************/ abp.localization = abp.localization || {}; - + abp.localization.internal = abp.localization.internal || {}; abp.localization.values = abp.localization.values || {}; + abp.localization.resources = abp.localization.resources || {}; + + abp.localization.internal.getResource = function (resourceName) { + var resource = abp.localization.resources[resourceName]; + if (resource) { + return resource; + } + + var legacySource = abp.localization.values[resourceName]; + if (legacySource) { + return { + texts: abp.localization.values[resourceName], + baseResources: [] + }; + } + + abp.log.warn('Could not find localization source: ' + resourceName); + return null; + }; + + abp.localization.internal.localize = function (key, sourceName) { + var resource = abp.localization.internal.getResource(sourceName); + if (!resource){ + return { + value: key, + found: false + }; + } + + var value = resource.texts[key]; + if (value === undefined) { + for (var i = 0; i < resource.baseResources.length; i++){ + var result = abp.localization.internal.localize(key, resource.baseResources[i]); + if (result.found){ + return result; + } + } + + return { + value: key, + found: false + }; + } + + var copiedArguments = Array.prototype.slice.call(arguments, 0); + copiedArguments.splice(1, 1); + copiedArguments[0] = value; + + return { + value: abp.utils.formatString.apply(this, copiedArguments), + found: true + }; + }; abp.localization.localize = function (key, sourceName) { if (sourceName === '_') { //A convention to suppress the localization @@ -86,22 +139,7 @@ var abp = abp || {}; return key; } - var source = abp.localization.values[sourceName]; - if (!source) { - abp.log.warn('Could not find localization source: ' + sourceName); - return key; - } - - var value = source[key]; - if (value == undefined) { - return key; - } - - var copiedArguments = Array.prototype.slice.call(arguments, 0); - copiedArguments.splice(1, 1); - copiedArguments[0] = value; - - return abp.utils.formatString.apply(this, copiedArguments); + return abp.localization.internal.localize(key, sourceName).value; }; abp.localization.isLocalized = function (key, sourceName) { @@ -114,17 +152,7 @@ var abp = abp || {}; return false; } - var source = abp.localization.values[sourceName]; - if (!source) { - return false; - } - - var value = source[key]; - if (value === undefined) { - return false; - } - - return true; + return abp.localization.internal.localize(key, sourceName).found; }; abp.localization.getResource = function (name) { @@ -687,7 +715,7 @@ var abp = abp || {}; } /** - * Escape HTML to help prevent XSS attacks. + * Escape HTML to help prevent XSS attacks. */ abp.utils.htmlEscape = function (html) { return typeof html === 'string' ? html.replace(/&/g, '&').replace(//g, '>').replace(/"/g, '"') : html; @@ -759,7 +787,7 @@ var abp = abp || {}; return toUtc(date); } }; - + /* FEATURES *************************************************/ abp.features = abp.features || {}; @@ -774,7 +802,7 @@ var abp = abp || {}; abp.features.get = function (name) { return abp.features.values[name]; }; - + /* GLOBAL FEATURES *************************************************/ abp.globalFeatures = abp.globalFeatures || {};