Implemented template renderer.

pull/3792/head
Halil İbrahim Kalkan 5 years ago
parent 24365e4979
commit 61d2512311

@ -29,5 +29,12 @@ namespace Volo.Abp.Localization
CultureInfo.CurrentUICulture = currentUiCulture;
});
}
public static string GetBaseCultureName(string cultureName)
{
return cultureName.Contains("-")
? cultureName.Left(cultureName.IndexOf("-", StringComparison.Ordinal))
: cultureName;
}
}
}

@ -104,7 +104,7 @@ namespace Volo.Abp.Localization
//Try to get from same language dictionary (without country code)
if (cultureName.Contains("-")) //Example: "tr-TR" (length=5)
{
var strLang = Resource.Contributors.GetOrNull(GetBaseCultureName(cultureName), name);
var strLang = Resource.Contributors.GetOrNull(CultureHelper.GetBaseCultureName(cultureName), name);
if (strLang != null)
{
return strLang;
@ -168,7 +168,7 @@ namespace Volo.Abp.Localization
//Overwrite all strings from the language based on country culture
if (cultureName.Contains("-"))
{
Resource.Contributors.Fill(GetBaseCultureName(cultureName), allStrings);
Resource.Contributors.Fill(CultureHelper.GetBaseCultureName(cultureName), allStrings);
}
}
@ -178,12 +178,7 @@ namespace Volo.Abp.Localization
return allStrings.Values.ToImmutableList();
}
protected virtual string GetBaseCultureName(string cultureName)
{
return cultureName.Contains("-")
? cultureName.Left(cultureName.IndexOf("-", StringComparison.Ordinal))
: cultureName;
}
public class CultureWrapperStringLocalizer : IStringLocalizer, IStringLocalizerSupportsInheritance
{

@ -1,9 +1,13 @@
using System.Threading.Tasks;
using JetBrains.Annotations;
namespace Volo.Abp.TextTemplating
{
public interface ITemplateContentProvider
{
Task<string> GetContentOrNullAsync(string templateName, string cultureName);
Task<string> GetContentOrNullAsync(
[NotNull] string templateName,
[CanBeNull] string cultureName = null
);
}
}

@ -1,4 +1,5 @@
using System.Threading.Tasks;
using JetBrains.Annotations;
using Volo.Abp.DependencyInjection;
namespace Volo.Abp.TextTemplating
@ -14,7 +15,9 @@ namespace Volo.Abp.TextTemplating
_templateDefinitionManager = templateDefinitionManager;
}
public async Task<string> GetContentOrNullAsync(string templateName, string cultureName)
public async Task<string> GetContentOrNullAsync(
[NotNull] string templateName,
[CanBeNull] string cultureName = null)
{
var template = _templateDefinitionManager.Get(templateName);

@ -1,14 +1,18 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using JetBrains.Annotations;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.FileProviders;
using Volo.Abp.Localization;
using Volo.Abp.VirtualFileSystem;
namespace Volo.Abp.TextTemplating.VirtualFiles
{
public class VirtualFileTemplateContributor : ITemplateContributor
{
public TemplateDefinition TemplateDefinition { get; private set; }
private readonly string _virtualPath;
private IVirtualFileProvider _virtualFileProvider;
private volatile Dictionary<string, string> _templateDictionary;
@ -23,21 +27,46 @@ namespace Volo.Abp.TextTemplating.VirtualFiles
public void Initialize(TemplateContributorInitializationContext context)
{
_virtualFileProvider = context.ServiceProvider.GetRequiredService<IVirtualFileProvider>();
TemplateDefinition = context.TemplateDefinition;
}
public string GetOrNull([CanBeNull] string cultureName = null)
{
var dictionary = GetTemplateDictionary();
//TODO: Refactor: Split implementation based on single file or dictionary of culture-specific contents
if (cultureName == null)
{
return dictionary.GetOrDefault("__default");
cultureName = CultureInfo.CurrentUICulture.Name;
}
var dictionary = GetTemplateDictionary();
var content = dictionary.GetOrDefault(cultureName);
if (content != null)
{
return content;
}
if (cultureName.Contains("-"))
{
var baseCultureName = CultureHelper.GetBaseCultureName(cultureName);
content = dictionary.GetOrDefault(baseCultureName);
if (content != null)
{
return content;
}
}
else
if (TemplateDefinition.DefaultCultureName != null)
{
return dictionary.GetOrDefault(cultureName) ??
dictionary.GetOrDefault("__default");
content = dictionary.GetOrDefault(TemplateDefinition.DefaultCultureName);
if (content != null)
{
return content;
}
}
return dictionary.GetOrDefault("__default");
}
private Dictionary<string, string> GetTemplateDictionary()

@ -1 +1 @@
abp.io'ya hoşgeldiniz!
Merhaba {{name}}, abp.io'ya hoşgeldiniz!

@ -1,4 +1,5 @@
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Threading.Tasks;
using Shouldly;
using Xunit;
@ -19,7 +20,85 @@ namespace Volo.Abp.TextTemplating
var content = await _templateRenderer.RenderAsync(
TestTemplates.ForgotPasswordEmail
);
content.ShouldBe("Please click to the following link to get an email to reset your password!");
}
[Fact]
public async Task Should_Get_Rendered_Localized_Template_Content_With_Different_Cultures()
{
(await _templateRenderer.RenderAsync(
TestTemplates.WelcomeEmail,
model: new
{
name = "John"
},
cultureName: "en"
)).ShouldBe("Welcome John to the abp.io!");
(await _templateRenderer.RenderAsync(
TestTemplates.WelcomeEmail,
model: new
{
name = "John"
},
cultureName: "tr"
)).ShouldBe("Merhaba John, abp.io'ya hoşgeldiniz!");
//"en-US" fallbacks to "en" since "en-US" doesn't exists and "en" is the fallback culture
(await _templateRenderer.RenderAsync(
TestTemplates.WelcomeEmail,
model: new
{
name = "John"
},
cultureName: "en-US"
)).ShouldBe("Welcome John to the abp.io!");
//"fr" fallbacks to "en" since "fr" doesn't exists and "en" is the default culture
(await _templateRenderer.RenderAsync(
TestTemplates.WelcomeEmail,
model: new
{
Name = "John" //Intentionally written as PascalCase since Scriban supports it
},
cultureName: "fr"
)).ShouldBe("Welcome John to the abp.io!");
}
[Fact]
public async Task Should_Get_Rendered_Localized_Template_Content_With_Stronly_Typed_Model()
{
(await _templateRenderer.RenderAsync(
TestTemplates.WelcomeEmail,
model: new WelcomeEmailModel("John"),
cultureName: "en"
)).ShouldBe("Welcome John to the abp.io!");
}
[Fact]
public async Task Should_Get_Rendered_Localized_Template_Content_With_Dictionary_Model()
{
(await _templateRenderer.RenderAsync(
TestTemplates.WelcomeEmail,
model: new Dictionary<string, object>() { { "name", "John" } },
cultureName: "en"
)).ShouldBe("Welcome John to the abp.io!");
}
private class WelcomeEmailModel
{
public string Name { get; set; }
public WelcomeEmailModel()
{
}
public WelcomeEmailModel(string name)
{
Name = name;
}
}
}
}

@ -6,7 +6,8 @@
{
context.Add(
new TemplateDefinition(
TestTemplates.WelcomeEmail
TestTemplates.WelcomeEmail,
defaultCultureName: "en"
).AddVirtualFiles("/SampleTemplates/WelcomeEmail")
);

@ -21,11 +21,11 @@ namespace Volo.Abp.TextTemplating.VirtualFiles
contributor
.GetOrNull("en")
.ShouldBe("Welcome to the abp.io!");
.ShouldBe("Welcome {{name}} to the abp.io!");
contributor
.GetOrNull("tr")
.ShouldBe("abp.io'ya hoşgeldiniz!");
.ShouldBe("Merhaba {{name}}, abp.io'ya hoşgeldiniz!");
}
[Fact]

Loading…
Cancel
Save