diff --git a/framework/src/Volo.Abp.Emailing/Volo.Abp.Emailing.csproj b/framework/src/Volo.Abp.Emailing/Volo.Abp.Emailing.csproj
index ab1b4ed370..b2394ea229 100644
--- a/framework/src/Volo.Abp.Emailing/Volo.Abp.Emailing.csproj
+++ b/framework/src/Volo.Abp.Emailing/Volo.Abp.Emailing.csproj
@@ -14,8 +14,12 @@
-
-
+
+
+
+
+
+
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 b861a3898c..d3a9598da1 100644
--- a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/AbpEmailingModule.cs
+++ b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/AbpEmailingModule.cs
@@ -1,6 +1,8 @@
-using Volo.Abp.BackgroundJobs;
+using System;
+using System.Collections.Generic;
+using Microsoft.Extensions.DependencyInjection;
+using Volo.Abp.BackgroundJobs;
using Volo.Abp.Emailing.Templates;
-using Volo.Abp.Emailing.Templates.Virtual;
using Volo.Abp.Localization;
using Volo.Abp.Modularity;
using Volo.Abp.Settings;
@@ -16,6 +18,11 @@ namespace Volo.Abp.Emailing
)]
public class AbpEmailingModule : AbpModule
{
+ public override void PreConfigureServices(ServiceConfigurationContext context)
+ {
+ AutoAddDefinitionProviders(context.Services);
+ }
+
public override void ConfigureServices(ServiceConfigurationContext context)
{
Configure(options =>
@@ -27,18 +34,42 @@ namespace Volo.Abp.Emailing
{
options.AddJob();
});
+ }
- Configure(options =>
+ private static void AutoAddDefinitionProviders(IServiceCollection services)
+ {
+ var definitionProviders = new List();
+
+ services.OnRegistred(context =>
{
- options.Templates
- .Add(
- new EmailTemplateDefinition(StandardEmailTemplates.DefaultLayout, isLayout: true, layout: null)
- .SetVirtualFilePath("/Volo/Abp/Emailing/Templates/DefaultLayout.html")
- ).Add(
- new EmailTemplateDefinition(StandardEmailTemplates.SimpleMessage)
- .SetVirtualFilePath("/Volo/Abp/Emailing/Templates/SimpleMessageTemplate.html")
- );
+
+ 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/DefaultEmailTemplateProvider.cs b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/DefaultEmailTemplateProvider.cs
new file mode 100644
index 0000000000..fdc7fa5375
--- /dev/null
+++ b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/DefaultEmailTemplateProvider.cs
@@ -0,0 +1,16 @@
+using Volo.Abp.Emailing.Templates.VirtualFiles;
+
+namespace Volo.Abp.Emailing.Templates
+{
+ public class DefaultEmailTemplateProvider : EmailTemplateDefinitionProvider
+ {
+ public override void Define(IEmailTemplateDefinitionContext context)
+ {
+ context.Add(new EmailTemplateDefinition(StandardEmailTemplates.DefaultLayout, isLayout: true, layout: null)
+ .AddTemplateVirtualFiles("/Volo/Abp/Emailing/Templates/DefaultEmailTemplates/Layout"));
+
+ context.Add(new EmailTemplateDefinition(StandardEmailTemplates.SimpleMessage)
+ .AddTemplateVirtualFiles("/Volo/Abp/Emailing/Templates/DefaultEmailTemplates/Message"));
+ }
+ }
+}
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/DefaultLayout.html b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/DefaultEmailTemplates/Layout/en.tpl
similarity index 100%
rename from framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/DefaultLayout.html
rename to framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/DefaultEmailTemplates/Layout/en.tpl
diff --git a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/SimpleMessageTemplate.html b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/DefaultEmailTemplates/Message/en.tpl
similarity index 100%
rename from framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/SimpleMessageTemplate.html
rename to framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/DefaultEmailTemplates/Message/en.tpl
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
new file mode 100644
index 0000000000..44a91212ea
--- /dev/null
+++ b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/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.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateDefinition.cs b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateDefinition.cs
index 9ef2ae3b1b..19f0eb2fa7 100644
--- a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateDefinition.cs
+++ b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateDefinition.cs
@@ -1,5 +1,4 @@
using System;
-using System.Collections.Generic;
using JetBrains.Annotations;
namespace Volo.Abp.Emailing.Templates
@@ -16,29 +15,22 @@ namespace Volo.Abp.Emailing.Templates
public Type LocalizationResource { get; set; }
- public Dictionary Properties { 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.
- ///
- public object this[string name]
- {
- get => Properties.GetOrDefault(name);
- set => Properties[name] = value;
- }
+ 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)
+ 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));
- Properties = new Dictionary();
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
new file mode 100644
index 0000000000..03a6c95d8b
--- /dev/null
+++ b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateDefinitionContext.cs
@@ -0,0 +1,38 @@
+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/EmailTemplateDefinitionManager.cs b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateDefinitionManager.cs
new file mode 100644
index 0000000000..a6a58aef27
--- /dev/null
+++ b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateDefinitionManager.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.Emailing.Templates
+{
+ public class EmailTemplateDefinitionManager : IEmailTemplateDefinitionManager, ISingletonDependency
+ {
+ protected Lazy> EmailTemplateDefinitions { get; }
+
+ protected EmailTemplateOptions 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
new file mode 100644
index 0000000000..e53505fafc
--- /dev/null
+++ b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateDefinitionProvider.cs
@@ -0,0 +1,9 @@
+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
new file mode 100644
index 0000000000..8cd4b95bbd
--- /dev/null
+++ b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/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.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateOptions.cs b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateOptions.cs
index 6d10bd562e..57533b1aff 100644
--- a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateOptions.cs
+++ b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateOptions.cs
@@ -1,26 +1,18 @@
-using System.Collections.Generic;
-using Volo.Abp.Emailing.Templates.Virtual;
+using Volo.Abp.Collections;
namespace Volo.Abp.Emailing.Templates
{
public class EmailTemplateOptions
{
- public List Providers { get; }
-
- public EmailTemplateDefinitionDictionary Templates { get; }
-
public string DefaultLayout { get; set; }
+ public ITypeList DefinitionProviders { get; }
+
public EmailTemplateOptions()
{
- Providers = new List
- {
- new VirtualFileEmailTemplateProviderContributor()
- };
-
- Templates = new EmailTemplateDefinitionDictionary();
-
DefaultLayout = StandardEmailTemplates.DefaultLayout;
+
+ DefinitionProviders = new TypeList();
}
}
}
\ 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
index c5fb44e0ed..28abdfc213 100644
--- a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateProvider.cs
+++ b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateProvider.cs
@@ -1,6 +1,6 @@
using System;
+using System.Globalization;
using System.Threading.Tasks;
-using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Localization;
using Microsoft.Extensions.Options;
using Volo.Abp.DependencyInjection;
@@ -10,80 +10,105 @@ namespace Volo.Abp.Emailing.Templates
{
public class EmailTemplateProvider : IEmailTemplateProvider, ITransientDependency
{
- protected IServiceProvider ServiceProvider { get; }
+ protected IEmailTemplateDefinitionManager EmailTemplateDefinitionManager;
protected ITemplateLocalizer TemplateLocalizer { get; }
protected EmailTemplateOptions Options { get; }
+ protected IStringLocalizerFactory StringLocalizerFactory;
- public EmailTemplateProvider(
- IOptions options,
- IServiceProvider serviceProvider,
- ITemplateLocalizer templateLocalizer)
+ public EmailTemplateProvider(IEmailTemplateDefinitionManager emailTemplateDefinitionManager,
+ ITemplateLocalizer templateLocalizer, IStringLocalizerFactory stringLocalizerFactory,
+ IOptions options)
{
- ServiceProvider = serviceProvider;
+ EmailTemplateDefinitionManager = emailTemplateDefinitionManager;
TemplateLocalizer = templateLocalizer;
+ StringLocalizerFactory = stringLocalizerFactory;
Options = options.Value;
}
- public async Task GetAsync(string name)
+ public async Task GetAsync(string name, string cultureName)
{
- using (var scope = ServiceProvider.CreateScope())
- {
- return await GetInternalAsync(scope.ServiceProvider, name);
- }
+ return await GetInternalAsync(name, cultureName);
}
- protected virtual async Task GetInternalAsync(IServiceProvider serviceProvider, string name)
+ protected virtual async Task GetInternalAsync(string name, string cultureName)
{
- var context = new EmailTemplateProviderContributorContext(name, serviceProvider);
+ var emailTemplateDefinition = EmailTemplateDefinitionManager.GetOrNull(name);
+ if (emailTemplateDefinition == null)
+ {
+ // TODO: Localized message
+ throw new AbpException($"email template {name} not definition");
+ }
- foreach (var provider in Options.Providers)
+ var emailTemplateString = emailTemplateDefinition.Contributors.GetOrNull(cultureName);
+ if (emailTemplateString == null && emailTemplateDefinition.DefaultCultureName != null)
{
- await provider.ProvideAsync(context);
+ emailTemplateString =
+ emailTemplateDefinition.Contributors.GetOrNull(emailTemplateDefinition.DefaultCultureName);
+ if (emailTemplateString != null)
+ {
+ cultureName = emailTemplateDefinition.DefaultCultureName;
+ }
}
- if (context.Template == null)
+ if (emailTemplateString != null)
{
- throw new AbpException($"Could not found the template: {name}");
+ var emailTemplate = new EmailTemplate(emailTemplateString, emailTemplateDefinition);
+
+ await SetLayoutAsync(emailTemplateDefinition, emailTemplate, cultureName);
+
+ if (emailTemplateDefinition.SingleTemplateFile)
+ {
+ await LocalizeAsync(emailTemplateDefinition, emailTemplate, cultureName);
+ }
+
+ return emailTemplate;
}
- await SetLayoutAsync(serviceProvider, context);
- await LocalizeAsync(serviceProvider, context);
-
- return context.Template;
+ // TODO: Localized message
+ throw new AbpException($"{cultureName} template not exist!");
}
- protected virtual async Task SetLayoutAsync(IServiceProvider serviceProvider, EmailTemplateProviderContributorContext context)
+ protected virtual async Task SetLayoutAsync(EmailTemplateDefinition emailTemplateDefinition,
+ EmailTemplate emailTemplate, string cultureName)
{
- var layout = context.Template.Definition.Layout;
-
- if (layout.IsNullOrEmpty())
+ var layout = emailTemplateDefinition.Layout;
+ if (layout.IsNullOrWhiteSpace())
{
return;
}
-
+
if (layout == EmailTemplateDefinition.DefaultLayoutPlaceHolder)
{
layout = Options.DefaultLayout;
}
- var layoutTemplate = await GetInternalAsync(serviceProvider, layout);
- context.Template.SetLayout(layoutTemplate);
+ var layoutTemplate = await GetInternalAsync(layout, cultureName);
+
+ emailTemplate.SetLayout(layoutTemplate);
}
- protected virtual Task LocalizeAsync(IServiceProvider serviceProvider, EmailTemplateProviderContributorContext context)
+ protected virtual Task LocalizeAsync(EmailTemplateDefinition emailTemplateDefinition,
+ EmailTemplate emailTemplate, string cultureName)
{
- if (context.Template.Definition.LocalizationResource == null)
+ if (emailTemplateDefinition.LocalizationResource == null)
{
return Task.CompletedTask;
}
- var localizer = serviceProvider
- .GetRequiredService()
- .Create(context.Template.Definition.LocalizationResource);
-
- context.Template.SetContent(
- TemplateLocalizer.Localize(localizer, context.Template.Content)
- );
+ var localizer = StringLocalizerFactory.Create(emailTemplateDefinition.LocalizationResource);
+ if (cultureName != null)
+ {
+ emailTemplate.SetContent(
+ TemplateLocalizer.Localize(localizer.WithCulture(new CultureInfo(cultureName)),
+ emailTemplate.Content)
+ );
+ }
+ else
+ {
+ emailTemplate.SetContent(
+ TemplateLocalizer.Localize(localizer, emailTemplate.Content)
+ );
+ }
return Task.CompletedTask;
}
diff --git a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateProviderContributorContext.cs b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateProviderContributorContext.cs
deleted file mode 100644
index 9893ddc789..0000000000
--- a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/EmailTemplateProviderContributorContext.cs
+++ /dev/null
@@ -1,20 +0,0 @@
-using System;
-using Volo.Abp.DependencyInjection;
-
-namespace Volo.Abp.Emailing.Templates
-{
- public class EmailTemplateProviderContributorContext : IServiceProviderAccessor
- {
- public string Name { get; }
-
- public IServiceProvider ServiceProvider { get; }
-
- public EmailTemplate Template { get; set; }
-
- public EmailTemplateProviderContributorContext(string name, IServiceProvider serviceProvider)
- {
- Name = name;
- ServiceProvider = serviceProvider;
- }
- }
-}
\ 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
new file mode 100644
index 0000000000..d2c2775845
--- /dev/null
+++ b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/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/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/IEmailTemplateDefinitionContext.cs b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/IEmailTemplateDefinitionContext.cs
new file mode 100644
index 0000000000..1641562ccf
--- /dev/null
+++ b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/IEmailTemplateDefinitionContext.cs
@@ -0,0 +1,9 @@
+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
new file mode 100644
index 0000000000..0936a2fe93
--- /dev/null
+++ b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/IEmailTemplateDefinitionManager.cs
@@ -0,0 +1,15 @@
+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
new file mode 100644
index 0000000000..691d3874d6
--- /dev/null
+++ b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/IEmailTemplateDefinitionProvider.cs
@@ -0,0 +1,7 @@
+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
index aad1fe4f05..4fc8381833 100644
--- a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/IEmailTemplateProvider.cs
+++ b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/IEmailTemplateProvider.cs
@@ -4,6 +4,6 @@ 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/IEmailTemplateProviderContributor.cs b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/IEmailTemplateProviderContributor.cs
deleted file mode 100644
index 6bc63f9661..0000000000
--- a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/IEmailTemplateProviderContributor.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-using System.Threading.Tasks;
-
-namespace Volo.Abp.Emailing.Templates
-{
- public interface IEmailTemplateProviderContributor
- {
- Task ProvideAsync(EmailTemplateProviderContributorContext contributorContext);
- }
-}
\ 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
new file mode 100644
index 0000000000..35ac14c8fd
--- /dev/null
+++ b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/ITemplateRender.cs
@@ -0,0 +1,9 @@
+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
new file mode 100644
index 0000000000..8c4e24017c
--- /dev/null
+++ b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/TemplateRender.cs
@@ -0,0 +1,15 @@
+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/Virtual/EmailTemplateDefinitionExtensions.cs b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/Virtual/EmailTemplateDefinitionExtensions.cs
deleted file mode 100644
index cb49491b0f..0000000000
--- a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/Virtual/EmailTemplateDefinitionExtensions.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-namespace Volo.Abp.Emailing.Templates.Virtual
-{
- public static class EmailTemplateDefinitionExtensions
- {
- public static EmailTemplateDefinition SetVirtualFilePath(this EmailTemplateDefinition emailTemplateDefinition, string path)
- {
- emailTemplateDefinition[VirtualFileEmailTemplateProviderContributor.VirtualFilePathKey] = path;
- return emailTemplateDefinition;
- }
-
- public static string GetVirtualFilePathOrNull(this EmailTemplateDefinition emailTemplateDefinition)
- {
- return emailTemplateDefinition[VirtualFileEmailTemplateProviderContributor.VirtualFilePathKey] as string;
- }
- }
-}
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/Virtual/VirtualFileEmailTemplateOptions.cs b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/Virtual/VirtualFileEmailTemplateOptions.cs
deleted file mode 100644
index 0103ac27dc..0000000000
--- a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/Virtual/VirtualFileEmailTemplateOptions.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-using System.Collections.Generic;
-
-namespace Volo.Abp.Emailing.Templates.Virtual
-{
- public class VirtualFileEmailTemplateOptions
- {
- public IDictionary Templates { get; }
-
- public VirtualFileEmailTemplateOptions()
- {
- Templates = new Dictionary();
- }
- }
-}
\ No newline at end of file
diff --git a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/Virtual/VirtualFileEmailTemplateProviderContributor.cs b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/Virtual/VirtualFileEmailTemplateProviderContributor.cs
deleted file mode 100644
index d54f4c94cb..0000000000
--- a/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/Virtual/VirtualFileEmailTemplateProviderContributor.cs
+++ /dev/null
@@ -1,61 +0,0 @@
-using System.Collections.Generic;
-using System.Threading.Tasks;
-using Microsoft.Extensions.DependencyInjection;
-using Microsoft.Extensions.FileProviders;
-using Microsoft.Extensions.Options;
-using Volo.Abp.VirtualFileSystem;
-
-namespace Volo.Abp.Emailing.Templates.Virtual
-{
- public class VirtualFileEmailTemplateProviderContributor : IEmailTemplateProviderContributor
- {
- public const string VirtualFilePathKey = "VirtualFilePath";
-
- public Task ProvideAsync(EmailTemplateProviderContributorContext contributorContext)
- {
- var templateDefinition = FindTemplateDefinition(contributorContext);
- if (templateDefinition == null)
- {
- return Task.CompletedTask;
- }
-
- var fileInfo = FindVirtualFileInfo(contributorContext, templateDefinition);
- if (fileInfo == null)
- {
- return Task.CompletedTask;
- }
-
- contributorContext.Template = new EmailTemplate(fileInfo.ReadAsString(), templateDefinition);
- return Task.CompletedTask;
- }
-
- protected virtual EmailTemplateDefinition FindTemplateDefinition(EmailTemplateProviderContributorContext contributorContext)
- {
- return contributorContext
- .ServiceProvider
- .GetRequiredService>()
- .Value
- .Templates
- .GetOrDefault(contributorContext.Name);
- }
-
- protected virtual IFileInfo FindVirtualFileInfo(EmailTemplateProviderContributorContext contributorContext, EmailTemplateDefinition templateDefinition)
- {
- var virtualFilePath = templateDefinition?.GetVirtualFilePathOrNull();
- if (virtualFilePath == null)
- {
- return null;
- }
-
- var virtualFileProvider = contributorContext.ServiceProvider.GetRequiredService();
-
- var fileInfo = virtualFileProvider.GetFileInfo(virtualFilePath);
- if (fileInfo?.Exists != true)
- {
- return null;
- }
-
- return fileInfo;
- }
- }
-}
\ 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
new file mode 100644
index 0000000000..7bee611d28
--- /dev/null
+++ b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/VirtualFiles/EmailTemplateDefinitionExtensions.cs
@@ -0,0 +1,19 @@
+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
new file mode 100644
index 0000000000..2ae5f88cc5
--- /dev/null
+++ b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/VirtualFiles/MultipleVirtualFilesEmailTemplateContributor.cs
@@ -0,0 +1,68 @@
+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
new file mode 100644
index 0000000000..d72d18e99a
--- /dev/null
+++ b/framework/src/Volo.Abp.Emailing/Volo/Abp/Emailing/Templates/VirtualFiles/SingleVirtualFileEmailTemplateContributor.cs
@@ -0,0 +1,34 @@
+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/test/Volo.Abp.Emailing.Tests/Volo.Abp.Emailing.Tests.csproj b/framework/test/Volo.Abp.Emailing.Tests/Volo.Abp.Emailing.Tests.csproj
index 32b4f25816..ca155ab951 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
@@ -11,12 +11,15 @@
-
-
+
+
+
+
+
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 a36c664e8a..831258c5d5 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,5 @@
-using Microsoft.Extensions.DependencyInjection;
-using Volo.Abp.Emailing.Templates;
-using Volo.Abp.Emailing.Templates.Virtual;
+using Volo.Abp.Emailing.Localization;
+using Volo.Abp.Localization;
using Volo.Abp.Modularity;
using Volo.Abp.VirtualFileSystem;
@@ -18,12 +17,13 @@ namespace Volo.Abp.Emailing
options.FileSets.AddEmbedded();
});
- Configure(options =>
+ Configure(options =>
{
- options.Templates["template1"] =
- new EmailTemplateDefinition("template1")
- .SetVirtualFilePath("/Volo/Abp/Emailing/TestTemplates/template1.html");
+ 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
new file mode 100644
index 0000000000..403aaad0bd
--- /dev/null
+++ b/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/EmailTemplateRender_Tests.cs
@@ -0,0 +1,64 @@
+using System.Collections.Generic;
+using System.Threading.Tasks;
+using Shouldly;
+using Volo.Abp.Emailing.Templates;
+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
index a09fb48ed1..62a2cb3eb6 100644
--- 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
@@ -7,6 +7,11 @@ namespace Volo.Abp.Emailing
{
public class EmailTemplateStore_Tests : AbpIntegratedTest
{
+ protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options)
+ {
+ options.UseAutofac();
+ }
+
private readonly IEmailTemplateProvider _emailTemplateProvider;
public EmailTemplateStore_Tests()
@@ -17,8 +22,31 @@ namespace Volo.Abp.Emailing
[Fact]
public async Task Should_Get_Registered_Template()
{
- var template = await _emailTemplateProvider.GetAsync("template1");
- template.Content.ShouldContain("This is a test 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("\r\n " + "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
new file mode 100644
index 0000000000..bdc75f9f2f
--- /dev/null
+++ b/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/Localization/AbpEmailingTestResource.cs
@@ -0,0 +1,10 @@
+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/en.json b/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/Localization/en.json
new file mode 100644
index 0000000000..38f7cf7e5b
--- /dev/null
+++ b/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/Localization/en.json
@@ -0,0 +1,6 @@
+{
+ "culture": "en",
+ "texts": {
+ "hello": "hello"
+ }
+}
\ 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
new file mode 100644
index 0000000000..6c3c94cfdf
--- /dev/null
+++ b/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/Localization/tr.json
@@ -0,0 +1,6 @@
+{
+ "culture": "tr",
+ "texts": {
+ "hello": "Merhaba"
+ }
+}
\ 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
new file mode 100644
index 0000000000..60c9a2ccf3
--- /dev/null
+++ b/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/TestEmailTemplateProvider.cs
@@ -0,0 +1,24 @@
+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
new file mode 100644
index 0000000000..49a951e8c0
--- /dev/null
+++ b/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/TestTemplates/Template1/en.tpl
@@ -0,0 +1,4 @@
+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
new file mode 100644
index 0000000000..3e572aedbb
--- /dev/null
+++ b/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/TestTemplates/Template1/tr.tpl
@@ -0,0 +1,4 @@
+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
new file mode 100644
index 0000000000..49a951e8c0
--- /dev/null
+++ b/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/TestTemplates/Template2/en.tpl
@@ -0,0 +1,4 @@
+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
new file mode 100644
index 0000000000..f30f512848
--- /dev/null
+++ b/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/TestTemplates/Template3/Template.tpl
@@ -0,0 +1 @@
+{{#L:hello}} Abp
\ No newline at end of file
diff --git a/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/TestTemplates/template1.html b/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/TestTemplates/template1.html
deleted file mode 100644
index 5c98393c69..0000000000
--- a/framework/test/Volo.Abp.Emailing.Tests/Volo/Abp/Emailing/TestTemplates/template1.html
+++ /dev/null
@@ -1,9 +0,0 @@
-
-
-
-
-
-
- This is a test template!
-
-
\ No newline at end of file