Browse Source

Merge pull request #3989 from abpframework/maliming/text-templating

"L" function in the text template rendering system should support parametric text.
pull/4016/head
Halil İbrahim Kalkan 6 years ago
committed by GitHub
parent
commit
69e464598e
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 8
      docs/en/Text-Templating.md
  2. 50
      framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateLocalizer.cs
  3. 9
      framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateRenderer.cs
  4. 7
      framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/Localization/en.json
  5. 7
      framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/Localization/tr.json
  6. 2
      framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/SampleTemplates/ForgotPasswordEmail.tpl
  7. 21
      framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/TemplateRenderer_Tests.cs

8
docs/en/Text-Templating.md

@ -204,13 +204,14 @@ Inline localization uses the [localization system](Localization.md) to localize
Assuming you need to send an email to a user to reset her/his password. Here, the template content: Assuming you need to send an email to a user to reset her/his password. Here, the template content:
```` ````
<a href="{%{{{model.link}}}%}">{%{{{L "ResetMyPassword"}}}%}</a> <a title="{%{{{L "ResetMyPasswordTitle"}}}%}" href="{%{{{model.link}}}%}">{%{{{L "ResetMyPassword" model.name}}}%}</a>
```` ````
`L` function is used to localize the given key based on the current user culture. You need to define the `ResetMyPassword` key inside your localization file: `L` function is used to localize the given key based on the current user culture. You need to define the `ResetMyPassword` key inside your localization file:
````json ````json
"ResetMyPassword": "Click here to reset your password" "ResetMyPasswordTitle": "Reset my password",
"ResetMyPassword": "Hi {0}, Click here to reset your password"
```` ````
You also need to declare the localization resource to be used with this template, inside your template definition provider class: You also need to declare the localization resource to be used with this template, inside your template definition provider class:
@ -234,6 +235,7 @@ var result = await _templateRenderer.RenderAsync(
"PasswordReset", //the template name "PasswordReset", //the template name
new PasswordResetModel new PasswordResetModel
{ {
Name = "john",
Link = "https://abp.io/example-link?userId=123&token=ABC" Link = "https://abp.io/example-link?userId=123&token=ABC"
} }
); );
@ -242,7 +244,7 @@ var result = await _templateRenderer.RenderAsync(
You will see the localized result: You will see the localized result:
````csharp ````csharp
<a href="https://abp.io/example-link?userId=123&token=ABC">Click here to reset your password</a> <a title="Reset my password" href="https://abp.io/example-link?userId=123&token=ABC">Hi john, Click here to reset your password</a>
```` ````
> If you define the [default localization resource](Localization.md) for your application, then no need to declare the resource type for the template definition. > If you define the [default localization resource](Localization.md) for your application, then no need to declare the resource type for the template definition.

50
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<object> InvokeAsync(TemplateContext context, ScriptNode callerContext, ScriptArray arguments,
ScriptBlockStatement blockStatement)
{
return new ValueTask<object>(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()];
}
}
}

9
framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateRenderer.cs

@ -140,12 +140,7 @@ namespace Volo.Abp.TextTemplating
var localizer = GetLocalizerOrNull(templateDefinition); var localizer = GetLocalizerOrNull(templateDefinition);
if (localizer != null) if (localizer != null)
{ {
scriptObject.Import( scriptObject.SetValue("L", new TemplateLocalizer(localizer), true);
"L",
new Func<string, string>(
name => localizer[name]
)
);
} }
context.PushGlobal(scriptObject); context.PushGlobal(scriptObject);
@ -163,4 +158,4 @@ namespace Volo.Abp.TextTemplating
return _stringLocalizerFactory.CreateDefaultOrNull(); return _stringLocalizerFactory.CreateDefaultOrNull();
} }
} }
} }

7
framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/Localization/en.json

@ -1,6 +1,7 @@
{ {
"culture": "en", "culture": "en",
"texts": { "texts": {
"HelloText": "Hello" "HelloText": "Hello {0}",
} "HowAreYou": "how are you?"
} }
}

7
framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/Localization/tr.json

@ -1,6 +1,7 @@
{ {
"culture": "tr", "culture": "tr",
"texts": { "texts": {
"HelloText": "Merhaba" "HelloText": "Merhaba {0}",
} "HowAreYou": "nasılsın?"
} }
}

2
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! {{L "HelloText" model.name}}, {{L "HowAreYou" }}. Please click to the following link to get an email to reset your password!

21
framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/TemplateRenderer_Tests.cs

@ -81,13 +81,15 @@ namespace Volo.Abp.TextTemplating
{ {
(await _templateRenderer.RenderAsync( (await _templateRenderer.RenderAsync(
TestTemplates.ForgotPasswordEmail, TestTemplates.ForgotPasswordEmail,
new ForgotPasswordEmailModel("John"),
cultureName: "en" 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( (await _templateRenderer.RenderAsync(
TestTemplates.ForgotPasswordEmail, TestTemplates.ForgotPasswordEmail,
model: new Dictionary<string, object>() { { "name", "John" } },
cultureName: "tr" 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 private class WelcomeEmailModel
@ -104,5 +106,20 @@ namespace Volo.Abp.TextTemplating
Name = name; Name = name;
} }
} }
private class ForgotPasswordEmailModel
{
public string Name { get; set; }
public ForgotPasswordEmailModel()
{
}
public ForgotPasswordEmailModel(string name)
{
Name = name;
}
}
} }
} }

Loading…
Cancel
Save