From ca7a084c512b06ca19269ba7b1c26670851eaac1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Wed, 22 Apr 2020 18:36:57 +0300 Subject: [PATCH 01/35] Created Volo.Abp.TextTemplating package and copied initial files. --- framework/Volo.Abp.sln | 9 ++++- .../Volo.Abp.TextTemplating/FodyWeavers.xml | 3 ++ .../Volo.Abp.TextTemplating/FodyWeavers.xsd | 30 ++++++++++++++++ .../Volo.Abp.TextTemplating.csproj | 21 +++++++++++ .../TextTemplating/AbpTextTemplatingModule.cs | 9 +++++ .../EmailTemplateContributorList.cs | 22 ++++++++++++ .../TextTemplating/EmailTemplateDefinition.cs | 36 +++++++++++++++++++ .../EmailTemplateInitializationContext.cs | 18 ++++++++++ .../IEmailTemplateContributor.cs | 9 +++++ nupkg/common.ps1 | 1 + 10 files changed, 157 insertions(+), 1 deletion(-) create mode 100644 framework/src/Volo.Abp.TextTemplating/FodyWeavers.xml create mode 100644 framework/src/Volo.Abp.TextTemplating/FodyWeavers.xsd create mode 100644 framework/src/Volo.Abp.TextTemplating/Volo.Abp.TextTemplating.csproj create mode 100644 framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/AbpTextTemplatingModule.cs create mode 100644 framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/EmailTemplateContributorList.cs create mode 100644 framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/EmailTemplateDefinition.cs create mode 100644 framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/EmailTemplateInitializationContext.cs create mode 100644 framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/IEmailTemplateContributor.cs diff --git a/framework/Volo.Abp.sln b/framework/Volo.Abp.sln index 3db0998855..97a831752c 100644 --- a/framework/Volo.Abp.sln +++ b/framework/Volo.Abp.sln @@ -277,7 +277,9 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.Http.Client.Identi EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.ObjectExtending", "src\Volo.Abp.ObjectExtending\Volo.Abp.ObjectExtending.csproj", "{D1815C77-16D6-4F99-8814-69065CD89FB3}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.ObjectExtending.Tests", "test\Volo.Abp.ObjectExtending.Tests\Volo.Abp.ObjectExtending.Tests.csproj", "{17F8CA89-D9A2-4863-A5BD-B8E4D2901FD5}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.ObjectExtending.Tests", "test\Volo.Abp.ObjectExtending.Tests\Volo.Abp.ObjectExtending.Tests.csproj", "{17F8CA89-D9A2-4863-A5BD-B8E4D2901FD5}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.TextTemplating", "src\Volo.Abp.TextTemplating\Volo.Abp.TextTemplating.csproj", "{9E53F91F-EACD-4191-A487-E727741F1311}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -829,6 +831,10 @@ Global {17F8CA89-D9A2-4863-A5BD-B8E4D2901FD5}.Debug|Any CPU.Build.0 = Debug|Any CPU {17F8CA89-D9A2-4863-A5BD-B8E4D2901FD5}.Release|Any CPU.ActiveCfg = Release|Any CPU {17F8CA89-D9A2-4863-A5BD-B8E4D2901FD5}.Release|Any CPU.Build.0 = Release|Any CPU + {9E53F91F-EACD-4191-A487-E727741F1311}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {9E53F91F-EACD-4191-A487-E727741F1311}.Debug|Any CPU.Build.0 = Debug|Any CPU + {9E53F91F-EACD-4191-A487-E727741F1311}.Release|Any CPU.ActiveCfg = Release|Any CPU + {9E53F91F-EACD-4191-A487-E727741F1311}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -970,6 +976,7 @@ Global {E1963439-2BE5-4DB5-8438-2A9A792A1ADA} = {447C8A77-E5F0-4538-8687-7383196D04EA} {D1815C77-16D6-4F99-8814-69065CD89FB3} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} {17F8CA89-D9A2-4863-A5BD-B8E4D2901FD5} = {447C8A77-E5F0-4538-8687-7383196D04EA} + {9E53F91F-EACD-4191-A487-E727741F1311} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {BB97ECF4-9A84-433F-A80B-2A3285BDD1D5} diff --git a/framework/src/Volo.Abp.TextTemplating/FodyWeavers.xml b/framework/src/Volo.Abp.TextTemplating/FodyWeavers.xml new file mode 100644 index 0000000000..be0de3a908 --- /dev/null +++ b/framework/src/Volo.Abp.TextTemplating/FodyWeavers.xml @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/framework/src/Volo.Abp.TextTemplating/FodyWeavers.xsd b/framework/src/Volo.Abp.TextTemplating/FodyWeavers.xsd new file mode 100644 index 0000000000..3f3946e282 --- /dev/null +++ b/framework/src/Volo.Abp.TextTemplating/FodyWeavers.xsd @@ -0,0 +1,30 @@ + + + + + + + + + + + + + + + 'true' to run assembly verification (PEVerify) on the target assembly after all weavers have been executed. + + + + + A comma-separated list of error codes that can be safely ignored in assembly verification. + + + + + 'false' to turn off automatic generation of the XML Schema file. + + + + + \ No newline at end of file diff --git a/framework/src/Volo.Abp.TextTemplating/Volo.Abp.TextTemplating.csproj b/framework/src/Volo.Abp.TextTemplating/Volo.Abp.TextTemplating.csproj new file mode 100644 index 0000000000..cbc6ba05ec --- /dev/null +++ b/framework/src/Volo.Abp.TextTemplating/Volo.Abp.TextTemplating.csproj @@ -0,0 +1,21 @@ + + + + + + + netstandard2.0 + Volo.Abp.TextTemplating + Volo.Abp.TextTemplating + $(AssetTargetFallback);portable-net45+win8+wp8+wpa81; + false + false + false + + + + + + + + diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/AbpTextTemplatingModule.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/AbpTextTemplatingModule.cs new file mode 100644 index 0000000000..6b0ad6fb11 --- /dev/null +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/AbpTextTemplatingModule.cs @@ -0,0 +1,9 @@ +using Volo.Abp.Modularity; + +namespace Volo.Abp.TextTemplating +{ + public class AbpTextTemplatingModule : AbpModule + { + + } +} diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/EmailTemplateContributorList.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/EmailTemplateContributorList.cs new file mode 100644 index 0000000000..44a91212ea --- /dev/null +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/EmailTemplateContributorList.cs @@ -0,0 +1,22 @@ +using System.Collections.Generic; +using System.Linq; + +namespace Volo.Abp.Emailing.Templates +{ + public class EmailTemplateContributorList : 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/EmailTemplateDefinition.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/EmailTemplateDefinition.cs new file mode 100644 index 0000000000..19f0eb2fa7 --- /dev/null +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/EmailTemplateDefinition.cs @@ -0,0 +1,36 @@ +using System; +using JetBrains.Annotations; + +namespace Volo.Abp.Emailing.Templates +{ + public class EmailTemplateDefinition + { + public const string DefaultLayoutPlaceHolder = "_"; + + public string Name { get; } + + public bool IsLayout { get; } + + public string Layout { get; set; } + + public Type LocalizationResource { get; set; } + + public EmailTemplateContributorList Contributors { get; } + + public string DefaultCultureName { get; } + + public bool SingleTemplateFile { get; } + + public EmailTemplateDefinition([NotNull] string name, Type localizationResource = null, bool isLayout = false, + string layout = DefaultLayoutPlaceHolder, string defaultCultureName = null, bool singleTemplateFile = false) + { + Name = Check.NotNullOrWhiteSpace(name, nameof(name)); + LocalizationResource = localizationResource; + Contributors = new EmailTemplateContributorList(); + IsLayout = isLayout; + Layout = layout; + DefaultCultureName = defaultCultureName; + SingleTemplateFile = singleTemplateFile; + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/EmailTemplateInitializationContext.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/EmailTemplateInitializationContext.cs new file mode 100644 index 0000000000..8cd4b95bbd --- /dev/null +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/EmailTemplateInitializationContext.cs @@ -0,0 +1,18 @@ +using System; + +namespace Volo.Abp.Emailing.Templates +{ + public class EmailTemplateInitializationContext + { + public EmailTemplateDefinition EmailTemplateDefinition { get; } + + public IServiceProvider ServiceProvider { get; } + + public EmailTemplateInitializationContext(EmailTemplateDefinition emailTemplateDefinition, + IServiceProvider serviceProvider) + { + EmailTemplateDefinition = emailTemplateDefinition; + ServiceProvider = serviceProvider; + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/IEmailTemplateContributor.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/IEmailTemplateContributor.cs new file mode 100644 index 0000000000..d2c2775845 --- /dev/null +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/IEmailTemplateContributor.cs @@ -0,0 +1,9 @@ +namespace Volo.Abp.Emailing.Templates +{ + public interface IEmailTemplateContributor + { + void Initialize(EmailTemplateInitializationContext context); + + string GetOrNull(string cultureName); + } +} \ No newline at end of file diff --git a/nupkg/common.ps1 b/nupkg/common.ps1 index f9e1263908..9c77b05eef 100644 --- a/nupkg/common.ps1 +++ b/nupkg/common.ps1 @@ -101,6 +101,7 @@ $projects = ( "framework/src/Volo.Abp.Sms", "framework/src/Volo.Abp.Specifications", "framework/src/Volo.Abp.TestBase", + "framework/src/Volo.Abp.TextTemplating", "framework/src/Volo.Abp.Threading", "framework/src/Volo.Abp.Timing", "framework/src/Volo.Abp.UI", From af77ec2aee9f5a53d7f52ed11471bcc8693e48d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Wed, 22 Apr 2020 18:53:20 +0300 Subject: [PATCH 02/35] Refactored and added test project --- framework/Volo.Abp.sln | 7 +++ ...pleVirtualFilesEmailTemplateContributor.cs | 2 +- .../TextTemplating/EmailTemplateDefinition.cs | 36 --------------- .../EmailTemplateInitializationContext.cs | 18 -------- .../IEmailTemplateContributor.cs | 9 ---- .../TextTemplating/ITemplateContributor.cs | 9 ++++ ...emplateContributorInitializationContext.cs | 22 ++++++++++ ...utorList.cs => TemplateContributorList.cs} | 4 +- .../Abp/TextTemplating/TemplateDefinition.cs | 44 +++++++++++++++++++ .../Volo.Abp.TextTemplating.Tests.csproj | 16 +++++++ .../AbpTextTemplatingTestModule.cs | 9 ++++ 11 files changed, 110 insertions(+), 66 deletions(-) delete mode 100644 framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/EmailTemplateDefinition.cs delete mode 100644 framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/EmailTemplateInitializationContext.cs delete mode 100644 framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/IEmailTemplateContributor.cs create mode 100644 framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateContributor.cs create mode 100644 framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContributorInitializationContext.cs rename framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/{EmailTemplateContributorList.cs => TemplateContributorList.cs} (79%) create mode 100644 framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinition.cs create mode 100644 framework/test/Volo.Abp.TextTemplating.Tests/Volo.Abp.TextTemplating.Tests.csproj create mode 100644 framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/AbpTextTemplatingTestModule.cs diff --git a/framework/Volo.Abp.sln b/framework/Volo.Abp.sln index 97a831752c..5159f0a86e 100644 --- a/framework/Volo.Abp.sln +++ b/framework/Volo.Abp.sln @@ -281,6 +281,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Volo.Abp.ObjectExtending.Te EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.TextTemplating", "src\Volo.Abp.TextTemplating\Volo.Abp.TextTemplating.csproj", "{9E53F91F-EACD-4191-A487-E727741F1311}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Volo.Abp.TextTemplating.Tests", "test\Volo.Abp.TextTemplating.Tests\Volo.Abp.TextTemplating.Tests.csproj", "{251C7FD3-D313-4BCE-8068-352EC7EEA275}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -835,6 +837,10 @@ Global {9E53F91F-EACD-4191-A487-E727741F1311}.Debug|Any CPU.Build.0 = Debug|Any CPU {9E53F91F-EACD-4191-A487-E727741F1311}.Release|Any CPU.ActiveCfg = Release|Any CPU {9E53F91F-EACD-4191-A487-E727741F1311}.Release|Any CPU.Build.0 = Release|Any CPU + {251C7FD3-D313-4BCE-8068-352EC7EEA275}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {251C7FD3-D313-4BCE-8068-352EC7EEA275}.Debug|Any CPU.Build.0 = Debug|Any CPU + {251C7FD3-D313-4BCE-8068-352EC7EEA275}.Release|Any CPU.ActiveCfg = Release|Any CPU + {251C7FD3-D313-4BCE-8068-352EC7EEA275}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -977,6 +983,7 @@ Global {D1815C77-16D6-4F99-8814-69065CD89FB3} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} {17F8CA89-D9A2-4863-A5BD-B8E4D2901FD5} = {447C8A77-E5F0-4538-8687-7383196D04EA} {9E53F91F-EACD-4191-A487-E727741F1311} = {5DF0E140-0513-4D0D-BE2E-3D4D85CD70E6} + {251C7FD3-D313-4BCE-8068-352EC7EEA275} = {447C8A77-E5F0-4538-8687-7383196D04EA} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {BB97ECF4-9A84-433F-A80B-2A3285BDD1D5} diff --git a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/VirtualFiles/MultipleVirtualFilesEmailTemplateContributor.cs b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/VirtualFiles/MultipleVirtualFilesEmailTemplateContributor.cs index 2ae5f88cc5..39af512350 100644 --- a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/VirtualFiles/MultipleVirtualFilesEmailTemplateContributor.cs +++ b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/VirtualFiles/MultipleVirtualFilesEmailTemplateContributor.cs @@ -46,7 +46,7 @@ namespace Volo.Abp.Emailing.Templates.VirtualFiles { return dictionaries; } - + _templateDictionary = new Dictionary(); foreach (var file in _virtualFileProvider.GetDirectoryContents(_virtualPath)) { diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/EmailTemplateDefinition.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/EmailTemplateDefinition.cs deleted file mode 100644 index 19f0eb2fa7..0000000000 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/EmailTemplateDefinition.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System; -using JetBrains.Annotations; - -namespace Volo.Abp.Emailing.Templates -{ - public class EmailTemplateDefinition - { - public const string DefaultLayoutPlaceHolder = "_"; - - public string Name { get; } - - public bool IsLayout { get; } - - public string Layout { get; set; } - - public Type LocalizationResource { get; set; } - - public EmailTemplateContributorList Contributors { get; } - - public string DefaultCultureName { get; } - - public bool SingleTemplateFile { get; } - - public EmailTemplateDefinition([NotNull] string name, Type localizationResource = null, bool isLayout = false, - string layout = DefaultLayoutPlaceHolder, string defaultCultureName = null, bool singleTemplateFile = false) - { - Name = Check.NotNullOrWhiteSpace(name, nameof(name)); - LocalizationResource = localizationResource; - Contributors = new EmailTemplateContributorList(); - IsLayout = isLayout; - Layout = layout; - DefaultCultureName = defaultCultureName; - SingleTemplateFile = singleTemplateFile; - } - } -} \ No newline at end of file diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/EmailTemplateInitializationContext.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/EmailTemplateInitializationContext.cs deleted file mode 100644 index 8cd4b95bbd..0000000000 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/EmailTemplateInitializationContext.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System; - -namespace Volo.Abp.Emailing.Templates -{ - public class EmailTemplateInitializationContext - { - public EmailTemplateDefinition EmailTemplateDefinition { get; } - - public IServiceProvider ServiceProvider { get; } - - public EmailTemplateInitializationContext(EmailTemplateDefinition emailTemplateDefinition, - IServiceProvider serviceProvider) - { - EmailTemplateDefinition = emailTemplateDefinition; - ServiceProvider = serviceProvider; - } - } -} \ No newline at end of file diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/IEmailTemplateContributor.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/IEmailTemplateContributor.cs deleted file mode 100644 index d2c2775845..0000000000 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/IEmailTemplateContributor.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Volo.Abp.Emailing.Templates -{ - public interface IEmailTemplateContributor - { - void Initialize(EmailTemplateInitializationContext context); - - string GetOrNull(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 new file mode 100644 index 0000000000..c1a7eb95cd --- /dev/null +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateContributor.cs @@ -0,0 +1,9 @@ +namespace Volo.Abp.TextTemplating +{ + public interface ITemplateContributor + { + void Initialize(TemplateContributorInitializationContext context); + + string GetOrNull(string cultureName); + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContributorInitializationContext.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContributorInitializationContext.cs new file mode 100644 index 0000000000..e8a7332e83 --- /dev/null +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContributorInitializationContext.cs @@ -0,0 +1,22 @@ +using System; +using JetBrains.Annotations; + +namespace Volo.Abp.TextTemplating +{ + public class TemplateContributorInitializationContext + { + [NotNull] + public TemplateDefinition TemplateDefinition { get; } + + [NotNull] + public IServiceProvider ServiceProvider { get; } + + public TemplateContributorInitializationContext( + TemplateDefinition templateDefinition, + IServiceProvider serviceProvider) + { + TemplateDefinition = Check.NotNull(templateDefinition, nameof(templateDefinition)); + ServiceProvider = Check.NotNull(serviceProvider, nameof(serviceProvider)); + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/EmailTemplateContributorList.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContributorList.cs similarity index 79% rename from framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/EmailTemplateContributorList.cs rename to framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContributorList.cs index 44a91212ea..50fdb684df 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/EmailTemplateContributorList.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContributorList.cs @@ -1,9 +1,9 @@ using System.Collections.Generic; using System.Linq; -namespace Volo.Abp.Emailing.Templates +namespace Volo.Abp.TextTemplating { - public class EmailTemplateContributorList : List + public class TemplateContributorList : List { public string GetOrNull(string cultureName) { diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinition.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinition.cs new file mode 100644 index 0000000000..b9b7762405 --- /dev/null +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinition.cs @@ -0,0 +1,44 @@ +using System; +using JetBrains.Annotations; + +namespace Volo.Abp.TextTemplating +{ + public class TemplateDefinition + { + public const string DefaultLayoutPlaceHolder = "_"; + + [NotNull] + public string Name { get; } + + public bool IsLayout { get; } + + [CanBeNull] + public string Layout { get; set; } + + public Type LocalizationResource { get; set; } //TODO: ??? + + public TemplateContributorList Contributors { get; } + + [CanBeNull] + public string DefaultCultureName { get; } + + public bool SingleTemplateFile { get; } //TODO: ??? + + public TemplateDefinition( + [NotNull] string name, + Type localizationResource = null, + bool isLayout = false, + string layout = DefaultLayoutPlaceHolder, + string defaultCultureName = null, + bool singleTemplateFile = false) + { + Name = Check.NotNullOrWhiteSpace(name, nameof(name)); + LocalizationResource = localizationResource; + Contributors = new TemplateContributorList(); + IsLayout = isLayout; + Layout = layout; + DefaultCultureName = defaultCultureName; + SingleTemplateFile = singleTemplateFile; + } + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.TextTemplating.Tests/Volo.Abp.TextTemplating.Tests.csproj b/framework/test/Volo.Abp.TextTemplating.Tests/Volo.Abp.TextTemplating.Tests.csproj new file mode 100644 index 0000000000..56e93ae650 --- /dev/null +++ b/framework/test/Volo.Abp.TextTemplating.Tests/Volo.Abp.TextTemplating.Tests.csproj @@ -0,0 +1,16 @@ + + + + + + netcoreapp3.1 + + + + + + + + + + diff --git a/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/AbpTextTemplatingTestModule.cs b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/AbpTextTemplatingTestModule.cs new file mode 100644 index 0000000000..280059a40e --- /dev/null +++ b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/AbpTextTemplatingTestModule.cs @@ -0,0 +1,9 @@ +using Volo.Abp.Modularity; + +namespace Volo.Abp.TextTemplating +{ + public class AbpTextTemplatingTestModule : AbpModule + { + + } +} From 095bb128a0502e35a69ba9aa8750565fb0ea305b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Wed, 22 Apr 2020 19:30:27 +0300 Subject: [PATCH 03/35] Added template definition system and tests. --- .../Volo/Abp/Emailing/AbpEmailingModule.cs | 1 - .../TextTemplating/AbpTextTemplatingModule.cs | 26 ++++++- .../AbpTextTemplatingOptions.cs | 14 ++++ .../ITemplateDefinitionContext.cs | 9 +++ .../ITemplateDefinitionManager.cs | 15 ++++ .../ITemplateDefinitionProvider.cs | 7 ++ .../TemplateDefinitionContext.cs | 38 ++++++++++ .../TemplateDefinitionManager.cs | 74 +++++++++++++++++++ .../TemplateDefinitionProvider.cs | 9 +++ .../Volo.Abp.TextTemplating.Tests.csproj | 3 +- .../AbpTextTemplatingOptions_Tests.cs | 24 ++++++ .../AbpTextTemplatingTestBase.cs | 12 +++ .../AbpTextTemplatingTestModule.cs | 8 +- .../TextTemplating/TemplateDefinitionTests.cs | 22 ++++++ .../TestTemplateDefinitionProvider.cs | 14 ++++ .../Volo/Abp/TextTemplating/TestTemplates.cs | 7 ++ 16 files changed, 279 insertions(+), 4 deletions(-) create mode 100644 framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/AbpTextTemplatingOptions.cs create mode 100644 framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateDefinitionContext.cs create mode 100644 framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateDefinitionManager.cs create mode 100644 framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateDefinitionProvider.cs create mode 100644 framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionContext.cs create mode 100644 framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionManager.cs create mode 100644 framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionProvider.cs create mode 100644 framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/AbpTextTemplatingOptions_Tests.cs create mode 100644 framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/AbpTextTemplatingTestBase.cs create mode 100644 framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/TemplateDefinitionTests.cs create mode 100644 framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/TestTemplateDefinitionProvider.cs create mode 100644 framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/TestTemplates.cs diff --git a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/AbpEmailingModule.cs b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/AbpEmailingModule.cs index c2e29a7ff7..9641f7c14c 100644 --- a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/AbpEmailingModule.cs +++ b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/AbpEmailingModule.cs @@ -50,7 +50,6 @@ namespace Volo.Abp.Emailing services.OnRegistred(context => { - if (typeof(IEmailTemplateDefinitionProvider).IsAssignableFrom(context.ImplementationType)) { definitionProviders.Add(context.ImplementationType); 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 6b0ad6fb11..28b71da4aa 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/AbpTextTemplatingModule.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/AbpTextTemplatingModule.cs @@ -1,9 +1,33 @@ -using Volo.Abp.Modularity; +using System; +using System.Collections.Generic; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Modularity; namespace Volo.Abp.TextTemplating { public class AbpTextTemplatingModule : AbpModule { + public override void PreConfigureServices(ServiceConfigurationContext context) + { + AutoAddDefinitionProviders(context.Services); + } + private static void AutoAddDefinitionProviders(IServiceCollection services) + { + var definitionProviders = new List(); + + services.OnRegistred(context => + { + if (typeof(ITemplateDefinitionProvider).IsAssignableFrom(context.ImplementationType)) + { + definitionProviders.Add(context.ImplementationType); + } + }); + + services.Configure(options => + { + options.DefinitionProviders.AddIfNotContains(definitionProviders); + }); + } } } diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/AbpTextTemplatingOptions.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/AbpTextTemplatingOptions.cs new file mode 100644 index 0000000000..a79b66e255 --- /dev/null +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/AbpTextTemplatingOptions.cs @@ -0,0 +1,14 @@ +using Volo.Abp.Collections; + +namespace Volo.Abp.TextTemplating +{ + public class AbpTextTemplatingOptions + { + public ITypeList DefinitionProviders { get; } + + public AbpTextTemplatingOptions() + { + DefinitionProviders = new TypeList(); + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateDefinitionContext.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateDefinitionContext.cs new file mode 100644 index 0000000000..18402f8f9d --- /dev/null +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateDefinitionContext.cs @@ -0,0 +1,9 @@ +namespace Volo.Abp.TextTemplating +{ + public interface ITemplateDefinitionContext + { + TemplateDefinition GetOrNull(string name); + + void Add(params TemplateDefinition[] definitions); + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateDefinitionManager.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateDefinitionManager.cs new file mode 100644 index 0000000000..feadd3442f --- /dev/null +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateDefinitionManager.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; +using JetBrains.Annotations; + +namespace Volo.Abp.TextTemplating +{ + public interface ITemplateDefinitionManager + { + [NotNull] + TemplateDefinition Get([NotNull] string name); + + IReadOnlyList GetAll(); + + TemplateDefinition GetOrNull(string name); + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateDefinitionProvider.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateDefinitionProvider.cs new file mode 100644 index 0000000000..a9e5155d0c --- /dev/null +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateDefinitionProvider.cs @@ -0,0 +1,7 @@ +namespace Volo.Abp.TextTemplating +{ + public interface ITemplateDefinitionProvider + { + void Define(ITemplateDefinitionContext context); + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionContext.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionContext.cs new file mode 100644 index 0000000000..39da2f5e88 --- /dev/null +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionContext.cs @@ -0,0 +1,38 @@ +using System.Collections.Generic; +using System.Collections.Immutable; + +namespace Volo.Abp.TextTemplating +{ + public class TemplateDefinitionContext : ITemplateDefinitionContext + { + protected Dictionary EmailTemplates { get; } + + public TemplateDefinitionContext(Dictionary emailTemplates) + { + EmailTemplates = emailTemplates; + } + + public virtual TemplateDefinition GetOrNull(string name) + { + return EmailTemplates.GetOrDefault(name); + } + + public virtual IReadOnlyList GetAll() + { + return EmailTemplates.Values.ToImmutableList(); + } + + public virtual void Add(params TemplateDefinition[] definitions) + { + if (definitions.IsNullOrEmpty()) + { + return; + } + + foreach (var definition in definitions) + { + EmailTemplates[definition.Name] = definition; + } + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionManager.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionManager.cs new file mode 100644 index 0000000000..534010dbe2 --- /dev/null +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionManager.cs @@ -0,0 +1,74 @@ +using System; +using System.Collections.Generic; +using System.Collections.Immutable; +using System.Linq; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.TextTemplating +{ + public class TemplateDefinitionManager : ITemplateDefinitionManager, ISingletonDependency + { + protected Lazy> EmailTemplateDefinitions { get; } + + protected AbpTextTemplatingOptions Options { get; } + + protected IServiceProvider ServiceProvider { get; } + + public TemplateDefinitionManager( + IOptions options, + IServiceProvider serviceProvider) + { + ServiceProvider = serviceProvider; + Options = options.Value; + + EmailTemplateDefinitions = + new Lazy>(CreateEmailTemplateDefinitions, true); + } + + public virtual TemplateDefinition Get(string name) + { + Check.NotNull(name, nameof(name)); + + var template = GetOrNull(name); + + if (template == null) + { + throw new AbpException("Undefined template: " + name); + } + + return template; + } + + public virtual IReadOnlyList GetAll() + { + return EmailTemplateDefinitions.Value.Values.ToImmutableList(); + } + + public virtual TemplateDefinition GetOrNull(string name) + { + return EmailTemplateDefinitions.Value.GetOrDefault(name); + } + + protected virtual IDictionary CreateEmailTemplateDefinitions() + { + var templates = new Dictionary(); + + using (var scope = ServiceProvider.CreateScope()) + { + var providers = Options + .DefinitionProviders + .Select(p => scope.ServiceProvider.GetRequiredService(p) as ITemplateDefinitionProvider) + .ToList(); + + foreach (var provider in providers) + { + provider.Define(new TemplateDefinitionContext(templates)); + } + } + + return templates; + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionProvider.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionProvider.cs new file mode 100644 index 0000000000..9afc22a8b8 --- /dev/null +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionProvider.cs @@ -0,0 +1,9 @@ +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.TextTemplating +{ + public abstract class TemplateDefinitionProvider : ITemplateDefinitionProvider, ITransientDependency + { + public abstract void Define(ITemplateDefinitionContext context); + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.TextTemplating.Tests/Volo.Abp.TextTemplating.Tests.csproj b/framework/test/Volo.Abp.TextTemplating.Tests/Volo.Abp.TextTemplating.Tests.csproj index 56e93ae650..bc5a0fc679 100644 --- a/framework/test/Volo.Abp.TextTemplating.Tests/Volo.Abp.TextTemplating.Tests.csproj +++ b/framework/test/Volo.Abp.TextTemplating.Tests/Volo.Abp.TextTemplating.Tests.csproj @@ -1,4 +1,4 @@ - + @@ -10,6 +10,7 @@ + diff --git a/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/AbpTextTemplatingOptions_Tests.cs b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/AbpTextTemplatingOptions_Tests.cs new file mode 100644 index 0000000000..294596c693 --- /dev/null +++ b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/AbpTextTemplatingOptions_Tests.cs @@ -0,0 +1,24 @@ +using Microsoft.Extensions.Options; +using Shouldly; +using Xunit; + +namespace Volo.Abp.TextTemplating +{ + public class AbpTextTemplatingOptions_Tests : AbpTextTemplatingTestBase + { + private readonly AbpTextTemplatingOptions _options; + + public AbpTextTemplatingOptions_Tests() + { + _options = GetRequiredService>().Value; + } + + [Fact] + public void Should_Auto_Add_TemplateDefinitionProviders_To_Options() + { + _options + .DefinitionProviders + .ShouldContain(typeof(TestTemplateDefinitionProvider)); + } + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/AbpTextTemplatingTestBase.cs b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/AbpTextTemplatingTestBase.cs new file mode 100644 index 0000000000..ca5dc20445 --- /dev/null +++ b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/AbpTextTemplatingTestBase.cs @@ -0,0 +1,12 @@ +using Volo.Abp.Testing; + +namespace Volo.Abp.TextTemplating +{ + public abstract class AbpTextTemplatingTestBase : AbpIntegratedTest + { + protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options) + { + options.UseAutofac(); + } + } +} diff --git a/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/AbpTextTemplatingTestModule.cs b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/AbpTextTemplatingTestModule.cs index 280059a40e..057accfc23 100644 --- a/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/AbpTextTemplatingTestModule.cs +++ b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/AbpTextTemplatingTestModule.cs @@ -1,7 +1,13 @@ -using Volo.Abp.Modularity; +using Volo.Abp.Autofac; +using Volo.Abp.Modularity; namespace Volo.Abp.TextTemplating { + [DependsOn( + typeof(AbpTextTemplatingModule), + typeof(AbpTestBaseModule), + typeof(AbpAutofacModule) + )] public class AbpTextTemplatingTestModule : AbpModule { 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 new file mode 100644 index 0000000000..2202c098b1 --- /dev/null +++ b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/TemplateDefinitionTests.cs @@ -0,0 +1,22 @@ +using Shouldly; +using Xunit; + +namespace Volo.Abp.TextTemplating +{ + public class TemplateDefinitionTests : AbpTextTemplatingTestBase + { + private readonly ITemplateDefinitionManager _templateDefinitionManager; + + public TemplateDefinitionTests() + { + _templateDefinitionManager = GetRequiredService(); + } + + [Fact] + public void Should_Retrieve_Template_Definition() + { + var definition = _templateDefinitionManager.Get(TestTemplates.TestTemplate1); + definition.Name.ShouldBe(TestTemplates.TestTemplate1); + } + } +} \ No newline at end of file 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 new file mode 100644 index 0000000000..1ff8be9bab --- /dev/null +++ b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/TestTemplateDefinitionProvider.cs @@ -0,0 +1,14 @@ +namespace Volo.Abp.TextTemplating +{ + public class TestTemplateDefinitionProvider : TemplateDefinitionProvider + { + public override void Define(ITemplateDefinitionContext context) + { + context + .Add(new TemplateDefinition( + TestTemplates.TestTemplate1 + ) + ); + } + } +} 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 new file mode 100644 index 0000000000..8e6e21ea85 --- /dev/null +++ b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/TestTemplates.cs @@ -0,0 +1,7 @@ +namespace Volo.Abp.TextTemplating +{ + public static class TestTemplates + { + public const string TestTemplate1 = "TestTemplate1"; + } +} \ No newline at end of file From 42047737bd002b1fbed40841b95429170a75808b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Wed, 22 Apr 2020 22:23:09 +0300 Subject: [PATCH 04/35] Added more tests for template definitions. --- common.DotSettings | 6 ++++++ .../TextTemplating/ITemplateDefinitionManager.cs | 2 ++ .../TextTemplating/TemplateDefinitionTests.cs | 16 +++++++++++++++- .../TestTemplateDefinitionProvider.cs | 5 ++++- .../Volo/Abp/TextTemplating/TestTemplates.cs | 1 + 5 files changed, 28 insertions(+), 2 deletions(-) diff --git a/common.DotSettings b/common.DotSettings index 0eb4875d49..6f40d029a7 100644 --- a/common.DotSettings +++ b/common.DotSettings @@ -20,5 +20,11 @@ False False SQL + False + False + False + False + False + False True \ No newline at end of file diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateDefinitionManager.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateDefinitionManager.cs index feadd3442f..cbd2d15463 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateDefinitionManager.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateDefinitionManager.cs @@ -8,8 +8,10 @@ namespace Volo.Abp.TextTemplating [NotNull] TemplateDefinition Get([NotNull] string name); + [NotNull] IReadOnlyList GetAll(); + [CanBeNull] TemplateDefinition GetOrNull(string name); } } \ 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 2202c098b1..bc0e8b94c4 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 @@ -13,10 +13,24 @@ namespace Volo.Abp.TextTemplating } [Fact] - public void Should_Retrieve_Template_Definition() + public void Should_Retrieve_Template_Definition_By_Name() { var definition = _templateDefinitionManager.Get(TestTemplates.TestTemplate1); definition.Name.ShouldBe(TestTemplates.TestTemplate1); } + + [Fact] + public void Should_Get_Null_If_Template_Not_Found() + { + var definition = _templateDefinitionManager.GetOrNull("undefined-template"); + definition.ShouldBeNull(); + } + + [Fact] + public void Should_Retrieve_All_Template_Definitions() + { + var definitions = _templateDefinitionManager.GetAll(); + definitions.Count.ShouldBeGreaterThan(1); + } } } \ No newline at end of file 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 1ff8be9bab..134ebdc74a 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 @@ -5,8 +5,11 @@ public override void Define(ITemplateDefinitionContext context) { context - .Add(new TemplateDefinition( + .Add( + new TemplateDefinition( TestTemplates.TestTemplate1 + ), 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 8e6e21ea85..e5b7bcc9ae 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 @@ -3,5 +3,6 @@ public static class TestTemplates { public const string TestTemplate1 = "TestTemplate1"; + public const string TestTemplateLayout1 = "TestTemplateLayout1"; } } \ No newline at end of file From 07aaaa046951f2b9614d9eb8d60a0e798d5feb90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Wed, 22 Apr 2020 23:08:57 +0300 Subject: [PATCH 05/35] Implemented VirtualFileTemplateContributor and added tests. --- .../Volo.Abp.TextTemplating.csproj | 4 +- .../TextTemplating/AbpTextTemplatingModule.cs | 4 + ...emplateContributorInitializationContext.cs | 4 +- .../Abp/TextTemplating/TemplateDefinition.cs | 12 +-- .../VirtualFileTemplateContributor.cs | 84 +++++++++++++++++++ .../Volo.Abp.TextTemplating.Tests.csproj | 5 ++ .../AbpTextTemplatingTestModule.cs | 9 +- .../SampleTemplates/ForgotPasswordEmail.tpl | 1 + .../SampleTemplates/WelcomeEmail/en.tpl | 1 + .../SampleTemplates/WelcomeEmail/tr.tpl | 1 + .../TestTemplateDefinitionProvider.cs | 23 +++-- .../VirtualFileTemplateContributor_Tests.cs | 50 +++++++++++ 12 files changed, 179 insertions(+), 19 deletions(-) create mode 100644 framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContributor.cs create mode 100644 framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/SampleTemplates/ForgotPasswordEmail.tpl create mode 100644 framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/SampleTemplates/WelcomeEmail/en.tpl create mode 100644 framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/SampleTemplates/WelcomeEmail/tr.tpl create mode 100644 framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContributor_Tests.cs diff --git a/framework/src/Volo.Abp.TextTemplating/Volo.Abp.TextTemplating.csproj b/framework/src/Volo.Abp.TextTemplating/Volo.Abp.TextTemplating.csproj index cbc6ba05ec..ba12b60ca7 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo.Abp.TextTemplating.csproj +++ b/framework/src/Volo.Abp.TextTemplating/Volo.Abp.TextTemplating.csproj @@ -1,4 +1,4 @@ - + @@ -15,7 +15,7 @@ - + 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 28b71da4aa..3ef30f5fc2 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/AbpTextTemplatingModule.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/AbpTextTemplatingModule.cs @@ -2,9 +2,13 @@ using System.Collections.Generic; using Microsoft.Extensions.DependencyInjection; using Volo.Abp.Modularity; +using Volo.Abp.VirtualFileSystem; namespace Volo.Abp.TextTemplating { + [DependsOn( + typeof(AbpVirtualFileSystemModule) + )] public class AbpTextTemplatingModule : AbpModule { public override void PreConfigureServices(ServiceConfigurationContext context) diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContributorInitializationContext.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContributorInitializationContext.cs index e8a7332e83..ffe97a3484 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContributorInitializationContext.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContributorInitializationContext.cs @@ -12,8 +12,8 @@ namespace Volo.Abp.TextTemplating public IServiceProvider ServiceProvider { get; } public TemplateContributorInitializationContext( - TemplateDefinition templateDefinition, - IServiceProvider serviceProvider) + [NotNull] TemplateDefinition templateDefinition, + [NotNull] IServiceProvider serviceProvider) { TemplateDefinition = Check.NotNull(templateDefinition, nameof(templateDefinition)); ServiceProvider = Check.NotNull(serviceProvider, nameof(serviceProvider)); diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinition.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinition.cs index b9b7762405..548ac87c15 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinition.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinition.cs @@ -22,15 +22,12 @@ namespace Volo.Abp.TextTemplating [CanBeNull] public string DefaultCultureName { get; } - public bool SingleTemplateFile { get; } //TODO: ??? - public TemplateDefinition( [NotNull] string name, Type localizationResource = null, bool isLayout = false, string layout = DefaultLayoutPlaceHolder, - string defaultCultureName = null, - bool singleTemplateFile = false) + string defaultCultureName = null) { Name = Check.NotNullOrWhiteSpace(name, nameof(name)); LocalizationResource = localizationResource; @@ -38,7 +35,12 @@ namespace Volo.Abp.TextTemplating IsLayout = isLayout; Layout = layout; DefaultCultureName = defaultCultureName; - SingleTemplateFile = singleTemplateFile; + } + + public virtual TemplateDefinition AddContributor(ITemplateContributor contributor) + { + Contributors.Add(contributor); + return this; } } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContributor.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContributor.cs new file mode 100644 index 0000000000..f7a320ab16 --- /dev/null +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContributor.cs @@ -0,0 +1,84 @@ +using System; +using System.Collections.Generic; +using System.Threading; +using JetBrains.Annotations; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.FileProviders; +using Volo.Abp.VirtualFileSystem; + +namespace Volo.Abp.TextTemplating.VirtualFiles +{ + public class VirtualFileTemplateContributor : ITemplateContributor + { + private readonly string _virtualPath; + private IVirtualFileProvider _virtualFileProvider; + private volatile Dictionary _templateDictionary; + private readonly object _syncObj = new object(); + + public VirtualFileTemplateContributor(string virtualPath) + { + _virtualPath = virtualPath; + } + + public void Initialize(TemplateContributorInitializationContext context) + { + _virtualFileProvider = context.ServiceProvider.GetRequiredService(); + } + + public string GetOrNull([CanBeNull] string cultureName = null) + { + var dictionary = GetTemplateDictionary(); + + if (cultureName == null) + { + return dictionary.GetOrDefault("__default"); + } + else + { + return dictionary.GetOrDefault(cultureName) ?? + dictionary.GetOrDefault("__default"); + } + } + + private Dictionary GetTemplateDictionary() + { + if (_templateDictionary != null) + { + return _templateDictionary; + } + + lock (_syncObj) + { + if (_templateDictionary != null) + { + return _templateDictionary; + } + + var dictionary = new Dictionary(); + + var fileInfo = _virtualFileProvider.GetFileInfo(_virtualPath); + if (!fileInfo.IsDirectory) + { + //TODO: __default to consts + dictionary.Add("__default", fileInfo.ReadAsString()); + } + else + { + foreach (var file in _virtualFileProvider.GetDirectoryContents(_virtualPath)) + { + if (file.IsDirectory) + { + continue; + } + + // TODO: How to normalize file names? + dictionary.Add(file.Name.RemovePostFix(".tpl"), file.ReadAsString()); + } + } + + _templateDictionary = dictionary; + return dictionary; + } + } + } +} \ No newline at end of file diff --git a/framework/test/Volo.Abp.TextTemplating.Tests/Volo.Abp.TextTemplating.Tests.csproj b/framework/test/Volo.Abp.TextTemplating.Tests/Volo.Abp.TextTemplating.Tests.csproj index bc5a0fc679..916495b116 100644 --- a/framework/test/Volo.Abp.TextTemplating.Tests/Volo.Abp.TextTemplating.Tests.csproj +++ b/framework/test/Volo.Abp.TextTemplating.Tests/Volo.Abp.TextTemplating.Tests.csproj @@ -7,6 +7,11 @@ + + + + + diff --git a/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/AbpTextTemplatingTestModule.cs b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/AbpTextTemplatingTestModule.cs index 057accfc23..0457e0136d 100644 --- a/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/AbpTextTemplatingTestModule.cs +++ b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/AbpTextTemplatingTestModule.cs @@ -1,5 +1,6 @@ using Volo.Abp.Autofac; using Volo.Abp.Modularity; +using Volo.Abp.VirtualFileSystem; namespace Volo.Abp.TextTemplating { @@ -10,6 +11,12 @@ namespace Volo.Abp.TextTemplating )] public class AbpTextTemplatingTestModule : AbpModule { - + public override void ConfigureServices(ServiceConfigurationContext context) + { + Configure(options => + { + options.FileSets.AddEmbedded("Volo.Abp.TextTemplating"); + }); + } } } 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 new file mode 100644 index 0000000000..674b734c8a --- /dev/null +++ b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/SampleTemplates/ForgotPasswordEmail.tpl @@ -0,0 +1 @@ +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/SampleTemplates/WelcomeEmail/en.tpl b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/SampleTemplates/WelcomeEmail/en.tpl new file mode 100644 index 0000000000..7dbe5e8cb0 --- /dev/null +++ b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/SampleTemplates/WelcomeEmail/en.tpl @@ -0,0 +1 @@ +Welcome to the abp.io! \ No newline at end of file diff --git a/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/SampleTemplates/WelcomeEmail/tr.tpl b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/SampleTemplates/WelcomeEmail/tr.tpl new file mode 100644 index 0000000000..6c70e0afb1 --- /dev/null +++ b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/SampleTemplates/WelcomeEmail/tr.tpl @@ -0,0 +1 @@ +abp.io'ya hoÅŸgeldiniz! \ No newline at end of file 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 134ebdc74a..57244c61c6 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 @@ -1,17 +1,22 @@ -namespace Volo.Abp.TextTemplating +using Volo.Abp.TextTemplating.VirtualFiles; + +namespace Volo.Abp.TextTemplating { public class TestTemplateDefinitionProvider : TemplateDefinitionProvider { public override void Define(ITemplateDefinitionContext context) { - context - .Add( - new TemplateDefinition( - TestTemplates.TestTemplate1 - ), new TemplateDefinition( - TestTemplates.TestTemplateLayout1 - ) - ); + context.Add( + new TemplateDefinition( + TestTemplates.TestTemplate1 + ).AddContributor( + new VirtualFileTemplateContributor("/SampleTemplates/WelcomeEmail") + ) + ); + + context.Add(new TemplateDefinition( + TestTemplates.TestTemplateLayout1 + )); } } } diff --git a/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContributor_Tests.cs b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContributor_Tests.cs new file mode 100644 index 0000000000..d884a5e73b --- /dev/null +++ b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContributor_Tests.cs @@ -0,0 +1,50 @@ +using Shouldly; +using Xunit; + +namespace Volo.Abp.TextTemplating.VirtualFiles +{ + public class VirtualFileTemplateContributor_Tests : AbpTextTemplatingTestBase + { + [Fact] + public void Should_Get_Localized_Content_By_Culture() + { + var contributor = new VirtualFileTemplateContributor( + "/SampleTemplates/WelcomeEmail" + ); + + contributor.Initialize( + new TemplateContributorInitializationContext( + new TemplateDefinition("Test"), + ServiceProvider + ) + ); + + contributor + .GetOrNull("en") + .ShouldBe("Welcome to the abp.io!"); + + contributor + .GetOrNull("tr") + .ShouldBe("abp.io'ya hoÅŸgeldiniz!"); + } + + [Fact] + public void Should_Get_Non_Localized_Template_Content() + { + var contributor = new VirtualFileTemplateContributor( + "/SampleTemplates/ForgotPasswordEmail.tpl" + ); + + contributor.Initialize( + new TemplateContributorInitializationContext( + new TemplateDefinition("Test"), + ServiceProvider + ) + ); + + contributor + .GetOrNull() + .ShouldBe("Please click to the following link to get an email to reset your password!"); + } + } +} From 9060b695ea6c06682a8d11c390463cd84b40423b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Wed, 22 Apr 2020 23:18:12 +0300 Subject: [PATCH 06/35] Added TemplateDefinitionExtensions. --- .../TemplateDefinitionExtensions.cs | 19 +++++++++++++++++++ .../VirtualFileTemplateContributor.cs | 6 +++--- .../TestTemplateDefinitionProvider.cs | 8 ++------ 3 files changed, 24 insertions(+), 9 deletions(-) create mode 100644 framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionExtensions.cs diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionExtensions.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionExtensions.cs new file mode 100644 index 0000000000..6508295da7 --- /dev/null +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionExtensions.cs @@ -0,0 +1,19 @@ +using JetBrains.Annotations; +using Volo.Abp.TextTemplating.VirtualFiles; + +namespace Volo.Abp.TextTemplating +{ + public static class TemplateDefinitionExtensions + { + public static TemplateDefinition AddVirtualFiles( + [NotNull] this TemplateDefinition templateDefinition, + [NotNull] string virtualPath) + { + Check.NotNull(templateDefinition, nameof(templateDefinition)); + + return templateDefinition.AddContributor( + new VirtualFileTemplateContributor(virtualPath) + ); + } + } +} diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContributor.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContributor.cs index f7a320ab16..869a9cb7b1 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContributor.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContributor.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Threading; using JetBrains.Annotations; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.FileProviders; @@ -15,9 +14,10 @@ namespace Volo.Abp.TextTemplating.VirtualFiles private volatile Dictionary _templateDictionary; private readonly object _syncObj = new object(); - public VirtualFileTemplateContributor(string virtualPath) + public VirtualFileTemplateContributor( + [NotNull] string virtualPath) { - _virtualPath = virtualPath; + _virtualPath = Check.NotNullOrWhiteSpace(virtualPath, nameof(virtualPath)); } public void Initialize(TemplateContributorInitializationContext context) 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 57244c61c6..f47d31ac4e 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 @@ -1,6 +1,4 @@ -using Volo.Abp.TextTemplating.VirtualFiles; - -namespace Volo.Abp.TextTemplating +namespace Volo.Abp.TextTemplating { public class TestTemplateDefinitionProvider : TemplateDefinitionProvider { @@ -9,9 +7,7 @@ namespace Volo.Abp.TextTemplating context.Add( new TemplateDefinition( TestTemplates.TestTemplate1 - ).AddContributor( - new VirtualFileTemplateContributor("/SampleTemplates/WelcomeEmail") - ) + ).AddVirtualFiles("/SampleTemplates/WelcomeEmail") ); context.Add(new TemplateDefinition( From 67dbc9b453cdaf5564e24ff44117d8d991648851 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Thu, 23 Apr 2020 15:06:20 +0300 Subject: [PATCH 07/35] Added template content provider and template renderer. --- .../TextTemplating/AbpTextTemplatingModule.cs | 23 ++++++++++++ .../ITemplateContentProvider.cs | 9 +++++ .../TextTemplating/ITemplateContributor.cs | 6 ++-- .../Abp/TextTemplating/ITemplateRenderer.cs | 14 ++++++++ .../TextTemplating/TemplateContentProvider.cs | 35 +++++++++++++++++++ .../TextTemplating/TemplateContributorList.cs | 15 +------- .../Abp/TextTemplating/TemplateRenderer.cs | 30 ++++++++++++++++ .../TextTemplating/TemplateDefinitionTests.cs | 4 +-- .../TextTemplating/TemplateRenderer_Tests.cs | 23 ++++++++++++ .../TestTemplateDefinitionProvider.cs | 8 ++++- .../Volo/Abp/TextTemplating/TestTemplates.cs | 3 +- 11 files changed, 150 insertions(+), 20 deletions(-) create mode 100644 framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateContentProvider.cs create mode 100644 framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateRenderer.cs create mode 100644 framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentProvider.cs create mode 100644 framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateRenderer.cs create mode 100644 framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/TemplateRenderer_Tests.cs 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 From 24365e49797a109921dee0eed4938c57e5baa9a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Thu, 23 Apr 2020 15:11:19 +0300 Subject: [PATCH 08/35] Use Scriban on TemplateRenderer --- .../Volo.Abp.TextTemplating.csproj | 4 ++++ .../Volo/Abp/TextTemplating/ITemplateRenderer.cs | 1 + .../Volo/Abp/TextTemplating/TemplateRenderer.cs | 11 ++++++++--- .../Volo/Abp/TextTemplating/TemplateRenderer_Tests.cs | 4 +++- 4 files changed, 16 insertions(+), 4 deletions(-) diff --git a/framework/src/Volo.Abp.TextTemplating/Volo.Abp.TextTemplating.csproj b/framework/src/Volo.Abp.TextTemplating/Volo.Abp.TextTemplating.csproj index ba12b60ca7..404259ae17 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo.Abp.TextTemplating.csproj +++ b/framework/src/Volo.Abp.TextTemplating/Volo.Abp.TextTemplating.csproj @@ -14,6 +14,10 @@ + + + + diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateRenderer.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateRenderer.cs index d65f77653a..92a1c0782c 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateRenderer.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateRenderer.cs @@ -8,6 +8,7 @@ namespace Volo.Abp.TextTemplating { Task RenderAsync( [NotNull] string templateName, + [CanBeNull] object model = null, [CanBeNull] string cultureName = null ); } 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 dcc36081fd..127e7e9872 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateRenderer.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateRenderer.cs @@ -1,5 +1,6 @@ using System.Threading.Tasks; using JetBrains.Annotations; +using Scriban; using Volo.Abp.DependencyInjection; namespace Volo.Abp.TextTemplating @@ -9,22 +10,26 @@ namespace Volo.Abp.TextTemplating private readonly ITemplateContentProvider _templateContentProvider; public TemplateRenderer( - ITemplateContentProvider templateContentProvider - ) + ITemplateContentProvider templateContentProvider) { _templateContentProvider = templateContentProvider; } public virtual async Task RenderAsync( [NotNull] string templateName, + [CanBeNull] object model = null, [CanBeNull] string cultureName = null) { Check.NotNullOrWhiteSpace(templateName, nameof(templateName)); - return await _templateContentProvider.GetContentOrNullAsync( + var content = await _templateContentProvider.GetContentOrNullAsync( templateName, cultureName ); + + var parsedTemplate = Template.Parse(content); + + return await parsedTemplate.RenderAsync(model); } } } \ 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 e4c5481413..70e257ae9a 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 @@ -16,7 +16,9 @@ namespace Volo.Abp.TextTemplating [Fact] public async Task Should_Get_Rendered_Non_Localized_Template_Content() { - var content = await _templateRenderer.RenderAsync(TestTemplates.ForgotPasswordEmail); + var content = await _templateRenderer.RenderAsync( + TestTemplates.ForgotPasswordEmail + ); content.ShouldBe("Please click to the following link to get an email to reset your password!"); } } From 61d2512311f832e7eb8c1be12c6915a2e7b3b9a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Thu, 23 Apr 2020 15:43:04 +0300 Subject: [PATCH 09/35] Implemented template renderer. --- .../Volo/Abp/Localization/CultureHelper.cs | 7 ++ .../AbpDictionaryBasedStringLocalizer.cs | 11 +-- .../ITemplateContentProvider.cs | 6 +- .../TextTemplating/TemplateContentProvider.cs | 5 +- .../VirtualFileTemplateContributor.cs | 39 +++++++-- .../SampleTemplates/WelcomeEmail/en.tpl | 2 +- .../SampleTemplates/WelcomeEmail/tr.tpl | 2 +- .../TextTemplating/TemplateRenderer_Tests.cs | 81 ++++++++++++++++++- .../TestTemplateDefinitionProvider.cs | 3 +- .../VirtualFileTemplateContributor_Tests.cs | 4 +- 10 files changed, 139 insertions(+), 21 deletions(-) diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Localization/CultureHelper.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Localization/CultureHelper.cs index 92320f737c..8f663e084e 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Localization/CultureHelper.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Localization/CultureHelper.cs @@ -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; + } } } diff --git a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/AbpDictionaryBasedStringLocalizer.cs b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/AbpDictionaryBasedStringLocalizer.cs index 79c164eb5f..53a2d7714e 100644 --- a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/AbpDictionaryBasedStringLocalizer.cs +++ b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/AbpDictionaryBasedStringLocalizer.cs @@ -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 { diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateContentProvider.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateContentProvider.cs index d4dc5615fb..526da6a381 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateContentProvider.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateContentProvider.cs @@ -1,9 +1,13 @@ using System.Threading.Tasks; +using JetBrains.Annotations; namespace Volo.Abp.TextTemplating { public interface ITemplateContentProvider { - Task GetContentOrNullAsync(string templateName, string cultureName); + Task GetContentOrNullAsync( + [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 index ab81d8b9f7..1334b5b1dd 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentProvider.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentProvider.cs @@ -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 GetContentOrNullAsync(string templateName, string cultureName) + public async Task GetContentOrNullAsync( + [NotNull] string templateName, + [CanBeNull] string cultureName = null) { var template = _templateDefinitionManager.Get(templateName); diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContributor.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContributor.cs index 869a9cb7b1..f1a4700da7 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContributor.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContributor.cs @@ -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 _templateDictionary; @@ -23,21 +27,46 @@ namespace Volo.Abp.TextTemplating.VirtualFiles public void Initialize(TemplateContributorInitializationContext context) { _virtualFileProvider = context.ServiceProvider.GetRequiredService(); + 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 GetTemplateDictionary() diff --git a/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/SampleTemplates/WelcomeEmail/en.tpl b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/SampleTemplates/WelcomeEmail/en.tpl index 7dbe5e8cb0..1088362628 100644 --- a/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/SampleTemplates/WelcomeEmail/en.tpl +++ b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/SampleTemplates/WelcomeEmail/en.tpl @@ -1 +1 @@ -Welcome to the abp.io! \ No newline at end of file +Welcome {{name}} to the abp.io! \ No newline at end of file diff --git a/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/SampleTemplates/WelcomeEmail/tr.tpl b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/SampleTemplates/WelcomeEmail/tr.tpl index 6c70e0afb1..b457611f1e 100644 --- a/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/SampleTemplates/WelcomeEmail/tr.tpl +++ b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/SampleTemplates/WelcomeEmail/tr.tpl @@ -1 +1 @@ -abp.io'ya hoÅŸgeldiniz! \ No newline at end of file +Merhaba {{name}}, abp.io'ya hoÅŸgeldiniz! \ 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 70e257ae9a..9e76d22ab8 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 @@ -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() { { "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; + } + } } } 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 d400964684..7a1ff4121b 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,7 +6,8 @@ { context.Add( new TemplateDefinition( - TestTemplates.WelcomeEmail + TestTemplates.WelcomeEmail, + defaultCultureName: "en" ).AddVirtualFiles("/SampleTemplates/WelcomeEmail") ); diff --git a/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContributor_Tests.cs b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContributor_Tests.cs index d884a5e73b..1c636d7813 100644 --- a/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContributor_Tests.cs +++ b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContributor_Tests.cs @@ -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] From 8fb41d9e430bbcd81bdb15c2a52aeca0cc22b6f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Thu, 23 Apr 2020 17:32:47 +0300 Subject: [PATCH 10/35] Delete email template system and use the text template system. --- .../Volo.Abp.Emailing.csproj | 5 +- .../Volo/Abp/Emailing/AbpEmailingModule.cs | 50 +------- .../Templates/AbpEmailTemplateOptions.cs | 18 --- .../Templates/DefaultEmailTemplateProvider.cs | 24 +++- .../DefaultEmailTemplates/Layout/en.tpl | 2 +- .../Abp/Emailing/Templates/EmailTemplate.cs | 42 ------ .../Templates/EmailTemplateContributorList.cs | 22 ---- .../Templates/EmailTemplateDefinition.cs | 36 ------ .../EmailTemplateDefinitionContext.cs | 38 ------ .../EmailTemplateDefinitionDictionary.cs | 22 ---- .../EmailTemplateDefinitionManager.cs | 74 ----------- .../EmailTemplateDefinitionProvider.cs | 9 -- .../EmailTemplateInitializationContext.cs | 18 --- .../Templates/EmailTemplateProvider.cs | 121 ------------------ .../Templates/IEmailTemplateContributor.cs | 9 -- .../IEmailTemplateDefinitionContext.cs | 9 -- .../IEmailTemplateDefinitionManager.cs | 15 --- .../IEmailTemplateDefinitionProvider.cs | 7 - .../Templates/IEmailTemplateProvider.cs | 11 -- .../Abp/Emailing/Templates/ITemplateRender.cs | 9 -- .../Abp/Emailing/Templates/TemplateRender.cs | 15 --- .../EmailTemplateDefinitionExtensions.cs | 19 --- ...pleVirtualFilesEmailTemplateContributor.cs | 68 ---------- ...ngleVirtualFileEmailTemplateContributor.cs | 34 ----- .../Abp/Localization/TemplateLocalizer.cs | 18 --- .../ITemplateContentProvider.cs | 5 + .../TextTemplating/TemplateContentProvider.cs | 16 ++- .../Abp/TextTemplating/TemplateDefinition.cs | 5 +- .../Abp/TextTemplating/TemplateRenderer.cs | 47 ++++++- .../Volo.Abp.Emailing.Tests.csproj | 7 - .../Abp/Emailing/AbpEmailingTestModule.cs | 10 -- .../Abp/Emailing/EmailTemplateRender_Tests.cs | 65 ---------- .../Abp/Emailing/EmailTemplateStore_Tests.cs | 54 -------- .../Localization/AbpEmailingTestResource.cs | 10 -- .../Volo/Abp/Emailing/Localization/cs.json | 6 - .../Volo/Abp/Emailing/Localization/en.json | 6 - .../Volo/Abp/Emailing/Localization/pl.json | 6 - .../Volo/Abp/Emailing/Localization/pt-BR.json | 6 - .../Volo/Abp/Emailing/Localization/tr.json | 6 - .../Volo/Abp/Emailing/Localization/vi.json | 6 - .../Abp/Emailing/Localization/zh-Hant.json | 6 - .../Abp/Emailing/TestEmailTemplateProvider.cs | 24 ---- .../Emailing/TestTemplates/Template1/en.tpl | 4 - .../Emailing/TestTemplates/Template1/tr.tpl | 4 - .../Emailing/TestTemplates/Template2/en.tpl | 4 - .../TestTemplates/Template3/Template.tpl | 1 - .../Localization/TemplateLocalizer_Tests.cs | 63 --------- 47 files changed, 85 insertions(+), 971 deletions(-) delete mode 100644 framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/AbpEmailTemplateOptions.cs delete mode 100644 framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplate.cs delete mode 100644 framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateContributorList.cs delete mode 100644 framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateDefinition.cs delete mode 100644 framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateDefinitionContext.cs delete mode 100644 framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateDefinitionDictionary.cs delete mode 100644 framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateDefinitionManager.cs delete mode 100644 framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateDefinitionProvider.cs delete mode 100644 framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateInitializationContext.cs delete mode 100644 framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateProvider.cs delete mode 100644 framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/IEmailTemplateContributor.cs delete mode 100644 framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/IEmailTemplateDefinitionContext.cs delete mode 100644 framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/IEmailTemplateDefinitionManager.cs delete mode 100644 framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/IEmailTemplateDefinitionProvider.cs delete mode 100644 framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/IEmailTemplateProvider.cs delete mode 100644 framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/ITemplateRender.cs delete mode 100644 framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/TemplateRender.cs delete mode 100644 framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/VirtualFiles/EmailTemplateDefinitionExtensions.cs delete mode 100644 framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/VirtualFiles/MultipleVirtualFilesEmailTemplateContributor.cs delete mode 100644 framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/VirtualFiles/SingleVirtualFileEmailTemplateContributor.cs delete mode 100644 framework/src/Volo.Abp.Localization/Volo/Abp/Localization/TemplateLocalizer.cs delete mode 100644 framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/EmailTemplateRender_Tests.cs delete mode 100644 framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/EmailTemplateStore_Tests.cs delete mode 100644 framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/Localization/AbpEmailingTestResource.cs delete mode 100644 framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/Localization/cs.json delete mode 100644 framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/Localization/en.json delete mode 100644 framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/Localization/pl.json delete mode 100644 framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/Localization/pt-BR.json delete mode 100644 framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/Localization/tr.json delete mode 100644 framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/Localization/vi.json delete mode 100644 framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/Localization/zh-Hant.json delete mode 100644 framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/TestEmailTemplateProvider.cs delete mode 100644 framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/TestTemplates/Template1/en.tpl delete mode 100644 framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/TestTemplates/Template1/tr.tpl delete mode 100644 framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/TestTemplates/Template2/en.tpl delete mode 100644 framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/TestTemplates/Template3/Template.tpl delete mode 100644 framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TemplateLocalizer_Tests.cs diff --git a/framework/src/Volo.Abp.Emailing/Volo.Abp.Emailing.csproj b/framework/src/Volo.Abp.Emailing/Volo.Abp.Emailing.csproj index be953a1f26..783d840cf0 100644 --- a/framework/src/Volo.Abp.Emailing/Volo.Abp.Emailing.csproj +++ b/framework/src/Volo.Abp.Emailing/Volo.Abp.Emailing.csproj @@ -24,14 +24,11 @@ - - - - + diff --git a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/AbpEmailingModule.cs b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/AbpEmailingModule.cs index 9641f7c14c..afcbaf6aef 100644 --- a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/AbpEmailingModule.cs +++ b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/AbpEmailingModule.cs @@ -1,12 +1,9 @@ -using System; -using System.Collections.Generic; -using Microsoft.Extensions.DependencyInjection; -using Volo.Abp.BackgroundJobs; +using Volo.Abp.BackgroundJobs; using Volo.Abp.Emailing.Localization; -using Volo.Abp.Emailing.Templates; using Volo.Abp.Localization; using Volo.Abp.Modularity; using Volo.Abp.Settings; +using Volo.Abp.TextTemplating; using Volo.Abp.VirtualFileSystem; namespace Volo.Abp.Emailing @@ -15,15 +12,11 @@ namespace Volo.Abp.Emailing typeof(AbpSettingsModule), typeof(AbpVirtualFileSystemModule), typeof(AbpBackgroundJobsAbstractionsModule), - typeof(AbpLocalizationModule) + typeof(AbpLocalizationModule), + typeof(AbpTextTemplatingModule) )] public class AbpEmailingModule : AbpModule { - public override void PreConfigureServices(ServiceConfigurationContext context) - { - AutoAddDefinitionProviders(context.Services); - } - public override void ConfigureServices(ServiceConfigurationContext context) { Configure(options => @@ -43,40 +36,5 @@ namespace Volo.Abp.Emailing options.AddJob(); }); } - - private static void AutoAddDefinitionProviders(IServiceCollection services) - { - var definitionProviders = new List(); - - services.OnRegistred(context => - { - if (typeof(IEmailTemplateDefinitionProvider).IsAssignableFrom(context.ImplementationType)) - { - definitionProviders.Add(context.ImplementationType); - } - }); - - services.Configure(options => - { - options.DefinitionProviders.AddIfNotContains(definitionProviders); - }); - } - - public override void OnApplicationInitialization(ApplicationInitializationContext context) - { - using (var scope = context.ServiceProvider.CreateScope()) - { - var emailTemplateDefinitionManager = - scope.ServiceProvider.GetRequiredService(); - - foreach (var templateDefinition in emailTemplateDefinitionManager.GetAll()) - { - foreach (var contributor in templateDefinition.Contributors) - { - contributor.Initialize(new EmailTemplateInitializationContext(templateDefinition, scope.ServiceProvider)); - } - } - } - } } } diff --git a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/AbpEmailTemplateOptions.cs b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/AbpEmailTemplateOptions.cs deleted file mode 100644 index cb5a9d370b..0000000000 --- a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/AbpEmailTemplateOptions.cs +++ /dev/null @@ -1,18 +0,0 @@ -using Volo.Abp.Collections; - -namespace Volo.Abp.Emailing.Templates -{ - public class AbpEmailTemplateOptions - { - public string DefaultLayout { get; set; } - - public ITypeList DefinitionProviders { get; } - - public AbpEmailTemplateOptions() - { - DefaultLayout = StandardEmailTemplates.DefaultLayout; - - DefinitionProviders = new TypeList(); - } - } -} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/DefaultEmailTemplateProvider.cs b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/DefaultEmailTemplateProvider.cs index c15012f0bf..28d1ac94c1 100644 --- a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/DefaultEmailTemplateProvider.cs +++ b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/DefaultEmailTemplateProvider.cs @@ -1,16 +1,26 @@ -using Volo.Abp.Emailing.Templates.VirtualFiles; +using Volo.Abp.TextTemplating; namespace Volo.Abp.Emailing.Templates { - public class DefaultEmailTemplateProvider : EmailTemplateDefinitionProvider + public class DefaultEmailTemplateProvider : TemplateDefinitionProvider { - public override void Define(IEmailTemplateDefinitionContext context) + public override void Define(ITemplateDefinitionContext context) { - context.Add(new EmailTemplateDefinition(StandardEmailTemplates.DefaultLayout, defaultCultureName: "en", isLayout: true, layout: null) - .AddTemplateVirtualFiles("/Volo/Abp/Emailing/Templates/DefaultEmailTemplates/Layout")); + context.Add( + new TemplateDefinition( + StandardEmailTemplates.DefaultLayout, + defaultCultureName: "en", + isLayout: true, + layout: null + ).AddVirtualFiles("/Volo/Abp/Emailing/Templates/DefaultEmailTemplates/Layout") + ); - context.Add(new EmailTemplateDefinition(StandardEmailTemplates.SimpleMessage, defaultCultureName: "en") - .AddTemplateVirtualFiles("/Volo/Abp/Emailing/Templates/DefaultEmailTemplates/Message")); + context.Add( + new TemplateDefinition( + StandardEmailTemplates.SimpleMessage, + defaultCultureName: "en" + ).AddVirtualFiles("/Volo/Abp/Emailing/Templates/DefaultEmailTemplates/Message") + ); } } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/DefaultEmailTemplates/Layout/en.tpl b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/DefaultEmailTemplates/Layout/en.tpl index 107fbb5230..57453a027f 100644 --- a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/DefaultEmailTemplates/Layout/en.tpl +++ b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/DefaultEmailTemplates/Layout/en.tpl @@ -4,6 +4,6 @@ - {{#content}} + {{content}} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplate.cs b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplate.cs deleted file mode 100644 index ad6f8c4839..0000000000 --- a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplate.cs +++ /dev/null @@ -1,42 +0,0 @@ -using System.Text; - -namespace Volo.Abp.Emailing.Templates -{ - public class EmailTemplate - { - public EmailTemplateDefinition Definition { get; } - - public string Content => ContentBuilder.ToString(); - - protected StringBuilder ContentBuilder { get; set; } - - public EmailTemplate(string content, EmailTemplateDefinition definition) - { - ContentBuilder = new StringBuilder(content); - Definition = definition; - } - - public virtual void SetLayout(EmailTemplate layoutTemplate) - { - if (!layoutTemplate.Definition.IsLayout) - { - throw new AbpException($"Given template is not a layout template: {layoutTemplate.Definition.Name}"); - } - - var newStrBuilder = new StringBuilder(layoutTemplate.Content); - newStrBuilder.Replace("{{#content}}", ContentBuilder.ToString()); - - ContentBuilder = newStrBuilder; - } - - public virtual void SetContent(string content) - { - ContentBuilder = new StringBuilder(content); - } - - public virtual void Replace(string name, string value) - { - ContentBuilder.Replace("{{" + name + "}}", value); - } - } -} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateContributorList.cs b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateContributorList.cs deleted file mode 100644 index 44a91212ea..0000000000 --- a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateContributorList.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.Collections.Generic; -using System.Linq; - -namespace Volo.Abp.Emailing.Templates -{ - public class EmailTemplateContributorList : 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.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateDefinition.cs b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateDefinition.cs deleted file mode 100644 index 19f0eb2fa7..0000000000 --- a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateDefinition.cs +++ /dev/null @@ -1,36 +0,0 @@ -using System; -using JetBrains.Annotations; - -namespace Volo.Abp.Emailing.Templates -{ - public class EmailTemplateDefinition - { - public const string DefaultLayoutPlaceHolder = "_"; - - public string Name { get; } - - public bool IsLayout { get; } - - public string Layout { get; set; } - - public Type LocalizationResource { get; set; } - - public EmailTemplateContributorList Contributors { get; } - - public string DefaultCultureName { get; } - - public bool SingleTemplateFile { get; } - - public EmailTemplateDefinition([NotNull] string name, Type localizationResource = null, bool isLayout = false, - string layout = DefaultLayoutPlaceHolder, string defaultCultureName = null, bool singleTemplateFile = false) - { - Name = Check.NotNullOrWhiteSpace(name, nameof(name)); - LocalizationResource = localizationResource; - Contributors = new EmailTemplateContributorList(); - IsLayout = isLayout; - Layout = layout; - DefaultCultureName = defaultCultureName; - SingleTemplateFile = singleTemplateFile; - } - } -} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateDefinitionContext.cs b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateDefinitionContext.cs deleted file mode 100644 index 03a6c95d8b..0000000000 --- a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateDefinitionContext.cs +++ /dev/null @@ -1,38 +0,0 @@ -using System.Collections.Generic; -using System.Collections.Immutable; - -namespace Volo.Abp.Emailing.Templates -{ - public class EmailTemplateDefinitionContext : IEmailTemplateDefinitionContext - { - protected Dictionary EmailTemplates { get; } - - public EmailTemplateDefinitionContext(Dictionary emailTemplates) - { - EmailTemplates = emailTemplates; - } - - public virtual EmailTemplateDefinition GetOrNull(string name) - { - return EmailTemplates.GetOrDefault(name); - } - - public virtual IReadOnlyList GetAll() - { - return EmailTemplates.Values.ToImmutableList(); - } - - public virtual void Add(params EmailTemplateDefinition[] definitions) - { - if (definitions.IsNullOrEmpty()) - { - return; - } - - foreach (var definition in definitions) - { - EmailTemplates[definition.Name] = definition; - } - } - } -} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateDefinitionDictionary.cs b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateDefinitionDictionary.cs deleted file mode 100644 index aa36232156..0000000000 --- a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateDefinitionDictionary.cs +++ /dev/null @@ -1,22 +0,0 @@ -using System.Collections.Generic; - -namespace Volo.Abp.Emailing.Templates -{ - public class EmailTemplateDefinitionDictionary : Dictionary - { - public EmailTemplateDefinitionDictionary Add(EmailTemplateDefinition emailTemplateDefinition) - { - if (ContainsKey(emailTemplateDefinition.Name)) - { - throw new AbpException( - "There is already an email template definition with given name: " + - emailTemplateDefinition.Name - ); - } - - this[emailTemplateDefinition.Name] = emailTemplateDefinition; - - return this; - } - } -} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateDefinitionManager.cs b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateDefinitionManager.cs deleted file mode 100644 index 0491dc867e..0000000000 --- a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateDefinitionManager.cs +++ /dev/null @@ -1,74 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.Immutable; -using System.Linq; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Options; -using Volo.Abp.DependencyInjection; - -namespace Volo.Abp.Emailing.Templates -{ - public class EmailTemplateDefinitionManager : IEmailTemplateDefinitionManager, ISingletonDependency - { - protected Lazy> EmailTemplateDefinitions { get; } - - protected AbpEmailTemplateOptions Options { get; } - - protected IServiceProvider ServiceProvider { get; } - - public EmailTemplateDefinitionManager( - IOptions options, - IServiceProvider serviceProvider) - { - ServiceProvider = serviceProvider; - Options = options.Value; - - EmailTemplateDefinitions = - new Lazy>(CreateEmailTemplateDefinitions, true); - } - - public virtual EmailTemplateDefinition Get(string name) - { - Check.NotNull(name, nameof(name)); - - var template = GetOrNull(name); - - if (template == null) - { - throw new AbpException("Undefined template: " + name); - } - - return template; - } - - public virtual IReadOnlyList GetAll() - { - return EmailTemplateDefinitions.Value.Values.ToImmutableList(); - } - - public virtual EmailTemplateDefinition GetOrNull(string name) - { - return EmailTemplateDefinitions.Value.GetOrDefault(name); - } - - protected virtual IDictionary CreateEmailTemplateDefinitions() - { - var templates = new Dictionary(); - - using (var scope = ServiceProvider.CreateScope()) - { - var providers = Options - .DefinitionProviders - .Select(p => scope.ServiceProvider.GetRequiredService(p) as IEmailTemplateDefinitionProvider) - .ToList(); - - foreach (var provider in providers) - { - provider.Define(new EmailTemplateDefinitionContext(templates)); - } - } - - return templates; - } - } -} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateDefinitionProvider.cs b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateDefinitionProvider.cs deleted file mode 100644 index e53505fafc..0000000000 --- a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateDefinitionProvider.cs +++ /dev/null @@ -1,9 +0,0 @@ -using Volo.Abp.DependencyInjection; - -namespace Volo.Abp.Emailing.Templates -{ - public abstract class EmailTemplateDefinitionProvider : IEmailTemplateDefinitionProvider, ITransientDependency - { - public abstract void Define(IEmailTemplateDefinitionContext context); - } -} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateInitializationContext.cs b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateInitializationContext.cs deleted file mode 100644 index 8cd4b95bbd..0000000000 --- a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateInitializationContext.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System; - -namespace Volo.Abp.Emailing.Templates -{ - public class EmailTemplateInitializationContext - { - public EmailTemplateDefinition EmailTemplateDefinition { get; } - - public IServiceProvider ServiceProvider { get; } - - public EmailTemplateInitializationContext(EmailTemplateDefinition emailTemplateDefinition, - IServiceProvider serviceProvider) - { - EmailTemplateDefinition = emailTemplateDefinition; - ServiceProvider = serviceProvider; - } - } -} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateProvider.cs b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateProvider.cs deleted file mode 100644 index 29fcf08664..0000000000 --- a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateProvider.cs +++ /dev/null @@ -1,121 +0,0 @@ -using System; -using System.Globalization; -using System.Threading.Tasks; -using Microsoft.Extensions.Localization; -using Microsoft.Extensions.Options; -using Volo.Abp.DependencyInjection; -using Volo.Abp.Localization; - -namespace Volo.Abp.Emailing.Templates -{ - public class EmailTemplateProvider : IEmailTemplateProvider, ITransientDependency - { - protected IEmailTemplateDefinitionManager EmailTemplateDefinitionManager; - protected ITemplateLocalizer TemplateLocalizer { get; } - protected AbpEmailTemplateOptions Options { get; } - protected IStringLocalizerFactory StringLocalizerFactory; - - public EmailTemplateProvider(IEmailTemplateDefinitionManager emailTemplateDefinitionManager, - ITemplateLocalizer templateLocalizer, IStringLocalizerFactory stringLocalizerFactory, - IOptions options) - { - EmailTemplateDefinitionManager = emailTemplateDefinitionManager; - TemplateLocalizer = templateLocalizer; - StringLocalizerFactory = stringLocalizerFactory; - Options = options.Value; - } - - public async Task GetAsync(string name) - { - return await GetAsync(name, CultureInfo.CurrentUICulture.Name); - } - - public async Task GetAsync(string name, string cultureName) - { - return await GetInternalAsync(name, cultureName); - } - - protected virtual async Task GetInternalAsync(string name, string cultureName) - { - var emailTemplateDefinition = EmailTemplateDefinitionManager.GetOrNull(name); - if (emailTemplateDefinition == null) - { - // TODO: Localized message - throw new AbpException($"email template {name} not definition"); - } - - var emailTemplateString = emailTemplateDefinition.Contributors.GetOrNull(cultureName); - if (emailTemplateString == null && emailTemplateDefinition.DefaultCultureName != null) - { - emailTemplateString = - emailTemplateDefinition.Contributors.GetOrNull(emailTemplateDefinition.DefaultCultureName); - if (emailTemplateString != null) - { - cultureName = emailTemplateDefinition.DefaultCultureName; - } - } - - if (emailTemplateString != null) - { - var emailTemplate = new EmailTemplate(emailTemplateString, emailTemplateDefinition); - - await SetLayoutAsync(emailTemplateDefinition, emailTemplate, cultureName); - - if (emailTemplateDefinition.SingleTemplateFile) - { - await LocalizeAsync(emailTemplateDefinition, emailTemplate, cultureName); - } - - return emailTemplate; - } - - // TODO: Localized message - throw new AbpException($"{cultureName} template not exist!"); - } - - protected virtual async Task SetLayoutAsync(EmailTemplateDefinition emailTemplateDefinition, - EmailTemplate emailTemplate, string cultureName) - { - var layout = emailTemplateDefinition.Layout; - if (layout.IsNullOrWhiteSpace()) - { - return; - } - - if (layout == EmailTemplateDefinition.DefaultLayoutPlaceHolder) - { - layout = Options.DefaultLayout; - } - - var layoutTemplate = await GetInternalAsync(layout, cultureName); - - emailTemplate.SetLayout(layoutTemplate); - } - - protected virtual Task LocalizeAsync(EmailTemplateDefinition emailTemplateDefinition, - EmailTemplate emailTemplate, string cultureName) - { - if (emailTemplateDefinition.LocalizationResource == null) - { - return Task.CompletedTask; - } - - var localizer = StringLocalizerFactory.Create(emailTemplateDefinition.LocalizationResource); - if (cultureName != null) - { - using (CultureHelper.Use(new CultureInfo(cultureName))) - { - emailTemplate.SetContent(TemplateLocalizer.Localize(localizer, emailTemplate.Content)); - } - } - else - { - emailTemplate.SetContent( - TemplateLocalizer.Localize(localizer, emailTemplate.Content) - ); - } - - return Task.CompletedTask; - } - } -} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/IEmailTemplateContributor.cs b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/IEmailTemplateContributor.cs deleted file mode 100644 index d2c2775845..0000000000 --- a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/IEmailTemplateContributor.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Volo.Abp.Emailing.Templates -{ - public interface IEmailTemplateContributor - { - void Initialize(EmailTemplateInitializationContext context); - - string GetOrNull(string cultureName); - } -} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/IEmailTemplateDefinitionContext.cs b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/IEmailTemplateDefinitionContext.cs deleted file mode 100644 index 1641562ccf..0000000000 --- a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/IEmailTemplateDefinitionContext.cs +++ /dev/null @@ -1,9 +0,0 @@ -namespace Volo.Abp.Emailing.Templates -{ - public interface IEmailTemplateDefinitionContext - { - EmailTemplateDefinition GetOrNull(string name); - - void Add(params EmailTemplateDefinition[] definitions); - } -} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/IEmailTemplateDefinitionManager.cs b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/IEmailTemplateDefinitionManager.cs deleted file mode 100644 index 0936a2fe93..0000000000 --- a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/IEmailTemplateDefinitionManager.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System.Collections.Generic; -using JetBrains.Annotations; - -namespace Volo.Abp.Emailing.Templates -{ - public interface IEmailTemplateDefinitionManager - { - [NotNull] - EmailTemplateDefinition Get([NotNull] string name); - - IReadOnlyList GetAll(); - - EmailTemplateDefinition GetOrNull(string name); - } -} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/IEmailTemplateDefinitionProvider.cs b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/IEmailTemplateDefinitionProvider.cs deleted file mode 100644 index 691d3874d6..0000000000 --- a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/IEmailTemplateDefinitionProvider.cs +++ /dev/null @@ -1,7 +0,0 @@ -namespace Volo.Abp.Emailing.Templates -{ - public interface IEmailTemplateDefinitionProvider - { - void Define(IEmailTemplateDefinitionContext context); - } -} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/IEmailTemplateProvider.cs b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/IEmailTemplateProvider.cs deleted file mode 100644 index ab68dbe2ca..0000000000 --- a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/IEmailTemplateProvider.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System.Threading.Tasks; - -namespace Volo.Abp.Emailing.Templates -{ - public interface IEmailTemplateProvider - { - Task GetAsync(string name); - - Task GetAsync(string name, string cultureName); - } -} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/ITemplateRender.cs b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/ITemplateRender.cs deleted file mode 100644 index 35ac14c8fd..0000000000 --- a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/ITemplateRender.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.Threading.Tasks; - -namespace Volo.Abp.Emailing.Templates -{ - public interface ITemplateRender - { - Task RenderAsync(string template, object model = null); - } -} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/TemplateRender.cs b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/TemplateRender.cs deleted file mode 100644 index 8c4e24017c..0000000000 --- a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/TemplateRender.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System.Threading.Tasks; -using Scriban; -using Volo.Abp.DependencyInjection; - -namespace Volo.Abp.Emailing.Templates -{ - public class TemplateRender : ITemplateRender, ITransientDependency - { - public async Task RenderAsync(string template, object model = null) - { - var scribanTemplate = Template.Parse(template); - return await scribanTemplate.RenderAsync(model); - } - } -} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/VirtualFiles/EmailTemplateDefinitionExtensions.cs b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/VirtualFiles/EmailTemplateDefinitionExtensions.cs deleted file mode 100644 index 7bee611d28..0000000000 --- a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/VirtualFiles/EmailTemplateDefinitionExtensions.cs +++ /dev/null @@ -1,19 +0,0 @@ -namespace Volo.Abp.Emailing.Templates.VirtualFiles -{ - public static class EmailTemplateDefinitionExtensions - { - public static EmailTemplateDefinition AddTemplateVirtualFile( - this EmailTemplateDefinition emailTemplateDefinition, string path) - { - emailTemplateDefinition.Contributors.Add(new SingleVirtualFileEmailTemplateContributor(path)); - return emailTemplateDefinition; - } - - public static EmailTemplateDefinition AddTemplateVirtualFiles( - this EmailTemplateDefinition emailTemplateDefinition, string path) - { - emailTemplateDefinition.Contributors.Add(new MultipleVirtualFilesEmailTemplateContributor(path)); - return emailTemplateDefinition; - } - } -} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/VirtualFiles/MultipleVirtualFilesEmailTemplateContributor.cs b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/VirtualFiles/MultipleVirtualFilesEmailTemplateContributor.cs deleted file mode 100644 index 39af512350..0000000000 --- a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/VirtualFiles/MultipleVirtualFilesEmailTemplateContributor.cs +++ /dev/null @@ -1,68 +0,0 @@ -using System; -using System.Collections.Generic; -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.FileProviders; -using Volo.Abp.VirtualFileSystem; - -namespace Volo.Abp.Emailing.Templates.VirtualFiles -{ - public class MultipleVirtualFilesEmailTemplateContributor : IEmailTemplateContributor - { - private readonly string _virtualPath; - - private IVirtualFileProvider _virtualFileProvider; - - private Dictionary _templateDictionary; - - private readonly object _syncObj = new object(); - - public MultipleVirtualFilesEmailTemplateContributor(string virtualPath) - { - _virtualPath = virtualPath; - } - - public void Initialize(EmailTemplateInitializationContext context) - { - _virtualFileProvider = context.ServiceProvider.GetRequiredService(); - } - - public string GetOrNull(string cultureName) - { - return GetTemplateDictionary().GetOrDefault(cultureName); - } - - private Dictionary GetTemplateDictionary() - { - var dictionaries = _templateDictionary; - if (dictionaries != null) - { - return dictionaries; - } - - lock (_syncObj) - { - dictionaries = _templateDictionary; - if (dictionaries != null) - { - return dictionaries; - } - - _templateDictionary = new Dictionary(); - foreach (var file in _virtualFileProvider.GetDirectoryContents(_virtualPath)) - { - if (file.IsDirectory) - { - continue; - } - - // TODO: How to normalize file names? - _templateDictionary.Add(file.Name.RemovePostFix(".tpl"), file.ReadAsString()); - } - - dictionaries = _templateDictionary; - } - - return dictionaries; - } - } -} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/VirtualFiles/SingleVirtualFileEmailTemplateContributor.cs b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/VirtualFiles/SingleVirtualFileEmailTemplateContributor.cs deleted file mode 100644 index d72d18e99a..0000000000 --- a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/VirtualFiles/SingleVirtualFileEmailTemplateContributor.cs +++ /dev/null @@ -1,34 +0,0 @@ -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.FileProviders; -using Volo.Abp.VirtualFileSystem; - -namespace Volo.Abp.Emailing.Templates.VirtualFiles -{ - public class SingleVirtualFileEmailTemplateContributor : IEmailTemplateContributor - { - private readonly string _virtualPath; - - private IVirtualFileProvider _virtualFileProvider; - - public SingleVirtualFileEmailTemplateContributor(string virtualPath) - { - _virtualPath = virtualPath; - } - - public void Initialize(EmailTemplateInitializationContext context) - { - _virtualFileProvider = context.ServiceProvider.GetRequiredService(); - } - - public string GetOrNull(string cultureName) - { - var file = _virtualFileProvider.GetFileInfo(_virtualPath); - if (file == null || !file.Exists || file.IsDirectory) - { - return null; - } - - return file.ReadAsString(); - } - } -} \ No newline at end of file diff --git a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/TemplateLocalizer.cs b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/TemplateLocalizer.cs deleted file mode 100644 index 5c4220c45f..0000000000 --- a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/TemplateLocalizer.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System.Text.RegularExpressions; -using Microsoft.Extensions.Localization; -using Volo.Abp.DependencyInjection; - -namespace Volo.Abp.Localization -{ - public class TemplateLocalizer : ITemplateLocalizer, ITransientDependency - { - public string Localize(IStringLocalizer localizer, string text) - { - return new Regex("\\{\\{#L:.+?\\}\\}") - .Replace( - text, - match => localizer[match.Value.Substring(5, match.Length - 7)] - ); - } - } -} \ No newline at end of file diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateContentProvider.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateContentProvider.cs index 526da6a381..12c8f8f8d8 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateContentProvider.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateContentProvider.cs @@ -9,5 +9,10 @@ namespace Volo.Abp.TextTemplating [NotNull] string templateName, [CanBeNull] string cultureName = null ); + + Task GetContentOrNullAsync( + [NotNull] TemplateDefinition templateDefinition, + [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 index 1334b5b1dd..4049a3861e 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentProvider.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentProvider.cs @@ -15,15 +15,23 @@ namespace Volo.Abp.TextTemplating _templateDefinitionManager = templateDefinitionManager; } - public async Task GetContentOrNullAsync( + public Task GetContentOrNullAsync( [NotNull] string templateName, [CanBeNull] string cultureName = null) { var template = _templateDefinitionManager.Get(templateName); + return GetContentOrNullAsync(template, cultureName); + } + + public async Task GetContentOrNullAsync( + [NotNull] TemplateDefinition templateDefinition, + [CanBeNull] string cultureName = null) + { + Check.NotNull(templateDefinition, nameof(templateDefinition)); - foreach (var contributor in template.Contributors) + foreach (var contributor in templateDefinition.Contributors) { - var templateString = contributor.GetOrNull(cultureName); + var templateString = contributor.GetOrNull(cultureName); //TODO: GetOrNull should be async! if (templateString != null) { return templateString; @@ -31,7 +39,7 @@ namespace Volo.Abp.TextTemplating } throw new AbpException( - $"None of the template contributors could get the content for the template '{templateName}'" + $"None of the template contributors could get the content for the template '{templateDefinition.Name}'" ); } } diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinition.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinition.cs index 548ac87c15..ea4ba03e27 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinition.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinition.cs @@ -15,7 +15,8 @@ namespace Volo.Abp.TextTemplating [CanBeNull] public string Layout { get; set; } - public Type LocalizationResource { get; set; } //TODO: ??? + [CanBeNull] + public Type LocalizationResource { get; set; } public TemplateContributorList Contributors { get; } @@ -24,7 +25,7 @@ namespace Volo.Abp.TextTemplating public TemplateDefinition( [NotNull] string name, - Type localizationResource = null, + [CanBeNull] Type localizationResource = null, bool isLayout = false, string layout = DefaultLayoutPlaceHolder, string defaultCultureName = null) 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 127e7e9872..c3e3f2b70d 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateRenderer.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateRenderer.cs @@ -1,5 +1,7 @@ -using System.Threading.Tasks; +using System.Text.RegularExpressions; +using System.Threading.Tasks; using JetBrains.Annotations; +using Microsoft.Extensions.Localization; using Scriban; using Volo.Abp.DependencyInjection; @@ -8,11 +10,17 @@ namespace Volo.Abp.TextTemplating public class TemplateRenderer : ITemplateRenderer, ITransientDependency { private readonly ITemplateContentProvider _templateContentProvider; + private readonly ITemplateDefinitionManager _templateDefinitionManager; + private readonly IStringLocalizerFactory _stringLocalizerFactory; public TemplateRenderer( - ITemplateContentProvider templateContentProvider) + ITemplateContentProvider templateContentProvider, + ITemplateDefinitionManager templateDefinitionManager, + IStringLocalizerFactory stringLocalizerFactory) { _templateContentProvider = templateContentProvider; + _templateDefinitionManager = templateDefinitionManager; + _stringLocalizerFactory = stringLocalizerFactory; } public virtual async Task RenderAsync( @@ -22,14 +30,43 @@ namespace Volo.Abp.TextTemplating { Check.NotNullOrWhiteSpace(templateName, nameof(templateName)); + var templateDefinition = _templateDefinitionManager.Get(templateName); + var content = await _templateContentProvider.GetContentOrNullAsync( - templateName, + templateDefinition, cultureName ); - var parsedTemplate = Template.Parse(content); + if (templateDefinition.LocalizationResource != null) + { + var localizer = _stringLocalizerFactory.Create(templateDefinition.LocalizationResource); + content = Localize(localizer, content); + } + + var renderedContent = await Template.Parse(content).RenderAsync(model); + + if (templateDefinition.Layout != null) + { + renderedContent = await RenderAsync( + templateDefinition.Layout, + new + { + content = renderedContent + }, + cultureName: cultureName + ); + } - return await parsedTemplate.RenderAsync(model); + return renderedContent; + } + + public string Localize(IStringLocalizer localizer, string text) + { + return new Regex("\\{\\{#L:.+?\\}\\}") + .Replace( + text, + match => localizer[match.Value.Substring(5, match.Length - 7)] + ); } } } \ No newline at end of file diff --git a/framework/test/Volo.Abp.Emailing.Tests/Volo.Abp.Emailing.Tests.csproj b/framework/test/Volo.Abp.Emailing.Tests/Volo.Abp.Emailing.Tests.csproj index a86ea9f051..030eddb65a 100644 --- a/framework/test/Volo.Abp.Emailing.Tests/Volo.Abp.Emailing.Tests.csproj +++ b/framework/test/Volo.Abp.Emailing.Tests/Volo.Abp.Emailing.Tests.csproj @@ -7,13 +7,6 @@ - - - - - - - diff --git a/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/AbpEmailingTestModule.cs b/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/AbpEmailingTestModule.cs index e4cdfe0556..7f1175bcbb 100644 --- a/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/AbpEmailingTestModule.cs +++ b/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/AbpEmailingTestModule.cs @@ -1,6 +1,4 @@ using Volo.Abp.Autofac; -using Volo.Abp.Emailing.Localization; -using Volo.Abp.Localization; using Volo.Abp.Modularity; using Volo.Abp.VirtualFileSystem; @@ -18,14 +16,6 @@ namespace Volo.Abp.Emailing { options.FileSets.AddEmbedded(); }); - - Configure(options => - { - options.Resources - .Add() - .AddVirtualJson("/Volo/Abp/Emailing/Localization"); - }); - } } } \ No newline at end of file diff --git a/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/EmailTemplateRender_Tests.cs b/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/EmailTemplateRender_Tests.cs deleted file mode 100644 index 24d7298f6c..0000000000 --- a/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/EmailTemplateRender_Tests.cs +++ /dev/null @@ -1,65 +0,0 @@ -using System.Collections.Generic; -using System.Threading.Tasks; -using Shouldly; -using Volo.Abp.Emailing.Templates; -using Volo.Abp.Testing; -using Xunit; - -namespace Volo.Abp.Emailing -{ - public class EmailTemplateRender_Tests : AbpIntegratedTest - { - protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options) - { - options.UseAutofac(); - } - - private readonly ITemplateRender _templateRender; - - public EmailTemplateRender_Tests() - { - _templateRender = GetRequiredService(); - } - - [Fact] - public async Task RenderAsync() - { - var template = "Hello {{email}} {{ for order in orders }}{{ order.id }}:{{ order.name }},{{ end }}"; - - var model = new ModelClass - { - Email = "john@abp.io", - Orders = new List - { - new ModelClass.Order - { - Id = "1", - Name = "iphone" - }, - new ModelClass.Order - { - Id = "2", - Name = "ipad" - } - } - }; - - var result = await _templateRender.RenderAsync(template, model); - result.ShouldBe("Hello john@abp.io 1:iphone,2:ipad,"); - } - - public class ModelClass - { - public string Email { get; set; } - - public List Orders { get; set; } - - public class Order - { - public string Id { get; set; } - - public string Name { get; set; } - } - } - } -} \ No newline at end of file diff --git a/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/EmailTemplateStore_Tests.cs b/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/EmailTemplateStore_Tests.cs deleted file mode 100644 index 1e4ea8c090..0000000000 --- a/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/EmailTemplateStore_Tests.cs +++ /dev/null @@ -1,54 +0,0 @@ -using System; -using System.Threading.Tasks; -using Shouldly; -using Volo.Abp.Emailing.Templates; -using Volo.Abp.Testing; -using Xunit; - -namespace Volo.Abp.Emailing -{ - public class EmailTemplateStore_Tests : AbpIntegratedTest - { - protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options) - { - options.UseAutofac(); - } - - private readonly IEmailTemplateProvider _emailTemplateProvider; - - public EmailTemplateStore_Tests() - { - _emailTemplateProvider = GetRequiredService(); - } - - [Fact] - public async Task Should_Get_Registered_Template() - { - var template = await _emailTemplateProvider.GetAsync("template1", "tr"); - template.Content.ShouldContain("Lütfen aÅŸağıdaki baÄŸlantıya tıklayarak e-posta adresinizi onaylayın."); - } - - [Fact] - public async Task Should_Get_Default_Culture_Template() - { - var template = await _emailTemplateProvider.GetAsync("template1", "zh-Hans"); - template.Content.ShouldContain("Please confirm your email address by clicking the link below."); - } - - [Fact] - public async Task Should_Get_Registered_Template_With_Layout() - { - var template = await _emailTemplateProvider.GetAsync("template2", "en"); - - template.Content.ShouldContain($"{Environment.NewLine} " + "Please confirm your email address by clicking the link below."); - } - - - [Fact] - public async Task Should_Get_Registered_Template_With_Localize() - { - var template = await _emailTemplateProvider.GetAsync("template3", "tr"); - template.Content.ShouldContain("Merhaba Abp"); - } - } -} diff --git a/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/Localization/AbpEmailingTestResource.cs b/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/Localization/AbpEmailingTestResource.cs deleted file mode 100644 index bdc75f9f2f..0000000000 --- a/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/Localization/AbpEmailingTestResource.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Text; - -namespace Volo.Abp.Emailing.Localization -{ - public class AbpEmailingTestResource - { - } -} diff --git a/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/Localization/cs.json b/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/Localization/cs.json deleted file mode 100644 index 5f6e35488e..0000000000 --- a/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/Localization/cs.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "culture": "cs", - "texts": { - "hello": "ahoj" - } -} \ No newline at end of file diff --git a/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/Localization/en.json b/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/Localization/en.json deleted file mode 100644 index 38f7cf7e5b..0000000000 --- a/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/Localization/en.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "culture": "en", - "texts": { - "hello": "hello" - } -} \ No newline at end of file diff --git a/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/Localization/pl.json b/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/Localization/pl.json deleted file mode 100644 index 6dd6654aa1..0000000000 --- a/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/Localization/pl.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "culture": "pl", - "texts": { - "hello": "witaj" - } -} \ No newline at end of file diff --git a/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/Localization/pt-BR.json b/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/Localization/pt-BR.json deleted file mode 100644 index 0e33dee138..0000000000 --- a/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/Localization/pt-BR.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "culture": "pt-BR", - "texts": { - "hello": "Olá" - } -} \ No newline at end of file diff --git a/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/Localization/tr.json b/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/Localization/tr.json deleted file mode 100644 index 6c3c94cfdf..0000000000 --- a/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/Localization/tr.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "culture": "tr", - "texts": { - "hello": "Merhaba" - } -} \ No newline at end of file diff --git a/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/Localization/vi.json b/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/Localization/vi.json deleted file mode 100644 index 8261599d78..0000000000 --- a/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/Localization/vi.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "culture": "vi", - "texts": { - "hello": "xin chào" - } -} diff --git a/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/Localization/zh-Hant.json b/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/Localization/zh-Hant.json deleted file mode 100644 index dd12964f70..0000000000 --- a/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/Localization/zh-Hant.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "culture": "zh-Hant", - "texts": { - "hello": "哈囉" - } -} \ No newline at end of file diff --git a/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/TestEmailTemplateProvider.cs b/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/TestEmailTemplateProvider.cs deleted file mode 100644 index 60c9a2ccf3..0000000000 --- a/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/TestEmailTemplateProvider.cs +++ /dev/null @@ -1,24 +0,0 @@ -using Volo.Abp.Emailing.Localization; -using Volo.Abp.Emailing.Templates; -using Volo.Abp.Emailing.Templates.VirtualFiles; - -namespace Volo.Abp.Emailing -{ - public class TestEmailTemplateProvider : EmailTemplateDefinitionProvider - { - public override void Define(IEmailTemplateDefinitionContext context) - { - var template1 = new EmailTemplateDefinition("template1", defaultCultureName: "en", layout: null) - .AddTemplateVirtualFiles("/Volo/Abp/Emailing/TestTemplates/Template1"); - context.Add(template1); - - var template2 = new EmailTemplateDefinition("template2", layout: StandardEmailTemplates.DefaultLayout) - .AddTemplateVirtualFiles("/Volo/Abp/Emailing/TestTemplates/Template2"); - context.Add(template2); - - var template3 = new EmailTemplateDefinition("template3", layout: null, singleTemplateFile: true, localizationResource: typeof(AbpEmailingTestResource)) - .AddTemplateVirtualFile("/Volo/Abp/Emailing/TestTemplates/Template3/Template.tpl"); - context.Add(template3); - } - } -} \ No newline at end of file diff --git a/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/TestTemplates/Template1/en.tpl b/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/TestTemplates/Template1/en.tpl deleted file mode 100644 index 49a951e8c0..0000000000 --- a/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/TestTemplates/Template1/en.tpl +++ /dev/null @@ -1,4 +0,0 @@ -Please confirm your email address by clicking the link below. -We may need to send you critical information about our service and it is important that we have an accurate email address. - -Confirm email address \ No newline at end of file diff --git a/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/TestTemplates/Template1/tr.tpl b/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/TestTemplates/Template1/tr.tpl deleted file mode 100644 index 3e572aedbb..0000000000 --- a/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/TestTemplates/Template1/tr.tpl +++ /dev/null @@ -1,4 +0,0 @@ -Lütfen aÅŸağıdaki baÄŸlantıya tıklayarak e-posta adresinizi onaylayın. -Size hizmetimizle ilgili kritik bilgileri göndermemiz gerekebilir ve doÄŸru bir e-posta adresimizin olması önemlidir. - -E-posta adresini onayla \ No newline at end of file diff --git a/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/TestTemplates/Template2/en.tpl b/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/TestTemplates/Template2/en.tpl deleted file mode 100644 index 49a951e8c0..0000000000 --- a/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/TestTemplates/Template2/en.tpl +++ /dev/null @@ -1,4 +0,0 @@ -Please confirm your email address by clicking the link below. -We may need to send you critical information about our service and it is important that we have an accurate email address. - -Confirm email address \ No newline at end of file diff --git a/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/TestTemplates/Template3/Template.tpl b/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/TestTemplates/Template3/Template.tpl deleted file mode 100644 index f30f512848..0000000000 --- a/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/TestTemplates/Template3/Template.tpl +++ /dev/null @@ -1 +0,0 @@ -{{#L:hello}} Abp \ No newline at end of file diff --git a/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TemplateLocalizer_Tests.cs b/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TemplateLocalizer_Tests.cs deleted file mode 100644 index 4b31554637..0000000000 --- a/framework/test/Volo.Abp.Localization.Tests/Volo/Abp/Localization/TemplateLocalizer_Tests.cs +++ /dev/null @@ -1,63 +0,0 @@ -using Microsoft.Extensions.DependencyInjection; -using Microsoft.Extensions.Localization; -using Shouldly; -using Volo.Abp.Localization.TestResources.Source; -using Volo.Abp.Modularity; -using Volo.Abp.Testing; -using Volo.Abp.VirtualFileSystem; -using Xunit; - -namespace Volo.Abp.Localization -{ - public class TemplateLocalizer_Tests : AbpIntegratedTest - { - private readonly ITemplateLocalizer _templateLocalizer; - private readonly IStringLocalizer _testResource; - - public TemplateLocalizer_Tests() - { - _testResource = GetRequiredService>(); - _templateLocalizer = GetRequiredService(); - } - - [Fact] - public void Should_Localize() - { - using (CultureHelper.Use("en")) - { - _templateLocalizer.Localize(_testResource, "

{{#L:CarPlural}} {{#L:Universe}}

") - .ShouldBe("

Cars Universe

"); - } - } - - [Fact] - public void Should_Work_Even_If_No_Text_To_Localize() - { - using (CultureHelper.Use("en")) - { - _templateLocalizer.Localize(_testResource, "

test

") - .ShouldBe("

test

"); - } - } - - [DependsOn(typeof(AbpTestBaseModule))] - [DependsOn(typeof(AbpLocalizationModule))] - public class TestModule : AbpModule - { - public override void ConfigureServices(ServiceConfigurationContext context) - { - Configure(options => - { - options.FileSets.AddEmbedded(); - }); - - Configure(options => - { - options.Resources - .Add("en") - .AddVirtualJson("/Volo/Abp/Localization/TestResources/Source"); - }); - } - } - } -} From 0311092ae1b43212ddee6c0c82ed2eafc6c013c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Thu, 23 Apr 2020 23:03:37 +0300 Subject: [PATCH 11/35] Refactored text templating and added more tests. --- .../Volo/Abp/Localization/CultureHelper.cs | 7 +- .../Abp/TextTemplating/TemplateDefinition.cs | 4 +- .../Abp/TextTemplating/TemplateRenderer.cs | 120 ++++++++++++++---- .../Volo.Abp.TextTemplating.Tests.csproj | 3 + .../AbpTextTemplatingTestModule.cs | 12 +- .../Localization/TestLocalizationSource.cs | 6 + .../Abp/TextTemplating/Localization/en.json | 6 + .../Abp/TextTemplating/Localization/tr.json | 6 + .../SampleTemplates/ForgotPasswordEmail.tpl | 2 +- .../SampleTemplates/TestTemplateLayout1.tpl | 1 + .../SampleTemplates/WelcomeEmail/en.tpl | 2 +- .../SampleTemplates/WelcomeEmail/tr.tpl | 2 +- .../TextTemplating/TemplateRenderer_Tests.cs | 24 ++-- .../TestTemplateDefinitionProvider.cs | 17 ++- .../VirtualFileTemplateContributor_Tests.cs | 6 +- 15 files changed, 168 insertions(+), 50 deletions(-) create mode 100644 framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/Localization/TestLocalizationSource.cs create mode 100644 framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/Localization/en.json create mode 100644 framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/Localization/tr.json create mode 100644 framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/SampleTemplates/TestTemplateLayout1.tpl diff --git a/framework/src/Volo.Abp.Core/Volo/Abp/Localization/CultureHelper.cs b/framework/src/Volo.Abp.Core/Volo/Abp/Localization/CultureHelper.cs index 8f663e084e..d4d9cfb1c0 100644 --- a/framework/src/Volo.Abp.Core/Volo/Abp/Localization/CultureHelper.cs +++ b/framework/src/Volo.Abp.Core/Volo/Abp/Localization/CultureHelper.cs @@ -10,7 +10,12 @@ namespace Volo.Abp.Localization { Check.NotNull(culture, nameof(culture)); - return Use(new CultureInfo(culture), uiCulture == null ? null : new CultureInfo(uiCulture)); + return Use( + new CultureInfo(culture), + uiCulture == null + ? null + : new CultureInfo(uiCulture) + ); } public static IDisposable Use([NotNull] CultureInfo culture, CultureInfo uiCulture = null) diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinition.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinition.cs index ea4ba03e27..8e113829ea 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinition.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinition.cs @@ -5,8 +5,6 @@ namespace Volo.Abp.TextTemplating { public class TemplateDefinition { - public const string DefaultLayoutPlaceHolder = "_"; - [NotNull] public string Name { get; } @@ -27,7 +25,7 @@ namespace Volo.Abp.TextTemplating [NotNull] string name, [CanBeNull] Type localizationResource = null, bool isLayout = false, - string layout = DefaultLayoutPlaceHolder, + string layout = null, string defaultCultureName = null) { Name = Check.NotNullOrWhiteSpace(name, nameof(name)); 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 c3e3f2b70d..4ff2beb9ba 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateRenderer.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateRenderer.cs @@ -1,9 +1,13 @@ -using System.Text.RegularExpressions; +using System; +using System.Collections.Generic; +using System.Globalization; using System.Threading.Tasks; using JetBrains.Annotations; using Microsoft.Extensions.Localization; using Scriban; +using Scriban.Runtime; using Volo.Abp.DependencyInjection; +using Volo.Abp.Localization; namespace Volo.Abp.TextTemplating { @@ -14,8 +18,8 @@ namespace Volo.Abp.TextTemplating private readonly IStringLocalizerFactory _stringLocalizerFactory; public TemplateRenderer( - ITemplateContentProvider templateContentProvider, - ITemplateDefinitionManager templateDefinitionManager, + ITemplateContentProvider templateContentProvider, + ITemplateDefinitionManager templateDefinitionManager, IStringLocalizerFactory stringLocalizerFactory) { _templateContentProvider = templateContentProvider; @@ -30,43 +34,111 @@ namespace Volo.Abp.TextTemplating { Check.NotNullOrWhiteSpace(templateName, nameof(templateName)); - var templateDefinition = _templateDefinitionManager.Get(templateName); - - var content = await _templateContentProvider.GetContentOrNullAsync( - templateDefinition, - cultureName - ); + if (cultureName == null) + { + cultureName = CultureInfo.CurrentUICulture.Name; + } - if (templateDefinition.LocalizationResource != null) + using (CultureHelper.Use(cultureName)) { - var localizer = _stringLocalizerFactory.Create(templateDefinition.LocalizationResource); - content = Localize(localizer, content); + return await RenderInternalAsync( + templateName, + new Dictionary(), + model + ); } + } - var renderedContent = await Template.Parse(content).RenderAsync(model); + private async Task RenderInternalAsync( + string templateName, + Dictionary globalContext, + object model = null) + { + var templateDefinition = _templateDefinitionManager.Get(templateName); + + var renderedContent = await RenderSingleTemplateAsync( + templateDefinition, + globalContext, + model + ); if (templateDefinition.Layout != null) { - renderedContent = await RenderAsync( + globalContext["content"] = renderedContent; + renderedContent = await RenderInternalAsync( templateDefinition.Layout, - new - { - content = renderedContent - }, - cultureName: cultureName + globalContext ); } return renderedContent; } - public string Localize(IStringLocalizer localizer, string text) + private async Task RenderSingleTemplateAsync( + TemplateDefinition templateDefinition, + Dictionary globalContext, + object model = null) + { + var rawTemplateContent = await _templateContentProvider + .GetContentOrNullAsync( + templateDefinition + ); + + return await RenderTemplateContentWithScribanAsync( + templateDefinition, + rawTemplateContent, + globalContext, + model + ); + } + + protected virtual async Task RenderTemplateContentWithScribanAsync( + TemplateDefinition templateDefinition, + string templateContent, + Dictionary globalContext, + object model = null) + { + var context = CreateScribanTemplateContext( + templateDefinition, + globalContext, + model + ); + + return await Template + .Parse(templateContent) + .RenderAsync(context); + } + + protected virtual TemplateContext CreateScribanTemplateContext( + TemplateDefinition templateDefinition, + Dictionary globalContext, + object model = null) { - return new Regex("\\{\\{#L:.+?\\}\\}") - .Replace( - text, - match => localizer[match.Value.Substring(5, match.Length - 7)] + var context = new TemplateContext(); + + var scriptObject = new ScriptObject(); + + scriptObject.Import(globalContext); + + if (model != null) + { + scriptObject["model"] = model; + } + + if (templateDefinition.LocalizationResource != null) + { + var localizer = _stringLocalizerFactory.Create(templateDefinition.LocalizationResource); + scriptObject.Import( + "l", + new Func( + name => localizer[name] + ) ); + } + + context.PushGlobal(scriptObject); + + return context; } } } \ No newline at end of file diff --git a/framework/test/Volo.Abp.TextTemplating.Tests/Volo.Abp.TextTemplating.Tests.csproj b/framework/test/Volo.Abp.TextTemplating.Tests/Volo.Abp.TextTemplating.Tests.csproj index 916495b116..0d230552e8 100644 --- a/framework/test/Volo.Abp.TextTemplating.Tests/Volo.Abp.TextTemplating.Tests.csproj +++ b/framework/test/Volo.Abp.TextTemplating.Tests/Volo.Abp.TextTemplating.Tests.csproj @@ -8,11 +8,14 @@ + + + diff --git a/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/AbpTextTemplatingTestModule.cs b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/AbpTextTemplatingTestModule.cs index 0457e0136d..8e8b69e116 100644 --- a/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/AbpTextTemplatingTestModule.cs +++ b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/AbpTextTemplatingTestModule.cs @@ -1,5 +1,7 @@ using Volo.Abp.Autofac; +using Volo.Abp.Localization; using Volo.Abp.Modularity; +using Volo.Abp.TextTemplating.Localization; using Volo.Abp.VirtualFileSystem; namespace Volo.Abp.TextTemplating @@ -7,7 +9,8 @@ namespace Volo.Abp.TextTemplating [DependsOn( typeof(AbpTextTemplatingModule), typeof(AbpTestBaseModule), - typeof(AbpAutofacModule) + typeof(AbpAutofacModule), + typeof(AbpLocalizationModule) )] public class AbpTextTemplatingTestModule : AbpModule { @@ -17,6 +20,13 @@ namespace Volo.Abp.TextTemplating { options.FileSets.AddEmbedded("Volo.Abp.TextTemplating"); }); + + Configure(options => + { + options.Resources + .Add("en") + .AddVirtualJson("/Localization"); + }); } } } diff --git a/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/Localization/TestLocalizationSource.cs b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/Localization/TestLocalizationSource.cs new file mode 100644 index 0000000000..a4e53e3861 --- /dev/null +++ b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/Localization/TestLocalizationSource.cs @@ -0,0 +1,6 @@ +namespace Volo.Abp.TextTemplating.Localization +{ + public class TestLocalizationSource + { + } +} 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 new file mode 100644 index 0000000000..a0dff7e930 --- /dev/null +++ b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/Localization/en.json @@ -0,0 +1,6 @@ +{ + "culture": "en", + "texts": { + "HelloText": "Hello" + } +} \ No newline at end of file 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 new file mode 100644 index 0000000000..d09f02cd8f --- /dev/null +++ b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/Localization/tr.json @@ -0,0 +1,6 @@ +{ + "culture": "tr", + "texts": { + "HelloText": "Merhaba" + } +} \ No newline at end of file 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 674b734c8a..7d844c6f7c 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 @@ -Please click to the following link to get an email to reset your password! \ No newline at end of file +{{l "HelloText"}}. 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/SampleTemplates/TestTemplateLayout1.tpl b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/SampleTemplates/TestTemplateLayout1.tpl new file mode 100644 index 0000000000..a780e210b0 --- /dev/null +++ b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/SampleTemplates/TestTemplateLayout1.tpl @@ -0,0 +1 @@ +*BEGIN*{{content}}*END* \ No newline at end of file diff --git a/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/SampleTemplates/WelcomeEmail/en.tpl b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/SampleTemplates/WelcomeEmail/en.tpl index 1088362628..1746eed52b 100644 --- a/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/SampleTemplates/WelcomeEmail/en.tpl +++ b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/SampleTemplates/WelcomeEmail/en.tpl @@ -1 +1 @@ -Welcome {{name}} to the abp.io! \ No newline at end of file +Welcome {{model.name}} to the abp.io! \ No newline at end of file diff --git a/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/SampleTemplates/WelcomeEmail/tr.tpl b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/SampleTemplates/WelcomeEmail/tr.tpl index b457611f1e..581016bc4d 100644 --- a/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/SampleTemplates/WelcomeEmail/tr.tpl +++ b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/SampleTemplates/WelcomeEmail/tr.tpl @@ -1 +1 @@ -Merhaba {{name}}, abp.io'ya hoşgeldiniz! \ No newline at end of file +Merhaba {{model.name}}, abp.io'ya hoşgeldiniz! \ 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 9e76d22ab8..14b3df3486 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 @@ -14,16 +14,6 @@ namespace Volo.Abp.TextTemplating _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!"); - } - [Fact] public async Task Should_Get_Rendered_Localized_Template_Content_With_Different_Cultures() { @@ -86,6 +76,20 @@ namespace Volo.Abp.TextTemplating )).ShouldBe("Welcome John to the abp.io!"); } + [Fact] + public async Task Should_Get_Rendered_Inline_Localized_Template() + { + (await _templateRenderer.RenderAsync( + TestTemplates.ForgotPasswordEmail, + cultureName: "en" + )).ShouldBe("*BEGIN*Hello. Please click to the following link to get an email to reset your password!*END*"); + + (await _templateRenderer.RenderAsync( + TestTemplates.ForgotPasswordEmail, + cultureName: "tr" + )).ShouldBe("*BEGIN*Merhaba. Please click to the following link to get an email to reset your password!*END*"); + } + private class WelcomeEmailModel { public string Name { get; set; } 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 7a1ff4121b..8fe7c98e38 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 @@ -1,4 +1,6 @@ -namespace Volo.Abp.TextTemplating +using Volo.Abp.TextTemplating.Localization; + +namespace Volo.Abp.TextTemplating { public class TestTemplateDefinitionProvider : TemplateDefinitionProvider { @@ -13,13 +15,18 @@ context.Add( new TemplateDefinition( - TestTemplates.ForgotPasswordEmail + TestTemplates.ForgotPasswordEmail, + localizationResource: typeof(TestLocalizationSource), + layout: TestTemplates.TestTemplateLayout1 ).AddVirtualFiles("/SampleTemplates/ForgotPasswordEmail.tpl") ); - context.Add(new TemplateDefinition( - TestTemplates.TestTemplateLayout1 - )); + context.Add( + new TemplateDefinition( + TestTemplates.TestTemplateLayout1, + isLayout: true + ).AddVirtualFiles("/SampleTemplates/TestTemplateLayout1.tpl") + ); } } } diff --git a/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContributor_Tests.cs b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContributor_Tests.cs index 1c636d7813..2c104b632d 100644 --- a/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContributor_Tests.cs +++ b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContributor_Tests.cs @@ -21,11 +21,11 @@ namespace Volo.Abp.TextTemplating.VirtualFiles contributor .GetOrNull("en") - .ShouldBe("Welcome {{name}} to the abp.io!"); + .ShouldBe("Welcome {{model.name}} to the abp.io!"); contributor .GetOrNull("tr") - .ShouldBe("Merhaba {{name}}, abp.io'ya hoşgeldiniz!"); + .ShouldBe("Merhaba {{model.name}}, abp.io'ya hoşgeldiniz!"); } [Fact] @@ -44,7 +44,7 @@ namespace Volo.Abp.TextTemplating.VirtualFiles contributor .GetOrNull() - .ShouldBe("Please click to the following link to get an email to reset your password!"); + .ShouldBe("{{l \"HelloText\"}}. Please click to the following link to get an email to reset your password!"); } } } From 7bd91c1d01e49bfd7850c6a10fbc15771fcd0fff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Thu, 23 Apr 2020 23:07:32 +0300 Subject: [PATCH 12/35] Get a globalContext from the TemplateRenderer --- .../Volo/Abp/TextTemplating/ITemplateRenderer.cs | 14 ++++++++++++-- .../Volo/Abp/TextTemplating/TemplateRenderer.cs | 5 +++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateRenderer.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateRenderer.cs index 92a1c0782c..b153a5130b 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateRenderer.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateRenderer.cs @@ -1,4 +1,5 @@ -using System.Linq; +using System.Collections.Generic; +using System.Globalization; using System.Threading.Tasks; using JetBrains.Annotations; @@ -6,10 +7,19 @@ namespace Volo.Abp.TextTemplating { public interface ITemplateRenderer { + /// + /// Renders a text template. + /// + /// The template name + /// An optional model object that is used in the template + /// Culture name. Uses the if not specified + /// A dictionary which can be used to import global objects to the template + /// Task RenderAsync( [NotNull] string templateName, [CanBeNull] object model = null, - [CanBeNull] string cultureName = null + [CanBeNull] string cultureName = null, + [CanBeNull] Dictionary globalContext = 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 index 4ff2beb9ba..2824c6e463 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateRenderer.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateRenderer.cs @@ -30,7 +30,8 @@ namespace Volo.Abp.TextTemplating public virtual async Task RenderAsync( [NotNull] string templateName, [CanBeNull] object model = null, - [CanBeNull] string cultureName = null) + [CanBeNull] string cultureName = null, + [CanBeNull] Dictionary globalContext = null) { Check.NotNullOrWhiteSpace(templateName, nameof(templateName)); @@ -43,7 +44,7 @@ namespace Volo.Abp.TextTemplating { return await RenderInternalAsync( templateName, - new Dictionary(), + globalContext ?? new Dictionary(), model ); } From 693e4ad5bf0e814622d6de058ded7bde4b450ff8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Thu, 23 Apr 2020 23:09:25 +0300 Subject: [PATCH 13/35] Update TemplateRenderer.cs --- .../Volo/Abp/TextTemplating/TemplateRenderer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 2824c6e463..558104e3a4 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateRenderer.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateRenderer.cs @@ -50,7 +50,7 @@ namespace Volo.Abp.TextTemplating } } - private async Task RenderInternalAsync( + protected virtual async Task RenderInternalAsync( string templateName, Dictionary globalContext, object model = null) @@ -75,7 +75,7 @@ namespace Volo.Abp.TextTemplating return renderedContent; } - private async Task RenderSingleTemplateAsync( + protected virtual async Task RenderSingleTemplateAsync( TemplateDefinition templateDefinition, Dictionary globalContext, object model = null) From f51c67f11a8427d8152302e0c57710023a6e1260 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Thu, 23 Apr 2020 23:23:10 +0300 Subject: [PATCH 14/35] Re-Organize standard email templates and renamed AddVirtualFiles to WithVirtualFilePath --- .../src/Volo.Abp.Emailing/Volo.Abp.Emailing.csproj | 8 ++++---- .../Templates/DefaultEmailTemplateProvider.cs | 14 +++++++------- .../{DefaultEmailTemplates => }/Layout/en.tpl | 0 .../{DefaultEmailTemplates => }/Message/en.tpl | 0 .../Emailing/Templates/StandardEmailTemplates.cs | 4 ++-- .../Volo/Abp/TextTemplating/TemplateDefinition.cs | 2 +- .../TextTemplating/TemplateDefinitionExtensions.cs | 10 ++++++++-- .../TestTemplateDefinitionProvider.cs | 6 +++--- 8 files changed, 25 insertions(+), 19 deletions(-) rename framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/{DefaultEmailTemplates => }/Layout/en.tpl (100%) rename framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/{DefaultEmailTemplates => }/Message/en.tpl (100%) diff --git a/framework/src/Volo.Abp.Emailing/Volo.Abp.Emailing.csproj b/framework/src/Volo.Abp.Emailing/Volo.Abp.Emailing.csproj index 783d840cf0..a2f83399a0 100644 --- a/framework/src/Volo.Abp.Emailing/Volo.Abp.Emailing.csproj +++ b/framework/src/Volo.Abp.Emailing/Volo.Abp.Emailing.csproj @@ -15,13 +15,13 @@ - - + + - - + + diff --git a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/DefaultEmailTemplateProvider.cs b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/DefaultEmailTemplateProvider.cs index 28d1ac94c1..385e0ef178 100644 --- a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/DefaultEmailTemplateProvider.cs +++ b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/DefaultEmailTemplateProvider.cs @@ -8,18 +8,18 @@ namespace Volo.Abp.Emailing.Templates { context.Add( new TemplateDefinition( - StandardEmailTemplates.DefaultLayout, + StandardEmailTemplates.Layout, defaultCultureName: "en", - isLayout: true, - layout: null - ).AddVirtualFiles("/Volo/Abp/Emailing/Templates/DefaultEmailTemplates/Layout") + isLayout: true + ).WithVirtualFilePath("/Volo/Abp/Emailing/Templates/Layout") ); context.Add( new TemplateDefinition( - StandardEmailTemplates.SimpleMessage, - defaultCultureName: "en" - ).AddVirtualFiles("/Volo/Abp/Emailing/Templates/DefaultEmailTemplates/Message") + StandardEmailTemplates.Message, + defaultCultureName: "en", + layout: StandardEmailTemplates.Layout + ).WithVirtualFilePath("/Volo/Abp/Emailing/Templates/Message") ); } } diff --git a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/DefaultEmailTemplates/Layout/en.tpl b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/Layout/en.tpl similarity index 100% rename from framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/DefaultEmailTemplates/Layout/en.tpl rename to framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/Layout/en.tpl diff --git a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/DefaultEmailTemplates/Message/en.tpl b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/Message/en.tpl similarity index 100% rename from framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/DefaultEmailTemplates/Message/en.tpl rename to framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/Message/en.tpl diff --git a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/StandardEmailTemplates.cs b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/StandardEmailTemplates.cs index 7e8cbedc68..6a60219a5e 100644 --- a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/StandardEmailTemplates.cs +++ b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/StandardEmailTemplates.cs @@ -2,7 +2,7 @@ { public static class StandardEmailTemplates { - public const string DefaultLayout = "Abp.DefaultLayout"; - public const string SimpleMessage = "Abp.SimpleMessage"; + public const string Layout = "Abp.StandardEmailTemplates.Layout"; + public const string Message = "Abp.StandardEmailTemplates.Message"; } } diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinition.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinition.cs index 8e113829ea..09de7bf458 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinition.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinition.cs @@ -36,7 +36,7 @@ namespace Volo.Abp.TextTemplating DefaultCultureName = defaultCultureName; } - public virtual TemplateDefinition AddContributor(ITemplateContributor contributor) + public virtual TemplateDefinition WithContributor(ITemplateContributor contributor) { Contributors.Add(contributor); return this; diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionExtensions.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionExtensions.cs index 6508295da7..9bd932c947 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionExtensions.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionExtensions.cs @@ -5,13 +5,19 @@ namespace Volo.Abp.TextTemplating { public static class TemplateDefinitionExtensions { - public static TemplateDefinition AddVirtualFiles( + /// + /// + /// + /// + /// + /// + public static TemplateDefinition WithVirtualFilePath( [NotNull] this TemplateDefinition templateDefinition, [NotNull] string virtualPath) { Check.NotNull(templateDefinition, nameof(templateDefinition)); - return templateDefinition.AddContributor( + return templateDefinition.WithContributor( new VirtualFileTemplateContributor(virtualPath) ); } 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 8fe7c98e38..05df1378b2 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 @@ -10,7 +10,7 @@ namespace Volo.Abp.TextTemplating new TemplateDefinition( TestTemplates.WelcomeEmail, defaultCultureName: "en" - ).AddVirtualFiles("/SampleTemplates/WelcomeEmail") + ).WithVirtualFilePath("/SampleTemplates/WelcomeEmail") ); context.Add( @@ -18,14 +18,14 @@ namespace Volo.Abp.TextTemplating TestTemplates.ForgotPasswordEmail, localizationResource: typeof(TestLocalizationSource), layout: TestTemplates.TestTemplateLayout1 - ).AddVirtualFiles("/SampleTemplates/ForgotPasswordEmail.tpl") + ).WithVirtualFilePath("/SampleTemplates/ForgotPasswordEmail.tpl") ); context.Add( new TemplateDefinition( TestTemplates.TestTemplateLayout1, isLayout: true - ).AddVirtualFiles("/SampleTemplates/TestTemplateLayout1.tpl") + ).WithVirtualFilePath("/SampleTemplates/TestTemplateLayout1.tpl") ); } } From 60e4a8e8c33388f67d555d779e932a648bc85acf Mon Sep 17 00:00:00 2001 From: Ahmet Date: Thu, 23 Apr 2020 23:48:29 +0300 Subject: [PATCH 15/35] ITemplateContributor GetOrNull converted to Async --- .../TextTemplating/ITemplateContributor.cs | 5 +++-- .../TextTemplating/TemplateContentProvider.cs | 2 +- .../VirtualFileTemplateContributor.cs | 3 ++- .../VirtualFileTemplateContributor_Tests.cs | 22 +++++++++---------- 4 files changed, 16 insertions(+), 16 deletions(-) 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 e8e1f97769..2174a65bcd 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateContributor.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateContributor.cs @@ -1,4 +1,5 @@ -using JetBrains.Annotations; +using System.Threading.Tasks; +using JetBrains.Annotations; namespace Volo.Abp.TextTemplating { @@ -6,6 +7,6 @@ namespace Volo.Abp.TextTemplating { void Initialize(TemplateContributorInitializationContext context); - string GetOrNull([CanBeNull] string cultureName); + Task GetOrNullAsync([CanBeNull] string cultureName); } } \ 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 index 4049a3861e..b983c75f11 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentProvider.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentProvider.cs @@ -31,7 +31,7 @@ namespace Volo.Abp.TextTemplating foreach (var contributor in templateDefinition.Contributors) { - var templateString = contributor.GetOrNull(cultureName); //TODO: GetOrNull should be async! + var templateString = await contributor.GetOrNullAsync(cultureName); if (templateString != null) { return templateString; diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContributor.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContributor.cs index f1a4700da7..ae4b8c92f0 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContributor.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContributor.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Globalization; +using System.Threading.Tasks; using JetBrains.Annotations; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.FileProviders; @@ -30,7 +31,7 @@ namespace Volo.Abp.TextTemplating.VirtualFiles TemplateDefinition = context.TemplateDefinition; } - public string GetOrNull([CanBeNull] string cultureName = null) + public async Task GetOrNullAsync([CanBeNull] string cultureName = null) { //TODO: Refactor: Split implementation based on single file or dictionary of culture-specific contents diff --git a/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContributor_Tests.cs b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContributor_Tests.cs index 2c104b632d..1ff2596342 100644 --- a/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContributor_Tests.cs +++ b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContributor_Tests.cs @@ -1,4 +1,5 @@ -using Shouldly; +using System.Threading.Tasks; +using Shouldly; using Xunit; namespace Volo.Abp.TextTemplating.VirtualFiles @@ -6,7 +7,7 @@ namespace Volo.Abp.TextTemplating.VirtualFiles public class VirtualFileTemplateContributor_Tests : AbpTextTemplatingTestBase { [Fact] - public void Should_Get_Localized_Content_By_Culture() + public async Task Should_Get_Localized_Content_By_Culture() { var contributor = new VirtualFileTemplateContributor( "/SampleTemplates/WelcomeEmail" @@ -19,17 +20,15 @@ namespace Volo.Abp.TextTemplating.VirtualFiles ) ); - contributor - .GetOrNull("en") - .ShouldBe("Welcome {{model.name}} to the abp.io!"); + (await contributor + .GetOrNullAsync("en")).ShouldBe("Welcome {{model.name}} to the abp.io!"); - contributor - .GetOrNull("tr") - .ShouldBe("Merhaba {{model.name}}, abp.io'ya hoşgeldiniz!"); + (await contributor + .GetOrNullAsync("tr")).ShouldBe("Merhaba {{model.name}}, abp.io'ya hoşgeldiniz!"); } [Fact] - public void Should_Get_Non_Localized_Template_Content() + public async Task Should_Get_Non_Localized_Template_Content() { var contributor = new VirtualFileTemplateContributor( "/SampleTemplates/ForgotPasswordEmail.tpl" @@ -42,9 +41,8 @@ namespace Volo.Abp.TextTemplating.VirtualFiles ) ); - contributor - .GetOrNull() - .ShouldBe("{{l \"HelloText\"}}. Please click to the following link to get an email to reset your password!"); + (await contributor + .GetOrNullAsync()).ShouldBe("{{l \"HelloText\"}}. Please click to the following link to get an email to reset your password!"); } } } From 1950a8dcc5f1f7e86b6b3434bf5ad77939e2ac09 Mon Sep 17 00:00:00 2001 From: Ahmet Date: Thu, 23 Apr 2020 23:50:11 +0300 Subject: [PATCH 16/35] TemplateRenderer null checking updated --- .../Volo/Abp/TextTemplating/TemplateRenderer.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) 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 558104e3a4..8b67a380f0 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateRenderer.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateRenderer.cs @@ -35,10 +35,7 @@ namespace Volo.Abp.TextTemplating { Check.NotNullOrWhiteSpace(templateName, nameof(templateName)); - if (cultureName == null) - { - cultureName = CultureInfo.CurrentUICulture.Name; - } + cultureName ??= CultureInfo.CurrentUICulture.Name; using (CultureHelper.Use(cultureName)) { From 0e519b765742e269e0dfff7d5c946bfc2775b412 Mon Sep 17 00:00:00 2001 From: Ahmet Date: Fri, 24 Apr 2020 00:13:43 +0300 Subject: [PATCH 17/35] null checking updated --- .../VirtualFiles/VirtualFileTemplateContributor.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContributor.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContributor.cs index ae4b8c92f0..eded060a2e 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContributor.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContributor.cs @@ -35,10 +35,7 @@ namespace Volo.Abp.TextTemplating.VirtualFiles { //TODO: Refactor: Split implementation based on single file or dictionary of culture-specific contents - if (cultureName == null) - { - cultureName = CultureInfo.CurrentUICulture.Name; - } + cultureName ??= CultureInfo.CurrentUICulture.Name; var dictionary = GetTemplateDictionary(); From 4437bf7ec0e467097312addea99997e726ceb9ac Mon Sep 17 00:00:00 2001 From: Ahmet Date: Fri, 24 Apr 2020 01:01:06 +0300 Subject: [PATCH 18/35] renamed some properties. --- .../Abp/TextTemplating/TemplateDefinitionContext.cs | 12 ++++++------ .../Abp/TextTemplating/TemplateDefinitionManager.cs | 8 ++++---- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionContext.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionContext.cs index 39da2f5e88..59fe7fced1 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionContext.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionContext.cs @@ -5,21 +5,21 @@ namespace Volo.Abp.TextTemplating { public class TemplateDefinitionContext : ITemplateDefinitionContext { - protected Dictionary EmailTemplates { get; } + protected Dictionary TextTemplates { get; } - public TemplateDefinitionContext(Dictionary emailTemplates) + public TemplateDefinitionContext(Dictionary textTemplates) { - EmailTemplates = emailTemplates; + TextTemplates = textTemplates; } public virtual TemplateDefinition GetOrNull(string name) { - return EmailTemplates.GetOrDefault(name); + return TextTemplates.GetOrDefault(name); } public virtual IReadOnlyList GetAll() { - return EmailTemplates.Values.ToImmutableList(); + return TextTemplates.Values.ToImmutableList(); } public virtual void Add(params TemplateDefinition[] definitions) @@ -31,7 +31,7 @@ namespace Volo.Abp.TextTemplating foreach (var definition in definitions) { - EmailTemplates[definition.Name] = definition; + TextTemplates[definition.Name] = definition; } } } diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionManager.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionManager.cs index 534010dbe2..657e227e9c 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionManager.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionManager.cs @@ -10,7 +10,7 @@ namespace Volo.Abp.TextTemplating { public class TemplateDefinitionManager : ITemplateDefinitionManager, ISingletonDependency { - protected Lazy> EmailTemplateDefinitions { get; } + protected Lazy> TemplateDefinitions { get; } protected AbpTextTemplatingOptions Options { get; } @@ -23,7 +23,7 @@ namespace Volo.Abp.TextTemplating ServiceProvider = serviceProvider; Options = options.Value; - EmailTemplateDefinitions = + TemplateDefinitions = new Lazy>(CreateEmailTemplateDefinitions, true); } @@ -43,12 +43,12 @@ namespace Volo.Abp.TextTemplating public virtual IReadOnlyList GetAll() { - return EmailTemplateDefinitions.Value.Values.ToImmutableList(); + return TemplateDefinitions.Value.Values.ToImmutableList(); } public virtual TemplateDefinition GetOrNull(string name) { - return EmailTemplateDefinitions.Value.GetOrDefault(name); + return TemplateDefinitions.Value.GetOrDefault(name); } protected virtual IDictionary CreateEmailTemplateDefinitions() From e1990d1a3f2fb6d6e38b01fc73ec997fa5df5cef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Fri, 24 Apr 2020 16:57:45 +0300 Subject: [PATCH 19/35] rename template contributor to template content contributor --- .../Volo/Abp/TextTemplating/AbpTextTemplatingModule.cs | 4 ++-- ...plateContributor.cs => ITemplateContentContributor.cs} | 4 ++-- ...=> TemplateContentContributorInitializationContext.cs} | 4 ++-- ...ntributorList.cs => TemplateContentContributorList.cs} | 2 +- .../Volo/Abp/TextTemplating/TemplateContentProvider.cs | 2 +- .../Volo/Abp/TextTemplating/TemplateDefinition.cs | 8 ++++---- .../Abp/TextTemplating/TemplateDefinitionExtensions.cs | 2 +- ...ibutor.cs => VirtualFileTemplateContentContributor.cs} | 6 +++--- .../VirtualFiles/VirtualFileTemplateContributor_Tests.cs | 8 ++++---- 9 files changed, 20 insertions(+), 20 deletions(-) rename framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/{ITemplateContributor.cs => ITemplateContentContributor.cs} (57%) rename framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/{TemplateContributorInitializationContext.cs => TemplateContentContributorInitializationContext.cs} (81%) rename framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/{TemplateContributorList.cs => TemplateContentContributorList.cs} (52%) rename framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/{VirtualFileTemplateContributor.cs => VirtualFileTemplateContentContributor.cs} (93%) 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 e49f271c1c..831de9c1c4 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/AbpTextTemplatingModule.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/AbpTextTemplatingModule.cs @@ -44,12 +44,12 @@ namespace Volo.Abp.TextTemplating foreach (var templateDefinition in templateDefinitionManager.GetAll()) { - var contributorInitializationContext = new TemplateContributorInitializationContext( + var contributorInitializationContext = new TemplateContentContributorInitializationContext( templateDefinition, scope.ServiceProvider ); - foreach (var contributor in templateDefinition.Contributors) + foreach (var contributor in templateDefinition.ContentContributors) { contributor.Initialize(contributorInitializationContext); } diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateContributor.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateContentContributor.cs similarity index 57% rename from framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateContributor.cs rename to framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateContentContributor.cs index 2174a65bcd..26aef67e94 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateContributor.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateContentContributor.cs @@ -3,9 +3,9 @@ using JetBrains.Annotations; namespace Volo.Abp.TextTemplating { - public interface ITemplateContributor + public interface ITemplateContentContributor { - void Initialize(TemplateContributorInitializationContext context); + void Initialize(TemplateContentContributorInitializationContext context); Task GetOrNullAsync([CanBeNull] string cultureName); } diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContributorInitializationContext.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentContributorInitializationContext.cs similarity index 81% rename from framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContributorInitializationContext.cs rename to framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentContributorInitializationContext.cs index ffe97a3484..523f7a6edf 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContributorInitializationContext.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentContributorInitializationContext.cs @@ -3,7 +3,7 @@ using JetBrains.Annotations; namespace Volo.Abp.TextTemplating { - public class TemplateContributorInitializationContext + public class TemplateContentContributorInitializationContext { [NotNull] public TemplateDefinition TemplateDefinition { get; } @@ -11,7 +11,7 @@ namespace Volo.Abp.TextTemplating [NotNull] public IServiceProvider ServiceProvider { get; } - public TemplateContributorInitializationContext( + public TemplateContentContributorInitializationContext( [NotNull] TemplateDefinition templateDefinition, [NotNull] IServiceProvider serviceProvider) { diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContributorList.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentContributorList.cs similarity index 52% rename from framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContributorList.cs rename to framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentContributorList.cs index e737897dae..3c67a03dcc 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContributorList.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentContributorList.cs @@ -2,7 +2,7 @@ namespace Volo.Abp.TextTemplating { - public class TemplateContributorList : List + public class TemplateContentContributorList : List { } diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentProvider.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentProvider.cs index b983c75f11..7c7031c980 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentProvider.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentProvider.cs @@ -29,7 +29,7 @@ namespace Volo.Abp.TextTemplating { Check.NotNull(templateDefinition, nameof(templateDefinition)); - foreach (var contributor in templateDefinition.Contributors) + foreach (var contributor in templateDefinition.ContentContributors) { var templateString = await contributor.GetOrNullAsync(cultureName); if (templateString != null) diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinition.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinition.cs index 09de7bf458..4c4703d5e3 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinition.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinition.cs @@ -16,7 +16,7 @@ namespace Volo.Abp.TextTemplating [CanBeNull] public Type LocalizationResource { get; set; } - public TemplateContributorList Contributors { get; } + public TemplateContentContributorList ContentContributors { get; } [CanBeNull] public string DefaultCultureName { get; } @@ -30,15 +30,15 @@ namespace Volo.Abp.TextTemplating { Name = Check.NotNullOrWhiteSpace(name, nameof(name)); LocalizationResource = localizationResource; - Contributors = new TemplateContributorList(); + ContentContributors = new TemplateContentContributorList(); IsLayout = isLayout; Layout = layout; DefaultCultureName = defaultCultureName; } - public virtual TemplateDefinition WithContributor(ITemplateContributor contributor) + public virtual TemplateDefinition WithContributor(ITemplateContentContributor contentContributor) { - Contributors.Add(contributor); + ContentContributors.Add(contentContributor); return this; } } diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionExtensions.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionExtensions.cs index 9bd932c947..c9a644fedc 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionExtensions.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionExtensions.cs @@ -18,7 +18,7 @@ namespace Volo.Abp.TextTemplating Check.NotNull(templateDefinition, nameof(templateDefinition)); return templateDefinition.WithContributor( - new VirtualFileTemplateContributor(virtualPath) + new VirtualFileTemplateContentContributor(virtualPath) ); } } diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContributor.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContentContributor.cs similarity index 93% rename from framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContributor.cs rename to framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContentContributor.cs index eded060a2e..5a6958e29b 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContributor.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContentContributor.cs @@ -10,7 +10,7 @@ using Volo.Abp.VirtualFileSystem; namespace Volo.Abp.TextTemplating.VirtualFiles { - public class VirtualFileTemplateContributor : ITemplateContributor + public class VirtualFileTemplateContentContributor : ITemplateContentContributor { public TemplateDefinition TemplateDefinition { get; private set; } @@ -19,13 +19,13 @@ namespace Volo.Abp.TextTemplating.VirtualFiles private volatile Dictionary _templateDictionary; private readonly object _syncObj = new object(); - public VirtualFileTemplateContributor( + public VirtualFileTemplateContentContributor( [NotNull] string virtualPath) { _virtualPath = Check.NotNullOrWhiteSpace(virtualPath, nameof(virtualPath)); } - public void Initialize(TemplateContributorInitializationContext context) + public void Initialize(TemplateContentContributorInitializationContext context) { _virtualFileProvider = context.ServiceProvider.GetRequiredService(); TemplateDefinition = context.TemplateDefinition; diff --git a/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContributor_Tests.cs b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContributor_Tests.cs index 1ff2596342..0bf54a5bee 100644 --- a/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContributor_Tests.cs +++ b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContributor_Tests.cs @@ -9,12 +9,12 @@ namespace Volo.Abp.TextTemplating.VirtualFiles [Fact] public async Task Should_Get_Localized_Content_By_Culture() { - var contributor = new VirtualFileTemplateContributor( + var contributor = new VirtualFileTemplateContentContributor( "/SampleTemplates/WelcomeEmail" ); contributor.Initialize( - new TemplateContributorInitializationContext( + new TemplateContentContributorInitializationContext( new TemplateDefinition("Test"), ServiceProvider ) @@ -30,12 +30,12 @@ namespace Volo.Abp.TextTemplating.VirtualFiles [Fact] public async Task Should_Get_Non_Localized_Template_Content() { - var contributor = new VirtualFileTemplateContributor( + var contributor = new VirtualFileTemplateContentContributor( "/SampleTemplates/ForgotPasswordEmail.tpl" ); contributor.Initialize( - new TemplateContributorInitializationContext( + new TemplateContentContributorInitializationContext( new TemplateDefinition("Test"), ServiceProvider ) From f3d82a3807d0e834c4298cdf5cc3fd33f971e834 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Fri, 24 Apr 2020 17:24:18 +0300 Subject: [PATCH 20/35] Refactor text template contribution system. --- .../TextTemplating/AbpTextTemplatingModule.cs | 34 ++------ .../AbpTextTemplatingOptions.cs | 2 + .../ITemplateContentContributor.cs | 5 +- .../TemplateContentContributorContext.cs | 27 ++++++ ...ContentContributorInitializationContext.cs | 13 --- .../TextTemplating/TemplateContentProvider.cs | 45 ++++++++-- .../Abp/TextTemplating/TemplateDefinition.cs | 34 ++++++-- .../TemplateDefinitionExtensions.cs | 5 +- .../VirtualFileTemplateContentContributor.cs | 84 ++++++++----------- .../VirtualFileTemplateContributor_Tests.cs | 71 ++++++++-------- 10 files changed, 176 insertions(+), 144 deletions(-) create mode 100644 framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentContributorContext.cs 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 831de9c1c4..aca0ac8f53 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/AbpTextTemplatingModule.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/AbpTextTemplatingModule.cs @@ -13,12 +13,13 @@ namespace Volo.Abp.TextTemplating { public override void PreConfigureServices(ServiceConfigurationContext context) { - AutoAddDefinitionProviders(context.Services); + AutoAddProvidersAndContributors(context.Services); } - private static void AutoAddDefinitionProviders(IServiceCollection services) + private static void AutoAddProvidersAndContributors(IServiceCollection services) { var definitionProviders = new List(); + var contentContributors = new List(); services.OnRegistred(context => { @@ -26,35 +27,18 @@ namespace Volo.Abp.TextTemplating { definitionProviders.Add(context.ImplementationType); } + + if (typeof(ITemplateContentContributor).IsAssignableFrom(context.ImplementationType)) + { + contentContributors.Add(context.ImplementationType); + } }); services.Configure(options => { options.DefinitionProviders.AddIfNotContains(definitionProviders); + options.ContentContributors.AddIfNotContains(contentContributors); }); } - - 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 TemplateContentContributorInitializationContext( - templateDefinition, - scope.ServiceProvider - ); - - foreach (var contributor in templateDefinition.ContentContributors) - { - contributor.Initialize(contributorInitializationContext); - } - } - } - } } } diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/AbpTextTemplatingOptions.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/AbpTextTemplatingOptions.cs index a79b66e255..b217094974 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/AbpTextTemplatingOptions.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/AbpTextTemplatingOptions.cs @@ -5,10 +5,12 @@ namespace Volo.Abp.TextTemplating public class AbpTextTemplatingOptions { public ITypeList DefinitionProviders { get; } + public ITypeList ContentContributors { get; } public AbpTextTemplatingOptions() { DefinitionProviders = new TypeList(); + ContentContributors = new TypeList(); } } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateContentContributor.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateContentContributor.cs index 26aef67e94..746b29a2f0 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateContentContributor.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateContentContributor.cs @@ -1,12 +1,9 @@ using System.Threading.Tasks; -using JetBrains.Annotations; namespace Volo.Abp.TextTemplating { public interface ITemplateContentContributor { - void Initialize(TemplateContentContributorInitializationContext context); - - Task GetOrNullAsync([CanBeNull] string cultureName); + Task GetOrNullAsync(TemplateContentContributorContext context); } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentContributorContext.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentContributorContext.cs new file mode 100644 index 0000000000..773bf1a0a4 --- /dev/null +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentContributorContext.cs @@ -0,0 +1,27 @@ +using System; +using JetBrains.Annotations; + +namespace Volo.Abp.TextTemplating +{ + public class TemplateContentContributorContext + { + [NotNull] + public TemplateDefinition TemplateDefinition { get; } + + [NotNull] + public IServiceProvider ServiceProvider { get; } + + [CanBeNull] + public string Culture { get; } + + public TemplateContentContributorContext( + [NotNull] TemplateDefinition templateDefinition, + [NotNull] IServiceProvider serviceProvider, + [CanBeNull] string culture) + { + TemplateDefinition = Check.NotNull(templateDefinition, nameof(templateDefinition)); + ServiceProvider = Check.NotNull(serviceProvider, nameof(serviceProvider)); + Culture = culture; + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentContributorInitializationContext.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentContributorInitializationContext.cs index 523f7a6edf..bf6ea65909 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentContributorInitializationContext.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentContributorInitializationContext.cs @@ -5,18 +5,5 @@ namespace Volo.Abp.TextTemplating { public class TemplateContentContributorInitializationContext { - [NotNull] - public TemplateDefinition TemplateDefinition { get; } - - [NotNull] - public IServiceProvider ServiceProvider { get; } - - public TemplateContentContributorInitializationContext( - [NotNull] TemplateDefinition templateDefinition, - [NotNull] IServiceProvider serviceProvider) - { - TemplateDefinition = Check.NotNull(templateDefinition, nameof(templateDefinition)); - ServiceProvider = Check.NotNull(serviceProvider, nameof(serviceProvider)); - } } } \ 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 index 7c7031c980..d7d7982f16 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentProvider.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentProvider.cs @@ -1,17 +1,25 @@ -using System.Threading.Tasks; +using System.Linq; +using System.Threading.Tasks; using JetBrains.Annotations; +using Microsoft.Extensions.DependencyInjection; +using Microsoft.Extensions.Options; using Volo.Abp.DependencyInjection; namespace Volo.Abp.TextTemplating { public class TemplateContentProvider : ITemplateContentProvider, ITransientDependency { + public IHybridServiceScopeFactory ServiceScopeFactory { get; } + public AbpTextTemplatingOptions Options { get; } private readonly ITemplateDefinitionManager _templateDefinitionManager; public TemplateContentProvider( - ITemplateDefinitionManager templateDefinitionManager - ) + ITemplateDefinitionManager templateDefinitionManager, + IHybridServiceScopeFactory serviceScopeFactory, + IOptions options) { + ServiceScopeFactory = serviceScopeFactory; + Options = options.Value; _templateDefinitionManager = templateDefinitionManager; } @@ -29,17 +37,36 @@ namespace Volo.Abp.TextTemplating { Check.NotNull(templateDefinition, nameof(templateDefinition)); - foreach (var contributor in templateDefinition.ContentContributors) + if (!Options.ContentContributors.Any()) { - var templateString = await contributor.GetOrNullAsync(cultureName); - if (templateString != null) + throw new AbpException( + $"No template content contributor was registered. Use {nameof(AbpTextTemplatingOptions)} to register contributors!" + ); + } + + using (var scope = ServiceScopeFactory.CreateScope()) + { + var context = new TemplateContentContributorContext( + templateDefinition, + scope.ServiceProvider, + cultureName + ); + + foreach (var contentContributorType in Options.ContentContributors) { - return templateString; + var contributor = (ITemplateContentContributor) scope.ServiceProvider + .GetRequiredService(contentContributorType); + + var templateString = await contributor.GetOrNullAsync(context); + if (templateString != null) + { + return templateString; + } } } - + throw new AbpException( - $"None of the template contributors could get the content for the template '{templateDefinition.Name}'" + $"None of the template content contributors could get the content for the template '{templateDefinition.Name}'" ); } } diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinition.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinition.cs index 4c4703d5e3..d165eb4d31 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinition.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinition.cs @@ -1,4 +1,5 @@ using System; +using System.Collections.Generic; using JetBrains.Annotations; namespace Volo.Abp.TextTemplating @@ -16,11 +17,30 @@ namespace Volo.Abp.TextTemplating [CanBeNull] public Type LocalizationResource { get; set; } - public TemplateContentContributorList ContentContributors { get; } - [CanBeNull] public string DefaultCultureName { get; } + /// + /// Gets/sets a key-value on the . + /// + /// Name of the property + /// + /// Returns the value in the dictionary by given . + /// Returns null if given is not present in the dictionary. + /// + [CanBeNull] + public object this[string name] + { + get => Properties.GetOrDefault(name); + set => Properties[name] = value; + } + + /// + /// Can be used to get/set custom properties for this feature. + /// + [NotNull] + public Dictionary Properties { get; } + public TemplateDefinition( [NotNull] string name, [CanBeNull] Type localizationResource = null, @@ -30,15 +50,19 @@ namespace Volo.Abp.TextTemplating { Name = Check.NotNullOrWhiteSpace(name, nameof(name)); LocalizationResource = localizationResource; - ContentContributors = new TemplateContentContributorList(); IsLayout = isLayout; Layout = layout; DefaultCultureName = defaultCultureName; + Properties = new Dictionary(); } - public virtual TemplateDefinition WithContributor(ITemplateContentContributor contentContributor) + /// + /// Sets a property in the dictionary. + /// This is a shortcut for nested calls on this object. + /// + public virtual TemplateDefinition WithProperty(string key, object value) { - ContentContributors.Add(contentContributor); + Properties[key] = value; return this; } } diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionExtensions.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionExtensions.cs index c9a644fedc..ef4a0ac9a3 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionExtensions.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionExtensions.cs @@ -17,8 +17,9 @@ namespace Volo.Abp.TextTemplating { Check.NotNull(templateDefinition, nameof(templateDefinition)); - return templateDefinition.WithContributor( - new VirtualFileTemplateContentContributor(virtualPath) + return templateDefinition.WithProperty( + VirtualFileTemplateContentContributor.VirtualPathPropertyName, + virtualPath ); } } diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContentContributor.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContentContributor.cs index 5a6958e29b..6d373dfec1 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContentContributor.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContentContributor.cs @@ -2,42 +2,38 @@ using System.Collections.Generic; using System.Globalization; using System.Threading.Tasks; -using JetBrains.Annotations; -using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.FileProviders; +using Volo.Abp.DependencyInjection; using Volo.Abp.Localization; using Volo.Abp.VirtualFileSystem; namespace Volo.Abp.TextTemplating.VirtualFiles { - public class VirtualFileTemplateContentContributor : ITemplateContentContributor + public class VirtualFileTemplateContentContributor : ITemplateContentContributor, ITransientDependency { - public TemplateDefinition TemplateDefinition { get; private set; } + public const string VirtualPathPropertyName = "VirtualPath"; - private readonly string _virtualPath; - private IVirtualFileProvider _virtualFileProvider; - private volatile Dictionary _templateDictionary; - private readonly object _syncObj = new object(); + private readonly IVirtualFileProvider _virtualFileProvider; - public VirtualFileTemplateContentContributor( - [NotNull] string virtualPath) + public VirtualFileTemplateContentContributor(IVirtualFileProvider virtualFileProvider) { - _virtualPath = Check.NotNullOrWhiteSpace(virtualPath, nameof(virtualPath)); + _virtualFileProvider = virtualFileProvider; } - public void Initialize(TemplateContentContributorInitializationContext context) + public async Task GetOrNullAsync(TemplateContentContributorContext context) { - _virtualFileProvider = context.ServiceProvider.GetRequiredService(); - TemplateDefinition = context.TemplateDefinition; - } + var virtualPath = context.TemplateDefinition.Properties.GetOrDefault(VirtualPathPropertyName) as string; + if (virtualPath == null) + { + return null; + } - public async Task GetOrNullAsync([CanBeNull] string cultureName = null) - { //TODO: Refactor: Split implementation based on single file or dictionary of culture-specific contents - cultureName ??= CultureInfo.CurrentUICulture.Name; + var cultureName = context.Culture ?? + CultureInfo.CurrentUICulture.Name; - var dictionary = GetTemplateDictionary(); + var dictionary = GetTemplateDictionary(virtualPath); var content = dictionary.GetOrDefault(cultureName); if (content != null) @@ -55,9 +51,9 @@ namespace Volo.Abp.TextTemplating.VirtualFiles } } - if (TemplateDefinition.DefaultCultureName != null) + if (context.TemplateDefinition.DefaultCultureName != null) { - content = dictionary.GetOrDefault(TemplateDefinition.DefaultCultureName); + content = dictionary.GetOrDefault(context.TemplateDefinition.DefaultCultureName); if (content != null) { return content; @@ -67,45 +63,31 @@ namespace Volo.Abp.TextTemplating.VirtualFiles return dictionary.GetOrDefault("__default"); } - private Dictionary GetTemplateDictionary() + private Dictionary GetTemplateDictionary(string virtualPath) { - if (_templateDictionary != null) + var dictionary = new Dictionary(); + + var fileInfo = _virtualFileProvider.GetFileInfo(virtualPath); + if (!fileInfo.IsDirectory) { - return _templateDictionary; + //TODO: __default to consts + dictionary.Add("__default", fileInfo.ReadAsString()); } - - lock (_syncObj) + else { - if (_templateDictionary != null) - { - return _templateDictionary; - } - - var dictionary = new Dictionary(); - - var fileInfo = _virtualFileProvider.GetFileInfo(_virtualPath); - if (!fileInfo.IsDirectory) - { - //TODO: __default to consts - dictionary.Add("__default", fileInfo.ReadAsString()); - } - else + foreach (var file in _virtualFileProvider.GetDirectoryContents(virtualPath)) { - foreach (var file in _virtualFileProvider.GetDirectoryContents(_virtualPath)) + if (file.IsDirectory) { - if (file.IsDirectory) - { - continue; - } - - // TODO: How to normalize file names? - dictionary.Add(file.Name.RemovePostFix(".tpl"), file.ReadAsString()); + continue; } - } - _templateDictionary = dictionary; - return dictionary; + // TODO: How to normalize file names? + dictionary.Add(file.Name.RemovePostFix(".tpl"), file.ReadAsString()); + } } + + return dictionary; } } } \ No newline at end of file diff --git a/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContributor_Tests.cs b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContributor_Tests.cs index 0bf54a5bee..da2d4179de 100644 --- a/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContributor_Tests.cs +++ b/framework/test/Volo.Abp.TextTemplating.Tests/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContributor_Tests.cs @@ -4,45 +4,46 @@ using Xunit; namespace Volo.Abp.TextTemplating.VirtualFiles { - public class VirtualFileTemplateContributor_Tests : AbpTextTemplatingTestBase - { - [Fact] - public async Task Should_Get_Localized_Content_By_Culture() - { - var contributor = new VirtualFileTemplateContentContributor( - "/SampleTemplates/WelcomeEmail" - ); + //TODO: Make tests running again! + //public class VirtualFileTemplateContributor_Tests : AbpTextTemplatingTestBase + //{ + // [Fact] + // public async Task Should_Get_Localized_Content_By_Culture() + // { + // var contributor = new VirtualFileTemplateContentContributor( + // "/SampleTemplates/WelcomeEmail" + // ); - contributor.Initialize( - new TemplateContentContributorInitializationContext( - new TemplateDefinition("Test"), - ServiceProvider - ) - ); + // contributor.Initialize( + // new TemplateContentContributorInitializationContext( + // new TemplateDefinition("Test"), + // ServiceProvider + // ) + // ); - (await contributor - .GetOrNullAsync("en")).ShouldBe("Welcome {{model.name}} to the abp.io!"); + // (await contributor + // .GetOrNullAsync("en")).ShouldBe("Welcome {{model.name}} to the abp.io!"); - (await contributor - .GetOrNullAsync("tr")).ShouldBe("Merhaba {{model.name}}, abp.io'ya hoşgeldiniz!"); - } + // (await contributor + // .GetOrNullAsync("tr")).ShouldBe("Merhaba {{model.name}}, abp.io'ya hoşgeldiniz!"); + // } - [Fact] - public async Task Should_Get_Non_Localized_Template_Content() - { - var contributor = new VirtualFileTemplateContentContributor( - "/SampleTemplates/ForgotPasswordEmail.tpl" - ); + // [Fact] + // public async Task Should_Get_Non_Localized_Template_Content() + // { + // var contributor = new VirtualFileTemplateContentContributor( + // "/SampleTemplates/ForgotPasswordEmail.tpl" + // ); - contributor.Initialize( - new TemplateContentContributorInitializationContext( - new TemplateDefinition("Test"), - ServiceProvider - ) - ); + // contributor.Initialize( + // new TemplateContentContributorInitializationContext( + // new TemplateDefinition("Test"), + // ServiceProvider + // ) + // ); - (await contributor - .GetOrNullAsync()).ShouldBe("{{l \"HelloText\"}}. Please click to the following link to get an email to reset your password!"); - } - } + // (await contributor + // .GetOrNullAsync()).ShouldBe("{{l \"HelloText\"}}. Please click to the following link to get an email to reset your password!"); + // } + //} } From 1dde0dbe2352bcd29795b704d5fd7c0dc0150fd8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Fri, 24 Apr 2020 17:31:36 +0300 Subject: [PATCH 21/35] Added PreDefine and PostDefine methods for the ITemplateDefinitionProvider --- .../TextTemplating/ITemplateDefinitionContext.cs | 6 +++++- .../TextTemplating/ITemplateDefinitionProvider.cs | 4 ++++ .../TextTemplating/TemplateDefinitionContext.cs | 5 +++++ .../TextTemplating/TemplateDefinitionManager.cs | 14 +++++++++++++- .../TextTemplating/TemplateDefinitionProvider.cs | 10 ++++++++++ 5 files changed, 37 insertions(+), 2 deletions(-) diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateDefinitionContext.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateDefinitionContext.cs index 18402f8f9d..515cee74ca 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateDefinitionContext.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateDefinitionContext.cs @@ -1,7 +1,11 @@ -namespace Volo.Abp.TextTemplating +using System.Collections.Generic; + +namespace Volo.Abp.TextTemplating { public interface ITemplateDefinitionContext { + IReadOnlyList GetAll(string name); + TemplateDefinition GetOrNull(string name); void Add(params TemplateDefinition[] definitions); diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateDefinitionProvider.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateDefinitionProvider.cs index a9e5155d0c..aeb6a3c2da 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateDefinitionProvider.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateDefinitionProvider.cs @@ -2,6 +2,10 @@ { public interface ITemplateDefinitionProvider { + void PreDefine(ITemplateDefinitionContext context); + void Define(ITemplateDefinitionContext context); + + void PostDefine(ITemplateDefinitionContext context); } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionContext.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionContext.cs index 59fe7fced1..d0911f21ac 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionContext.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionContext.cs @@ -12,6 +12,11 @@ namespace Volo.Abp.TextTemplating TextTemplates = textTemplates; } + public IReadOnlyList GetAll(string name) + { + return TextTemplates.Values.ToImmutableList(); + } + public virtual TemplateDefinition GetOrNull(string name) { return TextTemplates.GetOrDefault(name); diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionManager.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionManager.cs index 657e227e9c..224b220396 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionManager.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionManager.cs @@ -62,9 +62,21 @@ namespace Volo.Abp.TextTemplating .Select(p => scope.ServiceProvider.GetRequiredService(p) as ITemplateDefinitionProvider) .ToList(); + var context = new TemplateDefinitionContext(templates); + + foreach (var provider in providers) + { + provider.PreDefine(context); + } + + foreach (var provider in providers) + { + provider.Define(context); + } + foreach (var provider in providers) { - provider.Define(new TemplateDefinitionContext(templates)); + provider.PostDefine(context); } } diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionProvider.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionProvider.cs index 9afc22a8b8..924a6dfdd8 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionProvider.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionProvider.cs @@ -4,6 +4,16 @@ namespace Volo.Abp.TextTemplating { public abstract class TemplateDefinitionProvider : ITemplateDefinitionProvider, ITransientDependency { + public virtual void PreDefine(ITemplateDefinitionContext context) + { + + } + public abstract void Define(ITemplateDefinitionContext context); + + public virtual void PostDefine(ITemplateDefinitionContext context) + { + + } } } \ No newline at end of file From 8af5a54ad2b3f74a9883e3f6d59366c5b7777a40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Fri, 24 Apr 2020 18:42:57 +0300 Subject: [PATCH 22/35] Refactored VirtualFileTemplateContentContributor --- .../FolderLocalizedTemplateContentReader.cs | 65 ++++++++++++++ .../ILocalizedTemplateContentReader.cs | 7 ++ .../NullLocalizedTemplateContentReader.cs | 19 +++++ ...ingleFileLocalizedTemplateContentReader.cs | 20 +++++ .../VirtualFileTemplateContentContributor.cs | 85 +++++++------------ .../FileProviders/AbpFileInfoExtensions.cs | 24 ++++++ 6 files changed, 164 insertions(+), 56 deletions(-) create mode 100644 framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/FolderLocalizedTemplateContentReader.cs create mode 100644 framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/ILocalizedTemplateContentReader.cs create mode 100644 framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/NullLocalizedTemplateContentReader.cs create mode 100644 framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/SingleFileLocalizedTemplateContentReader.cs diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/FolderLocalizedTemplateContentReader.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/FolderLocalizedTemplateContentReader.cs new file mode 100644 index 0000000000..65bb2423a8 --- /dev/null +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/FolderLocalizedTemplateContentReader.cs @@ -0,0 +1,65 @@ +using System; +using System.Collections.Generic; +using System.Threading.Tasks; +using Microsoft.Extensions.FileProviders; +using Volo.Abp.Localization; +using Volo.Abp.VirtualFileSystem; + +namespace Volo.Abp.TextTemplating.VirtualFiles +{ + public class FolderLocalizedTemplateContentReader : ILocalizedTemplateContentReader + { + private Dictionary _dictionary; + + public async Task ReadContentsAsync(IVirtualFileProvider virtualFileProvider, string virtualPath) + { + _dictionary = new Dictionary(); + + var directoryInfo = virtualFileProvider.GetFileInfo(virtualPath); + if (!directoryInfo.IsDirectory) + { + throw new AbpException("Given virtual path is not a folder: " + virtualPath); + } + + foreach (var file in virtualFileProvider.GetDirectoryContents(virtualPath)) + { + if (file.IsDirectory) + { + continue; + } + + _dictionary.Add(file.Name.RemovePostFix(".tpl"), await file.ReadAsStringAsync()); + } + } + + public string GetContent(string cultureName, string defaultCultureName) + { + 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; + } + } + + if (defaultCultureName != null) + { + content = _dictionary.GetOrDefault(defaultCultureName); + if (content != null) + { + return content; + } + } + + return null; + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/ILocalizedTemplateContentReader.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/ILocalizedTemplateContentReader.cs new file mode 100644 index 0000000000..0b028138cd --- /dev/null +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/ILocalizedTemplateContentReader.cs @@ -0,0 +1,7 @@ +namespace Volo.Abp.TextTemplating.VirtualFiles +{ + public interface ILocalizedTemplateContentReader + { + public string GetContent(string culture, string defaultCultureName = null); + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/NullLocalizedTemplateContentReader.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/NullLocalizedTemplateContentReader.cs new file mode 100644 index 0000000000..0578a716ae --- /dev/null +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/NullLocalizedTemplateContentReader.cs @@ -0,0 +1,19 @@ +namespace Volo.Abp.TextTemplating.VirtualFiles +{ + public class NullLocalizedTemplateContentReader : ILocalizedTemplateContentReader + { + public static NullLocalizedTemplateContentReader Instance { get; } = new NullLocalizedTemplateContentReader(); + + private NullLocalizedTemplateContentReader() + { + + } + + public string GetContent( + string culture, + string defaultCultureName = null) + { + return null; + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/SingleFileLocalizedTemplateContentReader.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/SingleFileLocalizedTemplateContentReader.cs new file mode 100644 index 0000000000..23e4bfc14a --- /dev/null +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/SingleFileLocalizedTemplateContentReader.cs @@ -0,0 +1,20 @@ +using System.Threading.Tasks; +using Microsoft.Extensions.FileProviders; + +namespace Volo.Abp.TextTemplating.VirtualFiles +{ + public class SingleFileLocalizedTemplateContentReader : ILocalizedTemplateContentReader + { + private string _content; + + public async Task ReadContentsAsync(IFileInfo fileInfo) + { + _content = await fileInfo.ReadAsStringAsync(); + } + + public string GetContent(string culture, string defaultCultureName) + { + return _content; + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContentContributor.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContentContributor.cs index 6d373dfec1..dea4920447 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContentContributor.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContentContributor.cs @@ -1,10 +1,7 @@ -using System; -using System.Collections.Generic; +using System.Collections.Generic; using System.Globalization; using System.Threading.Tasks; -using Microsoft.Extensions.FileProviders; using Volo.Abp.DependencyInjection; -using Volo.Abp.Localization; using Volo.Abp.VirtualFileSystem; namespace Volo.Abp.TextTemplating.VirtualFiles @@ -20,74 +17,50 @@ namespace Volo.Abp.TextTemplating.VirtualFiles _virtualFileProvider = virtualFileProvider; } - public async Task GetOrNullAsync(TemplateContentContributorContext context) + public virtual async Task GetOrNullAsync(TemplateContentContributorContext context) { - var virtualPath = context.TemplateDefinition.Properties.GetOrDefault(VirtualPathPropertyName) as string; - if (virtualPath == null) - { - return null; - } - - //TODO: Refactor: Split implementation based on single file or dictionary of culture-specific contents - var cultureName = context.Culture ?? CultureInfo.CurrentUICulture.Name; - var dictionary = GetTemplateDictionary(virtualPath); + var localizedReader = await CreateLocalizedReader(context); - var content = dictionary.GetOrDefault(cultureName); - if (content != null) - { - return content; - } + return localizedReader.GetContent( + cultureName, + context.TemplateDefinition.DefaultCultureName + ); + } + + protected async Task CreateLocalizedReader( + TemplateContentContributorContext context) + { + var virtualPath = context + .TemplateDefinition + .Properties + .GetOrDefault(VirtualPathPropertyName) as string; - if (cultureName.Contains("-")) + if (virtualPath == null) { - var baseCultureName = CultureHelper.GetBaseCultureName(cultureName); - content = dictionary.GetOrDefault(baseCultureName); - if (content != null) - { - return content; - } + return NullLocalizedTemplateContentReader.Instance; } - if (context.TemplateDefinition.DefaultCultureName != null) + var fileInfo = _virtualFileProvider.GetFileInfo(virtualPath); + if (!fileInfo.Exists) { - content = dictionary.GetOrDefault(context.TemplateDefinition.DefaultCultureName); - if (content != null) - { - return content; - } + throw new AbpException("Could not find a file/folder at the location: " + virtualPath); } - return dictionary.GetOrDefault("__default"); - } - - private Dictionary GetTemplateDictionary(string virtualPath) - { - var dictionary = new Dictionary(); - - var fileInfo = _virtualFileProvider.GetFileInfo(virtualPath); - if (!fileInfo.IsDirectory) + if (fileInfo.IsDirectory) { - //TODO: __default to consts - dictionary.Add("__default", fileInfo.ReadAsString()); + var folderReader = new FolderLocalizedTemplateContentReader(); + await folderReader.ReadContentsAsync(_virtualFileProvider, virtualPath); + return folderReader; } - else + else //File { - foreach (var file in _virtualFileProvider.GetDirectoryContents(virtualPath)) - { - if (file.IsDirectory) - { - continue; - } - - // TODO: How to normalize file names? - dictionary.Add(file.Name.RemovePostFix(".tpl"), file.ReadAsString()); - } + var singleFileReader = new SingleFileLocalizedTemplateContentReader(); + await singleFileReader.ReadContentsAsync(fileInfo); + return singleFileReader; } - - return dictionary; } } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.VirtualFileSystem/Microsoft/Extensions/FileProviders/AbpFileInfoExtensions.cs b/framework/src/Volo.Abp.VirtualFileSystem/Microsoft/Extensions/FileProviders/AbpFileInfoExtensions.cs index 7d3505d616..8a6d7d57a1 100644 --- a/framework/src/Volo.Abp.VirtualFileSystem/Microsoft/Extensions/FileProviders/AbpFileInfoExtensions.cs +++ b/framework/src/Volo.Abp.VirtualFileSystem/Microsoft/Extensions/FileProviders/AbpFileInfoExtensions.cs @@ -18,6 +18,14 @@ namespace Microsoft.Extensions.FileProviders return fileInfo.ReadAsString(Encoding.UTF8); } + /// + /// Reads file content as string using encoding. + /// + public static Task ReadAsStringAsync([NotNull] this IFileInfo fileInfo) + { + return fileInfo.ReadAsStringAsync(Encoding.UTF8); + } + /// /// Reads file content as string using the given . /// @@ -34,6 +42,22 @@ namespace Microsoft.Extensions.FileProviders } } + /// + /// Reads file content as string using the given . + /// + public static async Task ReadAsStringAsync([NotNull] this IFileInfo fileInfo, Encoding encoding) + { + Check.NotNull(fileInfo, nameof(fileInfo)); + + using (var stream = fileInfo.CreateReadStream()) + { + using (var streamReader = new StreamReader(stream, encoding, true)) + { + return await streamReader.ReadToEndAsync(); + } + } + } + /// /// Reads file content as byte[]. /// From a29cdda2c53de46579e4044b8a3ee5b4c33d17e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Fri, 24 Apr 2020 18:51:51 +0300 Subject: [PATCH 23/35] Extract LocalizedTemplateContentReaderFactory --- .../ILocalizedTemplateContentReaderFactory.cs | 9 ++++ .../LocalizedTemplateContentReaderFactory.cs | 54 +++++++++++++++++++ .../VirtualFileTemplateContentContributor.cs | 51 +++--------------- 3 files changed, 70 insertions(+), 44 deletions(-) create mode 100644 framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/ILocalizedTemplateContentReaderFactory.cs create mode 100644 framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/LocalizedTemplateContentReaderFactory.cs diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/ILocalizedTemplateContentReaderFactory.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/ILocalizedTemplateContentReaderFactory.cs new file mode 100644 index 0000000000..2d4d9ef2d5 --- /dev/null +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/ILocalizedTemplateContentReaderFactory.cs @@ -0,0 +1,9 @@ +using System.Threading.Tasks; + +namespace Volo.Abp.TextTemplating.VirtualFiles +{ + public interface ILocalizedTemplateContentReaderFactory + { + Task CreateAsync(TemplateDefinition templateDefinition); + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/LocalizedTemplateContentReaderFactory.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/LocalizedTemplateContentReaderFactory.cs new file mode 100644 index 0000000000..41527c4e11 --- /dev/null +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/LocalizedTemplateContentReaderFactory.cs @@ -0,0 +1,54 @@ +using System.Collections.Generic; +using System.Threading.Tasks; +using Volo.Abp.DependencyInjection; +using Volo.Abp.VirtualFileSystem; + +namespace Volo.Abp.TextTemplating.VirtualFiles +{ + public class LocalizedTemplateContentReaderFactory : ILocalizedTemplateContentReaderFactory, ISingletonDependency + { + private readonly IVirtualFileProvider _virtualFileProvider; + + public LocalizedTemplateContentReaderFactory(IVirtualFileProvider virtualFileProvider) + { + _virtualFileProvider = virtualFileProvider; + } + + public Task CreateAsync(TemplateDefinition templateDefinition) + { + return CreateLocalizedReader(templateDefinition); + } + + protected async Task CreateLocalizedReader( + TemplateDefinition templateDefinition) + { + var virtualPath = templateDefinition + .Properties + .GetOrDefault(VirtualFileTemplateContentContributor.VirtualPathPropertyName) as string; + + if (virtualPath == null) + { + return NullLocalizedTemplateContentReader.Instance; + } + + var fileInfo = _virtualFileProvider.GetFileInfo(virtualPath); + if (!fileInfo.Exists) + { + throw new AbpException("Could not find a file/folder at the location: " + virtualPath); + } + + if (fileInfo.IsDirectory) + { + var folderReader = new FolderLocalizedTemplateContentReader(); + await folderReader.ReadContentsAsync(_virtualFileProvider, virtualPath); + return folderReader; + } + else //File + { + var singleFileReader = new SingleFileLocalizedTemplateContentReader(); + await singleFileReader.ReadContentsAsync(fileInfo); + return singleFileReader; + } + } + } +} \ No newline at end of file diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContentContributor.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContentContributor.cs index dea4920447..1240352bd2 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContentContributor.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContentContributor.cs @@ -1,8 +1,6 @@ -using System.Collections.Generic; -using System.Globalization; +using System.Globalization; using System.Threading.Tasks; using Volo.Abp.DependencyInjection; -using Volo.Abp.VirtualFileSystem; namespace Volo.Abp.TextTemplating.VirtualFiles { @@ -10,57 +8,22 @@ namespace Volo.Abp.TextTemplating.VirtualFiles { public const string VirtualPathPropertyName = "VirtualPath"; - private readonly IVirtualFileProvider _virtualFileProvider; + private readonly ILocalizedTemplateContentReaderFactory _localizedTemplateContentReaderFactory; - public VirtualFileTemplateContentContributor(IVirtualFileProvider virtualFileProvider) + public VirtualFileTemplateContentContributor(ILocalizedTemplateContentReaderFactory localizedTemplateContentReaderFactory) { - _virtualFileProvider = virtualFileProvider; + _localizedTemplateContentReaderFactory = localizedTemplateContentReaderFactory; } public virtual async Task GetOrNullAsync(TemplateContentContributorContext context) { - var cultureName = context.Culture ?? - CultureInfo.CurrentUICulture.Name; - - var localizedReader = await CreateLocalizedReader(context); + var localizedReader = await _localizedTemplateContentReaderFactory + .CreateAsync(context.TemplateDefinition); return localizedReader.GetContent( - cultureName, + context.Culture ?? CultureInfo.CurrentUICulture.Name, context.TemplateDefinition.DefaultCultureName ); } - - protected async Task CreateLocalizedReader( - TemplateContentContributorContext context) - { - var virtualPath = context - .TemplateDefinition - .Properties - .GetOrDefault(VirtualPathPropertyName) as string; - - if (virtualPath == null) - { - return NullLocalizedTemplateContentReader.Instance; - } - - var fileInfo = _virtualFileProvider.GetFileInfo(virtualPath); - if (!fileInfo.Exists) - { - throw new AbpException("Could not find a file/folder at the location: " + virtualPath); - } - - if (fileInfo.IsDirectory) - { - var folderReader = new FolderLocalizedTemplateContentReader(); - await folderReader.ReadContentsAsync(_virtualFileProvider, virtualPath); - return folderReader; - } - else //File - { - var singleFileReader = new SingleFileLocalizedTemplateContentReader(); - await singleFileReader.ReadContentsAsync(fileInfo); - return singleFileReader; - } - } } } \ No newline at end of file From 15ce08853d881694f5a5c2f470e8f6da7dc636ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Fri, 24 Apr 2020 18:53:39 +0300 Subject: [PATCH 24/35] Rename template content readers. --- ...tReader.cs => FileInfoLocalizedTemplateContentReader.cs} | 2 +- .../VirtualFiles/LocalizedTemplateContentReaderFactory.cs | 4 ++-- .../VirtualFiles/VirtualFileTemplateContentContributor.cs | 3 ++- ...er.cs => VirtualFolderLocalizedTemplateContentReader.cs} | 6 ++++-- 4 files changed, 9 insertions(+), 6 deletions(-) rename framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/{SingleFileLocalizedTemplateContentReader.cs => FileInfoLocalizedTemplateContentReader.cs} (82%) rename framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/{FolderLocalizedTemplateContentReader.cs => VirtualFolderLocalizedTemplateContentReader.cs} (88%) diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/SingleFileLocalizedTemplateContentReader.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/FileInfoLocalizedTemplateContentReader.cs similarity index 82% rename from framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/SingleFileLocalizedTemplateContentReader.cs rename to framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/FileInfoLocalizedTemplateContentReader.cs index 23e4bfc14a..4ff941fb84 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/SingleFileLocalizedTemplateContentReader.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/FileInfoLocalizedTemplateContentReader.cs @@ -3,7 +3,7 @@ using Microsoft.Extensions.FileProviders; namespace Volo.Abp.TextTemplating.VirtualFiles { - public class SingleFileLocalizedTemplateContentReader : ILocalizedTemplateContentReader + public class FileInfoLocalizedTemplateContentReader : ILocalizedTemplateContentReader { private string _content; diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/LocalizedTemplateContentReaderFactory.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/LocalizedTemplateContentReaderFactory.cs index 41527c4e11..b22a6fb7d5 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/LocalizedTemplateContentReaderFactory.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/LocalizedTemplateContentReaderFactory.cs @@ -39,13 +39,13 @@ namespace Volo.Abp.TextTemplating.VirtualFiles if (fileInfo.IsDirectory) { - var folderReader = new FolderLocalizedTemplateContentReader(); + var folderReader = new VirtualFolderLocalizedTemplateContentReader(); await folderReader.ReadContentsAsync(_virtualFileProvider, virtualPath); return folderReader; } else //File { - var singleFileReader = new SingleFileLocalizedTemplateContentReader(); + var singleFileReader = new FileInfoLocalizedTemplateContentReader(); await singleFileReader.ReadContentsAsync(fileInfo); return singleFileReader; } diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContentContributor.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContentContributor.cs index 1240352bd2..e06336c658 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContentContributor.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContentContributor.cs @@ -10,7 +10,8 @@ namespace Volo.Abp.TextTemplating.VirtualFiles private readonly ILocalizedTemplateContentReaderFactory _localizedTemplateContentReaderFactory; - public VirtualFileTemplateContentContributor(ILocalizedTemplateContentReaderFactory localizedTemplateContentReaderFactory) + public VirtualFileTemplateContentContributor( + ILocalizedTemplateContentReaderFactory localizedTemplateContentReaderFactory) { _localizedTemplateContentReaderFactory = localizedTemplateContentReaderFactory; } diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/FolderLocalizedTemplateContentReader.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFolderLocalizedTemplateContentReader.cs similarity index 88% rename from framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/FolderLocalizedTemplateContentReader.cs rename to framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFolderLocalizedTemplateContentReader.cs index 65bb2423a8..0f2a23a2fa 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/FolderLocalizedTemplateContentReader.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFolderLocalizedTemplateContentReader.cs @@ -7,11 +7,13 @@ using Volo.Abp.VirtualFileSystem; namespace Volo.Abp.TextTemplating.VirtualFiles { - public class FolderLocalizedTemplateContentReader : ILocalizedTemplateContentReader + public class VirtualFolderLocalizedTemplateContentReader : ILocalizedTemplateContentReader { private Dictionary _dictionary; - public async Task ReadContentsAsync(IVirtualFileProvider virtualFileProvider, string virtualPath) + public async Task ReadContentsAsync( + IVirtualFileProvider virtualFileProvider, + string virtualPath) { _dictionary = new Dictionary(); From f75e7baef6229e789d4b6a580bc1a159a32e5e6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Fri, 24 Apr 2020 19:04:16 +0300 Subject: [PATCH 25/35] Added caching for the LocalizedTemplateContentReaderFactory. --- .../LocalizedTemplateContentReaderFactory.cs | 41 +++++++++++++++++-- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/LocalizedTemplateContentReaderFactory.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/LocalizedTemplateContentReaderFactory.cs index b22a6fb7d5..f4f8384777 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/LocalizedTemplateContentReaderFactory.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/LocalizedTemplateContentReaderFactory.cs @@ -1,4 +1,7 @@ -using System.Collections.Generic; +using System; +using System.Collections.Concurrent; +using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using Volo.Abp.DependencyInjection; using Volo.Abp.VirtualFileSystem; @@ -8,18 +11,48 @@ namespace Volo.Abp.TextTemplating.VirtualFiles public class LocalizedTemplateContentReaderFactory : ILocalizedTemplateContentReaderFactory, ISingletonDependency { private readonly IVirtualFileProvider _virtualFileProvider; + private readonly Dictionary _readerCache; + private readonly ReaderWriterLockSlim _lock; public LocalizedTemplateContentReaderFactory(IVirtualFileProvider virtualFileProvider) { _virtualFileProvider = virtualFileProvider; + _readerCache = new Dictionary(); + _lock = new ReaderWriterLockSlim(LockRecursionPolicy.NoRecursion); } - public Task CreateAsync(TemplateDefinition templateDefinition) + public async Task CreateAsync(TemplateDefinition templateDefinition) { - return CreateLocalizedReader(templateDefinition); + _lock.EnterUpgradeableReadLock(); + + try + { + var reader = _readerCache.GetOrDefault(templateDefinition.Name); + if (reader != null) + { + return reader; + } + + _lock.EnterWriteLock(); + + try + { + reader = await CreateInternalAsync(templateDefinition); + _readerCache[templateDefinition.Name] = reader; + return reader; + } + finally + { + _lock.ExitWriteLock(); + } + } + finally + { + _lock.ExitUpgradeableReadLock(); + } } - protected async Task CreateLocalizedReader( + protected virtual async Task CreateInternalAsync( TemplateDefinition templateDefinition) { var virtualPath = templateDefinition From da78d48b101dca381ad4a95ba9070f22fb60c065 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Fri, 24 Apr 2020 19:17:10 +0300 Subject: [PATCH 26/35] Remove unused classes of the text template system --- .../TemplateContentContributorInitializationContext.cs | 9 --------- .../Abp/TextTemplating/TemplateContentContributorList.cs | 9 --------- 2 files changed, 18 deletions(-) delete mode 100644 framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentContributorInitializationContext.cs delete mode 100644 framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentContributorList.cs diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentContributorInitializationContext.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentContributorInitializationContext.cs deleted file mode 100644 index bf6ea65909..0000000000 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentContributorInitializationContext.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System; -using JetBrains.Annotations; - -namespace Volo.Abp.TextTemplating -{ - public class TemplateContentContributorInitializationContext - { - } -} \ No newline at end of file diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentContributorList.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentContributorList.cs deleted file mode 100644 index 3c67a03dcc..0000000000 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentContributorList.cs +++ /dev/null @@ -1,9 +0,0 @@ -using System.Collections.Generic; - -namespace Volo.Abp.TextTemplating -{ - public class TemplateContentContributorList : List - { - - } -} \ No newline at end of file From fe35f33265937df6c4fc30c85fe497e5409ae07f Mon Sep 17 00:00:00 2001 From: Ahmet Date: Tue, 28 Apr 2020 21:57:07 +0300 Subject: [PATCH 27/35] NameFix --- .../Volo/Abp/TextTemplating/TemplateDefinitionManager.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionManager.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionManager.cs index 224b220396..28909330fe 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionManager.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionManager.cs @@ -24,7 +24,7 @@ namespace Volo.Abp.TextTemplating Options = options.Value; TemplateDefinitions = - new Lazy>(CreateEmailTemplateDefinitions, true); + new Lazy>(CreateTextTemplateDefinitions, true); } public virtual TemplateDefinition Get(string name) @@ -51,7 +51,7 @@ namespace Volo.Abp.TextTemplating return TemplateDefinitions.Value.GetOrDefault(name); } - protected virtual IDictionary CreateEmailTemplateDefinitions() + protected virtual IDictionary CreateTextTemplateDefinitions() { var templates = new Dictionary(); From 41d1e12a747933df42c5cf0c490ed4109dcb161b Mon Sep 17 00:00:00 2001 From: Ahmet Date: Wed, 29 Apr 2020 00:17:05 +0300 Subject: [PATCH 28/35] contributors reversed for requesting content --- .../Volo/Abp/TextTemplating/TemplateContentProvider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentProvider.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentProvider.cs index d7d7982f16..fdb6a3c9dd 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentProvider.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentProvider.cs @@ -52,7 +52,7 @@ namespace Volo.Abp.TextTemplating cultureName ); - foreach (var contentContributorType in Options.ContentContributors) + foreach (var contentContributorType in Options.ContentContributors.Reverse()) { var contributor = (ITemplateContentContributor) scope.ServiceProvider .GetRequiredService(contentContributorType); From 9a0ecfb9948603d36f67c16f511b60022375727b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Wed, 29 Apr 2020 12:03:35 +0300 Subject: [PATCH 29/35] Remove old TODO --- .../Abp/Localization/LocalizationResourceContributorList.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizationResourceContributorList.cs b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizationResourceContributorList.cs index daa6abe667..a81adf3562 100644 --- a/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizationResourceContributorList.cs +++ b/framework/src/Volo.Abp.Localization/Volo/Abp/Localization/LocalizationResourceContributorList.cs @@ -8,7 +8,7 @@ namespace Volo.Abp.Localization { public LocalizedString GetOrNull(string cultureName, string name) { - foreach (var contributor in this.AsQueryable().Reverse()) //TODO: Reverse? + foreach (var contributor in this.AsQueryable().Reverse()) { var localString = contributor.GetOrNull(cultureName, name); if (localString != null) From 5aec15a123940977301320b0c99087e10969f35c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Wed, 29 Apr 2020 12:54:25 +0300 Subject: [PATCH 30/35] Move culture fallback logic to the TemplateContentProvider --- .../ITemplateContentProvider.cs | 6 +- .../TemplateContentContributorContext.cs | 6 +- .../TextTemplating/TemplateContentProvider.cs | 101 +++++++++++++++--- .../FileInfoLocalizedTemplateContentReader.cs | 2 +- .../ILocalizedTemplateContentReader.cs | 2 +- .../NullLocalizedTemplateContentReader.cs | 4 +- .../VirtualFileTemplateContentContributor.cs | 5 +- ...ualFolderLocalizedTemplateContentReader.cs | 30 +----- 8 files changed, 98 insertions(+), 58 deletions(-) diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateContentProvider.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateContentProvider.cs index 12c8f8f8d8..b352fc0503 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateContentProvider.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateContentProvider.cs @@ -7,12 +7,14 @@ namespace Volo.Abp.TextTemplating { Task GetContentOrNullAsync( [NotNull] string templateName, - [CanBeNull] string cultureName = null + [CanBeNull] string cultureName = null, + bool tryDefaults = true ); Task GetContentOrNullAsync( [NotNull] TemplateDefinition templateDefinition, - [CanBeNull] string cultureName = null + [CanBeNull] string cultureName = null, + bool tryDefaults = true ); } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentContributorContext.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentContributorContext.cs index 773bf1a0a4..bb304a3344 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentContributorContext.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentContributorContext.cs @@ -11,17 +11,17 @@ namespace Volo.Abp.TextTemplating [NotNull] public IServiceProvider ServiceProvider { get; } - [CanBeNull] + [NotNull] public string Culture { get; } public TemplateContentContributorContext( [NotNull] TemplateDefinition templateDefinition, [NotNull] IServiceProvider serviceProvider, - [CanBeNull] string culture) + [NotNull] string culture) { TemplateDefinition = Check.NotNull(templateDefinition, nameof(templateDefinition)); ServiceProvider = Check.NotNull(serviceProvider, nameof(serviceProvider)); - Culture = culture; + Culture = Check.NotNull(culture, nameof(culture)); } } } \ 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 index fdb6a3c9dd..dcb5d88850 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentProvider.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentProvider.cs @@ -1,9 +1,11 @@ -using System.Linq; +using System.Globalization; +using System.Linq; using System.Threading.Tasks; using JetBrains.Annotations; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using Volo.Abp.DependencyInjection; +using Volo.Abp.Localization; namespace Volo.Abp.TextTemplating { @@ -23,17 +25,19 @@ namespace Volo.Abp.TextTemplating _templateDefinitionManager = templateDefinitionManager; } - public Task GetContentOrNullAsync( + public virtual Task GetContentOrNullAsync( [NotNull] string templateName, - [CanBeNull] string cultureName = null) + [CanBeNull] string cultureName = null, + bool tryDefaults = true) { var template = _templateDefinitionManager.Get(templateName); return GetContentOrNullAsync(template, cultureName); } - public async Task GetContentOrNullAsync( + public virtual async Task GetContentOrNullAsync( [NotNull] TemplateDefinition templateDefinition, - [CanBeNull] string cultureName = null) + [CanBeNull] string cultureName = null, + bool tryDefaults = true) { Check.NotNull(templateDefinition, nameof(templateDefinition)); @@ -44,30 +48,93 @@ namespace Volo.Abp.TextTemplating ); } + if (cultureName == null) + { + cultureName = CultureInfo.CurrentUICulture.Name; + } + using (var scope = ServiceScopeFactory.CreateScope()) { - var context = new TemplateContentContributorContext( - templateDefinition, - scope.ServiceProvider, - cultureName + var contributors = Options.ContentContributors + .Select(type => (ITemplateContentContributor) scope.ServiceProvider.GetRequiredService(type)) + .Reverse() + .ToArray(); + + //Try to get from the requested culture + var templateString = await GetContentOrNullAsync( + contributors, + new TemplateContentContributorContext( + templateDefinition, + scope.ServiceProvider, + cultureName + ) ); - foreach (var contentContributorType in Options.ContentContributors.Reverse()) + if (templateString != null) + { + return templateString; + } + + if (!tryDefaults) { - var contributor = (ITemplateContentContributor) scope.ServiceProvider - .GetRequiredService(contentContributorType); + return null; + } + + //Try to get from same culture without country code + if (cultureName.Contains("-")) //Example: "tr-TR" + { + templateString = await GetContentOrNullAsync( + contributors, + new TemplateContentContributorContext( + templateDefinition, + scope.ServiceProvider, + CultureHelper.GetBaseCultureName(cultureName) + ) + ); + + if (templateString != null) + { + return templateString; + } + } + + //Try to get from default culture + if (templateDefinition.DefaultCultureName != null) + { + templateString = await GetContentOrNullAsync( + contributors, + new TemplateContentContributorContext( + templateDefinition, + scope.ServiceProvider, + templateDefinition.DefaultCultureName + ) + ); - var templateString = await contributor.GetOrNullAsync(context); if (templateString != null) { return templateString; } } } - - throw new AbpException( - $"None of the template content contributors could get the content for the template '{templateDefinition.Name}'" - ); + + //Not found + return null; + } + + protected virtual async Task GetContentOrNullAsync( + ITemplateContentContributor[] contributors, + TemplateContentContributorContext context) + { + foreach (var contributor in contributors) + { + var templateString = await contributor.GetOrNullAsync(context); + if (templateString != null) + { + return templateString; + } + } + + return null; } } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/FileInfoLocalizedTemplateContentReader.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/FileInfoLocalizedTemplateContentReader.cs index 4ff941fb84..3ddfb973f3 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/FileInfoLocalizedTemplateContentReader.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/FileInfoLocalizedTemplateContentReader.cs @@ -12,7 +12,7 @@ namespace Volo.Abp.TextTemplating.VirtualFiles _content = await fileInfo.ReadAsStringAsync(); } - public string GetContent(string culture, string defaultCultureName) + public string GetContentOrNull(string culture) { return _content; } diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/ILocalizedTemplateContentReader.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/ILocalizedTemplateContentReader.cs index 0b028138cd..611e50b005 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/ILocalizedTemplateContentReader.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/ILocalizedTemplateContentReader.cs @@ -2,6 +2,6 @@ { public interface ILocalizedTemplateContentReader { - public string GetContent(string culture, string defaultCultureName = null); + public string GetContentOrNull(string culture); } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/NullLocalizedTemplateContentReader.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/NullLocalizedTemplateContentReader.cs index 0578a716ae..475559c634 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/NullLocalizedTemplateContentReader.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/NullLocalizedTemplateContentReader.cs @@ -9,9 +9,7 @@ } - public string GetContent( - string culture, - string defaultCultureName = null) + public string GetContentOrNull(string culture) { return null; } diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContentContributor.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContentContributor.cs index e06336c658..668d1dc3ec 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContentContributor.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContentContributor.cs @@ -21,9 +21,8 @@ namespace Volo.Abp.TextTemplating.VirtualFiles var localizedReader = await _localizedTemplateContentReaderFactory .CreateAsync(context.TemplateDefinition); - return localizedReader.GetContent( - context.Culture ?? CultureInfo.CurrentUICulture.Name, - context.TemplateDefinition.DefaultCultureName + return localizedReader.GetContentOrNull( + context.Culture ); } } diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFolderLocalizedTemplateContentReader.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFolderLocalizedTemplateContentReader.cs index 0f2a23a2fa..b43ab722b7 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFolderLocalizedTemplateContentReader.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFolderLocalizedTemplateContentReader.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Threading.Tasks; using Microsoft.Extensions.FileProviders; -using Volo.Abp.Localization; using Volo.Abp.VirtualFileSystem; namespace Volo.Abp.TextTemplating.VirtualFiles @@ -34,34 +33,9 @@ namespace Volo.Abp.TextTemplating.VirtualFiles } } - public string GetContent(string cultureName, string defaultCultureName) + public string GetContentOrNull(string cultureName) { - 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; - } - } - - if (defaultCultureName != null) - { - content = _dictionary.GetOrDefault(defaultCultureName); - if (content != null) - { - return content; - } - } - - return null; + return _dictionary.GetOrDefault(cultureName); } } } \ No newline at end of file From 720b5d7e2f25bc9cc6fa2afd88a29cbff0f73cd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Wed, 29 Apr 2020 13:19:25 +0300 Subject: [PATCH 31/35] Add TemplateDefinitionIsInlineLocalized. --- .../Abp/TextTemplating/TemplateDefinition.cs | 2 ++ .../TemplateDefinitionContext.cs | 14 ++++----- .../TemplateDefinitionExtensions.cs | 19 +++++++----- .../TemplateDefinitionManager.cs | 30 +++++++++++++++++++ .../LocalizedTemplateContentReaderFactory.cs | 6 +--- .../TextTemplating/TemplateDefinitionTests.cs | 9 ++++-- 6 files changed, 59 insertions(+), 21 deletions(-) diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinition.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinition.cs index d165eb4d31..f3b31a769d 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinition.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinition.cs @@ -17,6 +17,8 @@ namespace Volo.Abp.TextTemplating [CanBeNull] public Type LocalizationResource { get; set; } + public bool IsInlineLocalized { get; internal set; } + [CanBeNull] public string DefaultCultureName { get; } diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionContext.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionContext.cs index d0911f21ac..04c3876531 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionContext.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionContext.cs @@ -5,26 +5,26 @@ namespace Volo.Abp.TextTemplating { public class TemplateDefinitionContext : ITemplateDefinitionContext { - protected Dictionary TextTemplates { get; } + protected Dictionary Templates { get; } - public TemplateDefinitionContext(Dictionary textTemplates) + public TemplateDefinitionContext(Dictionary templates) { - TextTemplates = textTemplates; + Templates = templates; } public IReadOnlyList GetAll(string name) { - return TextTemplates.Values.ToImmutableList(); + return Templates.Values.ToImmutableList(); } public virtual TemplateDefinition GetOrNull(string name) { - return TextTemplates.GetOrDefault(name); + return Templates.GetOrDefault(name); } public virtual IReadOnlyList GetAll() { - return TextTemplates.Values.ToImmutableList(); + return Templates.Values.ToImmutableList(); } public virtual void Add(params TemplateDefinition[] definitions) @@ -36,7 +36,7 @@ namespace Volo.Abp.TextTemplating foreach (var definition in definitions) { - TextTemplates[definition.Name] = definition; + Templates[definition.Name] = definition; } } } diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionExtensions.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionExtensions.cs index ef4a0ac9a3..0d17e9969c 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionExtensions.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionExtensions.cs @@ -1,16 +1,11 @@ -using JetBrains.Annotations; +using System.Collections.Generic; +using JetBrains.Annotations; using Volo.Abp.TextTemplating.VirtualFiles; namespace Volo.Abp.TextTemplating { public static class TemplateDefinitionExtensions { - /// - /// - /// - /// - /// - /// public static TemplateDefinition WithVirtualFilePath( [NotNull] this TemplateDefinition templateDefinition, [NotNull] string virtualPath) @@ -22,5 +17,15 @@ namespace Volo.Abp.TextTemplating virtualPath ); } + + public static string GetVirtualFilePathOrNull( + [NotNull] this TemplateDefinition templateDefinition) + { + Check.NotNull(templateDefinition, nameof(templateDefinition)); + + return templateDefinition + .Properties + .GetOrDefault(VirtualFileTemplateContentContributor.VirtualPathPropertyName) as string; + } } } diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionManager.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionManager.cs index 28909330fe..11081f6dff 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionManager.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinitionManager.cs @@ -5,6 +5,7 @@ using System.Linq; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; using Volo.Abp.DependencyInjection; +using Volo.Abp.VirtualFileSystem; namespace Volo.Abp.TextTemplating { @@ -78,9 +79,38 @@ namespace Volo.Abp.TextTemplating { provider.PostDefine(context); } + + SetIsInlineLocalized( + templates, + scope.ServiceProvider + ); } return templates; } + + protected virtual void SetIsInlineLocalized( + Dictionary templates, + IServiceProvider serviceProvider) + { + var virtualFileProvider = serviceProvider.GetRequiredService(); + + foreach (var templateDefinition in templates.Values) + { + var virtualPath = templateDefinition.GetVirtualFilePathOrNull(); + if (virtualPath == null) + { + continue; + } + + var fileInfo = virtualFileProvider.GetFileInfo(virtualPath); + if (!fileInfo.Exists) + { + throw new AbpException("Could not find a file/folder at the location: " + virtualPath); + } + + templateDefinition.IsInlineLocalized = !fileInfo.IsDirectory; + } + } } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/LocalizedTemplateContentReaderFactory.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/LocalizedTemplateContentReaderFactory.cs index f4f8384777..b30e5771f4 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/LocalizedTemplateContentReaderFactory.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/LocalizedTemplateContentReaderFactory.cs @@ -1,5 +1,4 @@ using System; -using System.Collections.Concurrent; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; @@ -55,10 +54,7 @@ namespace Volo.Abp.TextTemplating.VirtualFiles protected virtual async Task CreateInternalAsync( TemplateDefinition templateDefinition) { - var virtualPath = templateDefinition - .Properties - .GetOrDefault(VirtualFileTemplateContentContributor.VirtualPathPropertyName) as string; - + var virtualPath = templateDefinition.GetVirtualFilePathOrNull(); if (virtualPath == null) { return NullLocalizedTemplateContentReader.Instance; 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 b711860089..51c78cc13e 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,13 @@ namespace Volo.Abp.TextTemplating [Fact] public void Should_Retrieve_Template_Definition_By_Name() { - var definition = _templateDefinitionManager.Get(TestTemplates.WelcomeEmail); - definition.Name.ShouldBe(TestTemplates.WelcomeEmail); + var welcomeEmailTemplate = _templateDefinitionManager.Get(TestTemplates.WelcomeEmail); + welcomeEmailTemplate.Name.ShouldBe(TestTemplates.WelcomeEmail); + welcomeEmailTemplate.IsInlineLocalized.ShouldBeFalse(); + + var forgotPasswordEmailTemplate = _templateDefinitionManager.Get(TestTemplates.ForgotPasswordEmail); + forgotPasswordEmailTemplate.Name.ShouldBe(TestTemplates.ForgotPasswordEmail); + forgotPasswordEmailTemplate.IsInlineLocalized.ShouldBeTrue(); } [Fact] From 12bde17d6688bdfb43dce016199267956764e777 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Wed, 29 Apr 2020 13:56:25 +0300 Subject: [PATCH 32/35] Revisit getting template content --- .../TemplateContentContributorContext.cs | 6 +- .../TextTemplating/TemplateContentProvider.cs | 62 +++++++++++++++---- .../Abp/TextTemplating/TemplateDefinition.cs | 2 +- .../Abp/TextTemplating/TemplateRenderer.cs | 21 +++++-- .../FileInfoLocalizedTemplateContentReader.cs | 7 ++- .../ILocalizedTemplateContentReader.cs | 6 +- .../VirtualFileTemplateContentContributor.cs | 3 +- ...ualFolderLocalizedTemplateContentReader.cs | 5 ++ 8 files changed, 86 insertions(+), 26 deletions(-) diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentContributorContext.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentContributorContext.cs index bb304a3344..773bf1a0a4 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentContributorContext.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentContributorContext.cs @@ -11,17 +11,17 @@ namespace Volo.Abp.TextTemplating [NotNull] public IServiceProvider ServiceProvider { get; } - [NotNull] + [CanBeNull] public string Culture { get; } public TemplateContentContributorContext( [NotNull] TemplateDefinition templateDefinition, [NotNull] IServiceProvider serviceProvider, - [NotNull] string culture) + [CanBeNull] string culture) { TemplateDefinition = Check.NotNull(templateDefinition, nameof(templateDefinition)); ServiceProvider = Check.NotNull(serviceProvider, nameof(serviceProvider)); - Culture = Check.NotNull(culture, nameof(culture)); + Culture = culture; } } } \ 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 index dcb5d88850..2e9c7af269 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentProvider.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentProvider.cs @@ -47,14 +47,12 @@ namespace Volo.Abp.TextTemplating $"No template content contributor was registered. Use {nameof(AbpTextTemplatingOptions)} to register contributors!" ); } - - if (cultureName == null) - { - cultureName = CultureInfo.CurrentUICulture.Name; - } - + using (var scope = ServiceScopeFactory.CreateScope()) { + var searchCultureName = cultureName ?? + CultureInfo.CurrentUICulture.Name; + var contributors = Options.ContentContributors .Select(type => (ITemplateContentContributor) scope.ServiceProvider.GetRequiredService(type)) .Reverse() @@ -66,7 +64,7 @@ namespace Volo.Abp.TextTemplating new TemplateContentContributorContext( templateDefinition, scope.ServiceProvider, - cultureName + searchCultureName ) ); @@ -77,18 +75,36 @@ namespace Volo.Abp.TextTemplating if (!tryDefaults) { + if (templateDefinition.IsInlineLocalized && cultureName == null) + { + //Try to get culture independent content + templateString = await GetContentOrNullAsync( + contributors, + new TemplateContentContributorContext( + templateDefinition, + scope.ServiceProvider, + null + ) + ); + + if (templateString != null) + { + return templateString; + } + } + return null; } //Try to get from same culture without country code - if (cultureName.Contains("-")) //Example: "tr-TR" + if (searchCultureName.Contains("-")) //Example: "tr-TR" { templateString = await GetContentOrNullAsync( contributors, new TemplateContentContributorContext( templateDefinition, scope.ServiceProvider, - CultureHelper.GetBaseCultureName(cultureName) + CultureHelper.GetBaseCultureName(searchCultureName) ) ); @@ -97,16 +113,16 @@ namespace Volo.Abp.TextTemplating return templateString; } } - - //Try to get from default culture - if (templateDefinition.DefaultCultureName != null) + + if (templateDefinition.IsInlineLocalized) { + //Try to get culture independent content templateString = await GetContentOrNullAsync( contributors, new TemplateContentContributorContext( templateDefinition, scope.ServiceProvider, - templateDefinition.DefaultCultureName + null ) ); @@ -115,6 +131,26 @@ namespace Volo.Abp.TextTemplating return templateString; } } + else + { + //Try to get from default culture + if (templateDefinition.DefaultCultureName != null) + { + templateString = await GetContentOrNullAsync( + contributors, + new TemplateContentContributorContext( + templateDefinition, + scope.ServiceProvider, + templateDefinition.DefaultCultureName + ) + ); + + if (templateString != null) + { + return templateString; + } + } + } } //Not found diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinition.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinition.cs index f3b31a769d..769b970733 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinition.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinition.cs @@ -17,7 +17,7 @@ namespace Volo.Abp.TextTemplating [CanBeNull] public Type LocalizationResource { get; set; } - public bool IsInlineLocalized { get; internal set; } + public bool IsInlineLocalized { get; set; } [CanBeNull] public string DefaultCultureName { get; } 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 8b67a380f0..6a1fff00ef 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateRenderer.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateRenderer.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Globalization; using System.Threading.Tasks; using JetBrains.Annotations; using Microsoft.Extensions.Localization; @@ -35,16 +34,30 @@ namespace Volo.Abp.TextTemplating { Check.NotNullOrWhiteSpace(templateName, nameof(templateName)); - cultureName ??= CultureInfo.CurrentUICulture.Name; + if (globalContext == null) + { + globalContext = new Dictionary(); + } - using (CultureHelper.Use(cultureName)) + if (cultureName == null) { return await RenderInternalAsync( templateName, - globalContext ?? new Dictionary(), + globalContext, model ); } + else + { + using (CultureHelper.Use(cultureName)) + { + return await RenderInternalAsync( + templateName, + globalContext, + model + ); + } + } } protected virtual async Task RenderInternalAsync( diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/FileInfoLocalizedTemplateContentReader.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/FileInfoLocalizedTemplateContentReader.cs index 3ddfb973f3..cde913f307 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/FileInfoLocalizedTemplateContentReader.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/FileInfoLocalizedTemplateContentReader.cs @@ -14,7 +14,12 @@ namespace Volo.Abp.TextTemplating.VirtualFiles public string GetContentOrNull(string culture) { - return _content; + if (culture == null) + { + return _content; + } + + return null; } } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/ILocalizedTemplateContentReader.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/ILocalizedTemplateContentReader.cs index 611e50b005..7d837d731d 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/ILocalizedTemplateContentReader.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/ILocalizedTemplateContentReader.cs @@ -1,7 +1,9 @@ -namespace Volo.Abp.TextTemplating.VirtualFiles +using JetBrains.Annotations; + +namespace Volo.Abp.TextTemplating.VirtualFiles { public interface ILocalizedTemplateContentReader { - public string GetContentOrNull(string culture); + public string GetContentOrNull([CanBeNull] string culture); } } \ No newline at end of file diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContentContributor.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContentContributor.cs index 668d1dc3ec..ede33a3652 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContentContributor.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFileTemplateContentContributor.cs @@ -1,5 +1,4 @@ -using System.Globalization; -using System.Threading.Tasks; +using System.Threading.Tasks; using Volo.Abp.DependencyInjection; namespace Volo.Abp.TextTemplating.VirtualFiles diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFolderLocalizedTemplateContentReader.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFolderLocalizedTemplateContentReader.cs index b43ab722b7..638a7db190 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFolderLocalizedTemplateContentReader.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/VirtualFiles/VirtualFolderLocalizedTemplateContentReader.cs @@ -35,6 +35,11 @@ namespace Volo.Abp.TextTemplating.VirtualFiles public string GetContentOrNull(string cultureName) { + if (cultureName == null) + { + return null; + } + return _dictionary.GetOrDefault(cultureName); } } From c71550b98ccdff528761ac69df22ce6aad68f5ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Wed, 29 Apr 2020 14:16:55 +0300 Subject: [PATCH 33/35] Add useCurrentCultureIfCultureNameIsNull option. --- .../ITemplateContentProvider.cs | 6 +- .../TextTemplating/TemplateContentProvider.cs | 83 +++++++++---------- 2 files changed, 44 insertions(+), 45 deletions(-) diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateContentProvider.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateContentProvider.cs index b352fc0503..19248dc161 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateContentProvider.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/ITemplateContentProvider.cs @@ -8,13 +8,15 @@ namespace Volo.Abp.TextTemplating Task GetContentOrNullAsync( [NotNull] string templateName, [CanBeNull] string cultureName = null, - bool tryDefaults = true + bool tryDefaults = true, + bool useCurrentCultureIfCultureNameIsNull = true ); Task GetContentOrNullAsync( [NotNull] TemplateDefinition templateDefinition, [CanBeNull] string cultureName = null, - bool tryDefaults = true + bool tryDefaults = true, + bool useCurrentCultureIfCultureNameIsNull = true ); } } \ 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 index 2e9c7af269..8710068bca 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentProvider.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentProvider.cs @@ -1,4 +1,5 @@ -using System.Globalization; +using System; +using System.Globalization; using System.Linq; using System.Threading.Tasks; using JetBrains.Annotations; @@ -26,9 +27,10 @@ namespace Volo.Abp.TextTemplating } public virtual Task GetContentOrNullAsync( - [NotNull] string templateName, + [NotNull] string templateName, [CanBeNull] string cultureName = null, - bool tryDefaults = true) + bool tryDefaults = true, + bool useCurrentCultureIfCultureNameIsNull = true) { var template = _templateDefinitionManager.Get(templateName); return GetContentOrNullAsync(template, cultureName); @@ -37,7 +39,8 @@ namespace Volo.Abp.TextTemplating public virtual async Task GetContentOrNullAsync( [NotNull] TemplateDefinition templateDefinition, [CanBeNull] string cultureName = null, - bool tryDefaults = true) + bool tryDefaults = true, + bool useCurrentCultureIfCultureNameIsNull = true) { Check.NotNull(templateDefinition, nameof(templateDefinition)); @@ -47,64 +50,50 @@ namespace Volo.Abp.TextTemplating $"No template content contributor was registered. Use {nameof(AbpTextTemplatingOptions)} to register contributors!" ); } - + using (var scope = ServiceScopeFactory.CreateScope()) { - var searchCultureName = cultureName ?? - CultureInfo.CurrentUICulture.Name; - - var contributors = Options.ContentContributors - .Select(type => (ITemplateContentContributor) scope.ServiceProvider.GetRequiredService(type)) - .Reverse() - .ToArray(); - - //Try to get from the requested culture - var templateString = await GetContentOrNullAsync( - contributors, - new TemplateContentContributorContext( - templateDefinition, - scope.ServiceProvider, - searchCultureName - ) - ); + string templateString = null; - if (templateString != null) + if (cultureName == null && useCurrentCultureIfCultureNameIsNull) { - return templateString; + cultureName = CultureInfo.CurrentUICulture.Name; } - if (!tryDefaults) + var contributors = CreateTemplateContentContributors(scope.ServiceProvider); + + //Try to get from the requested culture + if (cultureName != null) { - if (templateDefinition.IsInlineLocalized && cultureName == null) - { - //Try to get culture independent content - templateString = await GetContentOrNullAsync( - contributors, - new TemplateContentContributorContext( - templateDefinition, - scope.ServiceProvider, - null - ) - ); + templateString = await GetContentOrNullAsync( + contributors, + new TemplateContentContributorContext( + templateDefinition, + scope.ServiceProvider, + cultureName + ) + ); - if (templateString != null) - { - return templateString; - } + if (templateString != null) + { + return templateString; } + } + if (!tryDefaults) + { return null; } //Try to get from same culture without country code - if (searchCultureName.Contains("-")) //Example: "tr-TR" + if (cultureName != null && cultureName.Contains("-")) //Example: "tr-TR" { templateString = await GetContentOrNullAsync( contributors, new TemplateContentContributorContext( templateDefinition, scope.ServiceProvider, - CultureHelper.GetBaseCultureName(searchCultureName) + CultureHelper.GetBaseCultureName(cultureName) ) ); @@ -113,7 +102,7 @@ namespace Volo.Abp.TextTemplating return templateString; } } - + if (templateDefinition.IsInlineLocalized) { //Try to get culture independent content @@ -157,6 +146,14 @@ namespace Volo.Abp.TextTemplating return null; } + protected virtual ITemplateContentContributor[] CreateTemplateContentContributors(IServiceProvider serviceProvider) + { + return Options.ContentContributors + .Select(type => (ITemplateContentContributor)serviceProvider.GetRequiredService(type)) + .Reverse() + .ToArray(); + } + protected virtual async Task GetContentOrNullAsync( ITemplateContentContributor[] contributors, TemplateContentContributorContext context) From c10f97c1d1ff3c480599f7efd11b04cc3d25556a Mon Sep 17 00:00:00 2001 From: Ahmet Date: Wed, 29 Apr 2020 17:02:08 +0300 Subject: [PATCH 34/35] TemplateDefinition DisplayName added --- .../Volo.Abp.TextTemplating.csproj | 1 + .../TextTemplating/AbpTextTemplatingModule.cs | 4 ++- .../TextTemplating/TemplateContentProvider.cs | 25 ++++++++----------- .../Abp/TextTemplating/TemplateDefinition.cs | 25 ++++++++++++++++--- 4 files changed, 36 insertions(+), 19 deletions(-) diff --git a/framework/src/Volo.Abp.TextTemplating/Volo.Abp.TextTemplating.csproj b/framework/src/Volo.Abp.TextTemplating/Volo.Abp.TextTemplating.csproj index 404259ae17..7bcc0400b5 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo.Abp.TextTemplating.csproj +++ b/framework/src/Volo.Abp.TextTemplating/Volo.Abp.TextTemplating.csproj @@ -19,6 +19,7 @@ + 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 aca0ac8f53..8d76391829 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/AbpTextTemplatingModule.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/AbpTextTemplatingModule.cs @@ -1,13 +1,15 @@ using System; using System.Collections.Generic; using Microsoft.Extensions.DependencyInjection; +using Volo.Abp.Localization; using Volo.Abp.Modularity; using Volo.Abp.VirtualFileSystem; namespace Volo.Abp.TextTemplating { [DependsOn( - typeof(AbpVirtualFileSystemModule) + typeof(AbpVirtualFileSystemModule), + typeof(AbpLocalizationAbstractionsModule) )] public class AbpTextTemplatingModule : AbpModule { diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentProvider.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentProvider.cs index 8710068bca..55a3979e21 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentProvider.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateContentProvider.cs @@ -63,21 +63,18 @@ namespace Volo.Abp.TextTemplating var contributors = CreateTemplateContentContributors(scope.ServiceProvider); //Try to get from the requested culture - if (cultureName != null) - { - templateString = await GetContentOrNullAsync( - contributors, - new TemplateContentContributorContext( - templateDefinition, - scope.ServiceProvider, - cultureName - ) - ); + templateString = await GetContentOrNullAsync( + contributors, + new TemplateContentContributorContext( + templateDefinition, + scope.ServiceProvider, + cultureName + ) + ); - if (templateString != null) - { - return templateString; - } + if (templateString != null) + { + return templateString; } if (!tryDefaults) diff --git a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinition.cs b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinition.cs index 769b970733..db2ccf6f63 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinition.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateDefinition.cs @@ -1,14 +1,29 @@ using System; using System.Collections.Generic; using JetBrains.Annotations; +using Volo.Abp.Localization; namespace Volo.Abp.TextTemplating { public class TemplateDefinition { + public const int MaxNameLength = 128; + [NotNull] public string Name { get; } + [NotNull] + public ILocalizableString DisplayName + { + get => _displayName; + set + { + Check.NotNull(value, nameof(value)); + _displayName = value; + } + } + private ILocalizableString _displayName; + public bool IsLayout { get; } [CanBeNull] @@ -44,14 +59,16 @@ namespace Volo.Abp.TextTemplating public Dictionary Properties { get; } public TemplateDefinition( - [NotNull] string name, - [CanBeNull] Type localizationResource = null, + [NotNull] string name, + [CanBeNull] Type localizationResource = null, + [CanBeNull] ILocalizableString displayName = null, bool isLayout = false, - string layout = null, + string layout = null, string defaultCultureName = null) { - Name = Check.NotNullOrWhiteSpace(name, nameof(name)); + Name = Check.NotNullOrWhiteSpace(name, nameof(name), MaxNameLength); LocalizationResource = localizationResource; + DisplayName = displayName ?? new FixedLocalizableString(Name); IsLayout = isLayout; Layout = layout; DefaultCultureName = defaultCultureName; From 092d2dc5cf4dc7b887336ecbacec341b762224d2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Halil=20=C4=B0brahim=20Kalkan?= Date: Thu, 30 Apr 2020 18:31:03 +0300 Subject: [PATCH 35/35] Use L instead of l on text templates --- .../Volo/Abp/Emailing/Templates/Message/en.tpl | 2 +- .../Volo/Abp/TextTemplating/TemplateRenderer.cs | 2 +- .../Abp/TextTemplating/SampleTemplates/ForgotPasswordEmail.tpl | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/Message/en.tpl b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/Message/en.tpl index 6454b0b93a..349de66b36 100644 --- a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/Message/en.tpl +++ b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/Message/en.tpl @@ -1 +1 @@ -{{message}} \ No newline at end of file +{{model.message}} \ 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 index 6a1fff00ef..f51e8447b0 100644 --- a/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateRenderer.cs +++ b/framework/src/Volo.Abp.TextTemplating/Volo/Abp/TextTemplating/TemplateRenderer.cs @@ -140,7 +140,7 @@ namespace Volo.Abp.TextTemplating { var localizer = _stringLocalizerFactory.Create(templateDefinition.LocalizationResource); scriptObject.Import( - "l", + "L", new Func( name => localizer[name] ) 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 7d844c6f7c..8bcab86d0f 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"}}. Please click to the following link to get an email to reset your password! \ No newline at end of file