From 46d0d4eba34cd2170d981530bd46f2c85ea41e5d Mon Sep 17 00:00:00 2001 From: maliming <6908465+maliming@users.noreply.github.com> Date: Mon, 18 May 2020 14:23:17 +0800 Subject: [PATCH] "L" function in the text template rendering system should support parametric text. Resolve #3977 --- .../Abp/TextTemplating/TemplateLocalizer.cs | 50 +++++++++++++++++++ .../Abp/TextTemplating/TemplateRenderer.cs | 9 +--- .../Abp/TextTemplating/Localization/en.json | 7 +-- .../Abp/TextTemplating/Localization/tr.json | 7 +-- .../SampleTemplates/ForgotPasswordEmail.tpl | 2 +- .../TextTemplating/TemplateRenderer_Tests.cs | 21 +++++++- 6 files changed, 80 insertions(+), 16 deletions(-) create mode 100644 framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateLocalizer.cs diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateLocalizer.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateLocalizer.cs new file mode 100644 index 0000000000..c3c67dd194 --- /dev/null +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateLocalizer.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading.Tasks; +using Microsoft.Extensions.Localization; +using Scriban; +using Scriban.Runtime; +using Scriban.Syntax; + +namespace Volo.Abp.TextTemplating +{ + public class TemplateLocalizer : IScriptCustomFunction + { + private readonly IStringLocalizer _localizer; + + public TemplateLocalizer(IStringLocalizer localizer) + { + _localizer = localizer; + } + + public object Invoke(TemplateContext context, ScriptNode callerContext, ScriptArray arguments, + ScriptBlockStatement blockStatement) + { + return GetString(arguments); + } + + public ValueTask InvokeAsync(TemplateContext context, ScriptNode callerContext, ScriptArray arguments, + ScriptBlockStatement blockStatement) + { + return new ValueTask(GetString(arguments)); + } + + private string GetString(ScriptArray arguments) + { + if (arguments.IsNullOrEmpty()) + { + return string.Empty; + } + + var name = arguments[0]; + if (name == null || name.ToString().IsNullOrWhiteSpace()) + { + return string.Empty; + } + + var args = arguments.Skip(1).Where(x => x != null && !x.ToString().IsNullOrWhiteSpace()).ToArray(); + return args.Any() ? _localizer[name.ToString(), args] : _localizer[name.ToString()]; + } + } +} diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateRenderer.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateRenderer.cs index 86eb684f52..c7d7b9d016 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateRenderer.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateRenderer.cs @@ -140,12 +140,7 @@ namespace Volo.Abp.TextTemplating var localizer = GetLocalizerOrNull(templateDefinition); if (localizer != null) { - scriptObject.Import( - "L", - new Func( - name => localizer[name] - ) - ); + scriptObject.SetValue("L", new TemplateLocalizer(localizer), true); } context.PushGlobal(scriptObject); @@ -163,4 +158,4 @@ namespace Volo.Abp.TextTemplating return _stringLocalizerFactory.CreateDefaultOrNull(); } } -} \ No newline at end of file +} diff --git a/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/Localization/en.json b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/Localization/en.json index a0dff7e930..441661716c 100644 --- a/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/Localization/en.json +++ b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/Localization/en.json @@ -1,6 +1,7 @@ { "culture": "en", "texts": { - "HelloText": "Hello" - } -} \ No newline at end of file + "HelloText": "Hello {0}", + "HowAreYou": "how are you?" + } +} diff --git a/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/Localization/tr.json b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/Localization/tr.json index d09f02cd8f..60e5da8fa0 100644 --- a/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/Localization/tr.json +++ b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/Localization/tr.json @@ -1,6 +1,7 @@ { "culture": "tr", "texts": { - "HelloText": "Merhaba" - } -} \ No newline at end of file + "HelloText": "Merhaba {0}", + "HowAreYou": "nasılsın?" + } +} diff --git a/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/SampleTemplates/ForgotPasswordEmail.tpl b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/SampleTemplates/ForgotPasswordEmail.tpl index 8bcab86d0f..6e5fcbe6e1 100644 --- a/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/SampleTemplates/ForgotPasswordEmail.tpl +++ b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/SampleTemplates/ForgotPasswordEmail.tpl @@ -1 +1 @@ -{{L "HelloText"}}. Please click to the following link to get an email to reset your password! \ No newline at end of file +{{L "HelloText" model.name}}, {{L "HowAreYou" }}. Please click to the following link to get an email to reset your password! \ No newline at end of file diff --git a/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/TemplateRenderer_Tests.cs b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/TemplateRenderer_Tests.cs index 14b3df3486..fef287a2b1 100644 --- a/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/TemplateRenderer_Tests.cs +++ b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/TemplateRenderer_Tests.cs @@ -81,13 +81,15 @@ namespace Volo.Abp.TextTemplating { (await _templateRenderer.RenderAsync( TestTemplates.ForgotPasswordEmail, + new ForgotPasswordEmailModel("John"), cultureName: "en" - )).ShouldBe("*BEGIN*Hello. Please click to the following link to get an email to reset your password!*END*"); + )).ShouldBe("*BEGIN*Hello John, how are you?. Please click to the following link to get an email to reset your password!*END*"); (await _templateRenderer.RenderAsync( TestTemplates.ForgotPasswordEmail, + model: new Dictionary() { { "name", "John" } }, cultureName: "tr" - )).ShouldBe("*BEGIN*Merhaba. Please click to the following link to get an email to reset your password!*END*"); + )).ShouldBe("*BEGIN*Merhaba John, nasılsın?. Please click to the following link to get an email to reset your password!*END*"); } private class WelcomeEmailModel @@ -104,5 +106,20 @@ namespace Volo.Abp.TextTemplating Name = name; } } + + private class ForgotPasswordEmailModel + { + public string Name { get; set; } + + public ForgotPasswordEmailModel() + { + + } + + public ForgotPasswordEmailModel(string name) + { + Name = name; + } + } } }