diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/AbpTextTemplatingModule.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/AbpTextTemplatingModule.cs index 3ef30f5fc2..e49f271c1c 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/AbpTextTemplatingModule.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/AbpTextTemplatingModule.cs @@ -33,5 +33,28 @@ namespace Volo.Abp.TextTemplating options.DefinitionProviders.AddIfNotContains(definitionProviders); }); } + + public override void OnApplicationInitialization(ApplicationInitializationContext context) + { + //TODO: Consider to move to the TemplateContentProvider and invoke lazy (with making it singleton) + using (var scope = context.ServiceProvider.CreateScope()) + { + var templateDefinitionManager = scope.ServiceProvider + .GetRequiredService(); + + foreach (var templateDefinition in templateDefinitionManager.GetAll()) + { + var contributorInitializationContext = new TemplateContributorInitializationContext( + templateDefinition, + scope.ServiceProvider + ); + + foreach (var contributor in templateDefinition.Contributors) + { + contributor.Initialize(contributorInitializationContext); + } + } + } + } } } diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateContentProvider.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateContentProvider.cs new file mode 100644 index 0000000000..d4dc5615fb --- /dev/null +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateContentProvider.cs @@ -0,0 +1,9 @@ +using System.Threading.Tasks; + +namespace Volo.Abp.TextTemplating +{ + public interface ITemplateContentProvider + { + Task GetContentOrNullAsync(string templateName, string cultureName); + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateContributor.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateContributor.cs index c1a7eb95cd..e8e1f97769 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateContributor.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateContributor.cs @@ -1,9 +1,11 @@ -namespace Volo.Abp.TextTemplating +using JetBrains.Annotations; + +namespace Volo.Abp.TextTemplating { public interface ITemplateContributor { void Initialize(TemplateContributorInitializationContext context); - string GetOrNull(string cultureName); + string GetOrNull([CanBeNull] string cultureName); } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateRenderer.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateRenderer.cs new file mode 100644 index 0000000000..d65f77653a --- /dev/null +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateRenderer.cs @@ -0,0 +1,14 @@ +using System.Linq; +using System.Threading.Tasks; +using JetBrains.Annotations; + +namespace Volo.Abp.TextTemplating +{ + public interface ITemplateRenderer + { + Task RenderAsync( + [NotNull] string templateName, + [CanBeNull] string cultureName = null + ); + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentProvider.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentProvider.cs new file mode 100644 index 0000000000..ab81d8b9f7 --- /dev/null +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentProvider.cs @@ -0,0 +1,35 @@ +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.TextTemplating +{ + public class TemplateContentProvider : ITemplateContentProvider, ITransientDependency + { + private readonly ITemplateDefinitionManager _templateDefinitionManager; + + public TemplateContentProvider( + ITemplateDefinitionManager templateDefinitionManager + ) + { + _templateDefinitionManager = templateDefinitionManager; + } + + public async Task GetContentOrNullAsync(string templateName, string cultureName) + { + var template = _templateDefinitionManager.Get(templateName); + + foreach (var contributor in template.Contributors) + { + var templateString = contributor.GetOrNull(cultureName); + if (templateString != null) + { + return templateString; + } + } + + throw new AbpException( + $"None of the template contributors could get the content for the template '{templateName}'" + ); + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContributorList.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContributorList.cs index 50fdb684df..e737897dae 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContributorList.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContributorList.cs @@ -1,22 +1,9 @@ using System.Collections.Generic; -using System.Linq; namespace Volo.Abp.TextTemplating { public class TemplateContributorList : List { - public string GetOrNull(string cultureName) - { - foreach (var contributor in this.AsQueryable().Reverse()) - { - var templateString = contributor.GetOrNull(cultureName); - if (templateString != null) - { - return templateString; - } - } - - return null; - } + } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateRenderer.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateRenderer.cs new file mode 100644 index 0000000000..dcc36081fd --- /dev/null +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateRenderer.cs @@ -0,0 +1,30 @@ +using System.Threading.Tasks; +using JetBrains.Annotations; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.TextTemplating +{ + public class TemplateRenderer : ITemplateRenderer, ITransientDependency + { + private readonly ITemplateContentProvider _templateContentProvider; + + public TemplateRenderer( + ITemplateContentProvider templateContentProvider + ) + { + _templateContentProvider = templateContentProvider; + } + + public virtual async Task RenderAsync( + [NotNull] string templateName, + [CanBeNull] string cultureName = null) + { + Check.NotNullOrWhiteSpace(templateName, nameof(templateName)); + + return await _templateContentProvider.GetContentOrNullAsync( + templateName, + cultureName + ); + } + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/TemplateDefinitionTests.cs b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/TemplateDefinitionTests.cs index bc0e8b94c4..b711860089 100644 --- a/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/TemplateDefinitionTests.cs +++ b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/TemplateDefinitionTests.cs @@ -15,8 +15,8 @@ namespace Volo.Abp.TextTemplating [Fact] public void Should_Retrieve_Template_Definition_By_Name() { - var definition = _templateDefinitionManager.Get(TestTemplates.TestTemplate1); - definition.Name.ShouldBe(TestTemplates.TestTemplate1); + var definition = _templateDefinitionManager.Get(TestTemplates.WelcomeEmail); + definition.Name.ShouldBe(TestTemplates.WelcomeEmail); } [Fact] 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 new file mode 100644 index 0000000000..e4c5481413 --- /dev/null +++ b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/TemplateRenderer_Tests.cs @@ -0,0 +1,23 @@ +using System.Threading.Tasks; +using Shouldly; +using Xunit; + +namespace Volo.Abp.TextTemplating +{ + public class TemplateRenderer_Tests : AbpTextTemplatingTestBase + { + private readonly ITemplateRenderer _templateRenderer; + + public TemplateRenderer_Tests() + { + _templateRenderer = GetRequiredService(); + } + + [Fact] + public async Task Should_Get_Rendered_Non_Localized_Template_Content() + { + var content = await _templateRenderer.RenderAsync(TestTemplates.ForgotPasswordEmail); + content.ShouldBe("Please click to the following link to get an email to reset your password!"); + } + } +} diff --git a/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/TestTemplateDefinitionProvider.cs b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/TestTemplateDefinitionProvider.cs index f47d31ac4e..d400964684 100644 --- a/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/TestTemplateDefinitionProvider.cs +++ b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/TestTemplateDefinitionProvider.cs @@ -6,10 +6,16 @@ { context.Add( new TemplateDefinition( - TestTemplates.TestTemplate1 + TestTemplates.WelcomeEmail ).AddVirtualFiles("/SampleTemplates/WelcomeEmail") ); + context.Add( + new TemplateDefinition( + TestTemplates.ForgotPasswordEmail + ).AddVirtualFiles("/SampleTemplates/ForgotPasswordEmail.tpl") + ); + context.Add(new TemplateDefinition( TestTemplates.TestTemplateLayout1 )); diff --git a/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/TestTemplates.cs b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/TestTemplates.cs index e5b7bcc9ae..a2b605c213 100644 --- a/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/TestTemplates.cs +++ b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/TestTemplates.cs @@ -2,7 +2,8 @@ { public static class TestTemplates { - public const string TestTemplate1 = "TestTemplate1"; + public const string WelcomeEmail = "WelcomeEmail"; + public const string ForgotPasswordEmail = "ForgotPasswordEmail"; public const string TestTemplateLayout1 = "TestTemplateLayout1"; } } \ No newline at end of file