mirror of https://github.com/abpframework/abp.git
Browse Source
Supports the use of multiple template rendering engines in one application.pull/8880/head
committed by
GitHub
63 changed files with 383 additions and 103 deletions
@ -0,0 +1,55 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Threading.Tasks; |
||||
|
using Microsoft.Extensions.DependencyInjection; |
||||
|
using Microsoft.Extensions.Options; |
||||
|
using Volo.Abp.DependencyInjection; |
||||
|
|
||||
|
namespace Volo.Abp.TextTemplating |
||||
|
{ |
||||
|
public class AbpTemplateRenderer : ITemplateRenderer, ITransientDependency |
||||
|
{ |
||||
|
protected IServiceScopeFactory ServiceScopeFactory { get; } |
||||
|
protected ITemplateDefinitionManager TemplateDefinitionManager { get; } |
||||
|
protected AbpTextTemplatingOptions Options { get; } |
||||
|
|
||||
|
public AbpTemplateRenderer( |
||||
|
IServiceScopeFactory serviceScopeFactory, |
||||
|
ITemplateDefinitionManager templateDefinitionManager, |
||||
|
IOptions<AbpTextTemplatingOptions> options) |
||||
|
{ |
||||
|
ServiceScopeFactory = serviceScopeFactory; |
||||
|
TemplateDefinitionManager = templateDefinitionManager; |
||||
|
Options = options.Value; |
||||
|
} |
||||
|
|
||||
|
public virtual async Task<string> RenderAsync( |
||||
|
string templateName, |
||||
|
object model = null, |
||||
|
string cultureName = null, |
||||
|
Dictionary<string, object> globalContext = null) |
||||
|
{ |
||||
|
var templateDefinition = TemplateDefinitionManager.Get(templateName); |
||||
|
|
||||
|
var renderEngine = templateDefinition.RenderEngine; |
||||
|
|
||||
|
if (renderEngine.IsNullOrWhiteSpace()) |
||||
|
{ |
||||
|
renderEngine = Options.DefaultRenderingEngine; |
||||
|
} |
||||
|
|
||||
|
var providerType = Options.RenderingEngines.GetOrDefault(renderEngine); |
||||
|
|
||||
|
if (providerType != null && typeof(ITemplateRenderingEngine).IsAssignableFrom(providerType)) |
||||
|
{ |
||||
|
using (var scope = ServiceScopeFactory.CreateScope()) |
||||
|
{ |
||||
|
var templateRenderingEngine = (ITemplateRenderingEngine)scope.ServiceProvider.GetRequiredService(providerType); |
||||
|
return await templateRenderingEngine.RenderAsync(templateName, model, cultureName, globalContext); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
throw new AbpException("There is no rendering engine found with template name: " + templateName); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,27 @@ |
|||||
|
using System.Collections.Generic; |
||||
|
using System.Globalization; |
||||
|
using System.Threading.Tasks; |
||||
|
using JetBrains.Annotations; |
||||
|
|
||||
|
namespace Volo.Abp.TextTemplating |
||||
|
{ |
||||
|
public interface ITemplateRenderingEngine |
||||
|
{ |
||||
|
string Name { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Renders a text template.
|
||||
|
/// </summary>
|
||||
|
/// <param name="templateName">The template name</param>
|
||||
|
/// <param name="model">An optional model object that is used in the template</param>
|
||||
|
/// <param name="cultureName">Culture name. Uses the <see cref="CultureInfo.CurrentUICulture"/> if not specified</param>
|
||||
|
/// <param name="globalContext">A dictionary which can be used to import global objects to the template</param>
|
||||
|
/// <returns></returns>
|
||||
|
Task<string> RenderAsync( |
||||
|
[NotNull] string templateName, |
||||
|
[CanBeNull] object model = null, |
||||
|
[CanBeNull] string cultureName = null, |
||||
|
[CanBeNull] Dictionary<string, object> globalContext = null |
||||
|
); |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,42 @@ |
|||||
|
using System.Collections.Generic; |
||||
|
using System.Threading.Tasks; |
||||
|
using Microsoft.Extensions.Localization; |
||||
|
|
||||
|
namespace Volo.Abp.TextTemplating |
||||
|
{ |
||||
|
public abstract class TemplateRenderingEngineBase : ITemplateRenderingEngine |
||||
|
{ |
||||
|
public abstract string Name { get; } |
||||
|
|
||||
|
protected readonly ITemplateDefinitionManager TemplateDefinitionManager; |
||||
|
protected readonly ITemplateContentProvider TemplateContentProvider; |
||||
|
protected readonly IStringLocalizerFactory StringLocalizerFactory; |
||||
|
|
||||
|
public TemplateRenderingEngineBase( |
||||
|
ITemplateDefinitionManager templateDefinitionManager, |
||||
|
ITemplateContentProvider templateContentProvider, |
||||
|
IStringLocalizerFactory stringLocalizerFactory) |
||||
|
{ |
||||
|
TemplateDefinitionManager = templateDefinitionManager; |
||||
|
TemplateContentProvider = templateContentProvider; |
||||
|
StringLocalizerFactory = stringLocalizerFactory; |
||||
|
} |
||||
|
|
||||
|
public abstract Task<string> RenderAsync(string templateName, object model = null, string cultureName = null, Dictionary<string, object> globalContext = null); |
||||
|
|
||||
|
protected virtual async Task<string> GetContentOrNullAsync(TemplateDefinition templateDefinition) |
||||
|
{ |
||||
|
return await TemplateContentProvider.GetContentOrNullAsync(templateDefinition); |
||||
|
} |
||||
|
|
||||
|
protected virtual IStringLocalizer GetLocalizerOrNull(TemplateDefinition templateDefinition) |
||||
|
{ |
||||
|
if (templateDefinition.LocalizationResource != null) |
||||
|
{ |
||||
|
return StringLocalizerFactory.Create(templateDefinition.LocalizationResource); |
||||
|
} |
||||
|
|
||||
|
return StringLocalizerFactory.CreateDefaultOrNull(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,12 +1,23 @@ |
|||||
using Volo.Abp.Modularity; |
using System; |
||||
|
using Volo.Abp.Modularity; |
||||
|
|
||||
namespace Volo.Abp.TextTemplating.Razor |
namespace Volo.Abp.TextTemplating.Razor |
||||
{ |
{ |
||||
[DependsOn( |
[DependsOn( |
||||
typeof(AbpTextTemplatingAbstractionsModule) |
typeof(AbpTextTemplatingCoreModule) |
||||
)] |
)] |
||||
public class AbpTextTemplatingRazorModule : AbpModule |
public class AbpTextTemplatingRazorModule : AbpModule |
||||
{ |
{ |
||||
|
public override void ConfigureServices(ServiceConfigurationContext context) |
||||
|
{ |
||||
|
Configure<AbpTextTemplatingOptions>(options => |
||||
|
{ |
||||
|
if (options.DefaultRenderingEngine.IsNullOrWhiteSpace()) |
||||
|
{ |
||||
|
options.DefaultRenderingEngine = RazorTemplateRenderingEngine.EngineName; |
||||
|
} |
||||
|
options.RenderingEngines[RazorTemplateRenderingEngine.EngineName] = typeof(RazorTemplateRenderingEngine); |
||||
|
}); |
||||
|
} |
||||
} |
} |
||||
} |
} |
||||
|
|||||
@ -0,0 +1,12 @@ |
|||||
|
using JetBrains.Annotations; |
||||
|
|
||||
|
namespace Volo.Abp.TextTemplating.Razor |
||||
|
{ |
||||
|
public static class RazorTemplateDefinitionExtensions |
||||
|
{ |
||||
|
public static TemplateDefinition WithRazorTemplate([NotNull] this TemplateDefinition templateDefinition) |
||||
|
{ |
||||
|
return templateDefinition.WithRenderEngine(RazorTemplateRenderingEngine.EngineName); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,12 @@ |
|||||
|
using JetBrains.Annotations; |
||||
|
|
||||
|
namespace Volo.Abp.TextTemplating.Scriban |
||||
|
{ |
||||
|
public static class ScribanTemplateDefinitionExtensions |
||||
|
{ |
||||
|
public static TemplateDefinition WithScribanTemplate([NotNull] this TemplateDefinition templateDefinition) |
||||
|
{ |
||||
|
return templateDefinition.WithRenderEngine(ScribanTemplateRenderingEngine.EngineName); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,2 +1,2 @@ |
|||||
@inherits Volo.Abp.TextTemplating.Razor.RazorTemplatePageBase<Volo.Abp.TextTemplating.Razor.RazorTemplateRenderer_Tests.ForgotPasswordEmailModel> |
@inherits Volo.Abp.TextTemplating.Razor.RazorTemplatePageBase<Volo.Abp.TextTemplating.Razor.RazorTemplateRendererProvider_Tests.ForgotPasswordEmailModel> |
||||
@Localizer["HelloText", Model.Name], @Localizer["HowAreYou"]. Please click to the following link to get an email to reset your password! |
@Localizer["HelloText", Model.Name], @Localizer["HowAreYou"]. Please click to the following link to get an email to reset your password! |
||||
@ -1,2 +1,2 @@ |
|||||
@inherits Volo.Abp.TextTemplating.Razor.RazorTemplatePageBase<Volo.Abp.TextTemplating.Razor.RazorTemplateRenderer_Tests.ShowDecimalNumberModel> |
@inherits Volo.Abp.TextTemplating.Razor.RazorTemplatePageBase<Volo.Abp.TextTemplating.Razor.RazorTemplateRendererProvider_Tests.ShowDecimalNumberModel> |
||||
@Model.Amount |
@Model.Amount |
||||
@ -1,2 +1,2 @@ |
|||||
@inherits Volo.Abp.TextTemplating.Razor.RazorTemplatePageBase<Volo.Abp.TextTemplating.Razor.RazorTemplateRenderer_Tests.WelcomeEmailModel> |
@inherits Volo.Abp.TextTemplating.Razor.RazorTemplatePageBase<Volo.Abp.TextTemplating.Razor.RazorTemplateRendererProvider_Tests.WelcomeEmailModel> |
||||
Welcome @Model.Name to the abp.io! |
Welcome @Model.Name to the abp.io! |
||||
@ -1,2 +1,2 @@ |
|||||
@inherits Volo.Abp.TextTemplating.Razor.RazorTemplatePageBase<Volo.Abp.TextTemplating.Razor.RazorTemplateRenderer_Tests.WelcomeEmailModel> |
@inherits Volo.Abp.TextTemplating.Razor.RazorTemplatePageBase<Volo.Abp.TextTemplating.Razor.RazorTemplateRendererProvider_Tests.WelcomeEmailModel> |
||||
Merhaba @Model.Name, abp.io'ya hoşgeldiniz! |
Merhaba @Model.Name, abp.io'ya hoşgeldiniz! |
||||
@ -0,0 +1,46 @@ |
|||||
|
using System.Threading.Tasks; |
||||
|
using Shouldly; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace Volo.Abp.TextTemplating |
||||
|
{ |
||||
|
public class HybridTemplateRendererProvider_Tests : AbpTextTemplatingTestBase<AbpTextTemplatingTestModule> |
||||
|
{ |
||||
|
private readonly ITemplateRenderer _templateRenderer; |
||||
|
|
||||
|
public HybridTemplateRendererProvider_Tests() |
||||
|
{ |
||||
|
_templateRenderer = GetRequiredService<ITemplateRenderer>(); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public async Task Should_Render_By_Scriban() |
||||
|
{ |
||||
|
(await _templateRenderer.RenderAsync( |
||||
|
TestTemplates.HybridTemplateScriban, |
||||
|
model: new |
||||
|
{ |
||||
|
name = "John" |
||||
|
} |
||||
|
)).ShouldBe("Hello John, how are you?"); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public async Task Should_Render_By_Razor() |
||||
|
{ |
||||
|
(await _templateRenderer.RenderAsync( |
||||
|
TestTemplates.HybridTemplateRazor, |
||||
|
model: new HybridModel |
||||
|
{ |
||||
|
Name = "John" |
||||
|
} |
||||
|
)).ShouldBe("Hello John, how are you?"); |
||||
|
} |
||||
|
|
||||
|
public class HybridModel |
||||
|
{ |
||||
|
public string Name { get; set; } |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,2 @@ |
|||||
|
@inherits Volo.Abp.TextTemplating.Razor.RazorTemplatePageBase<Volo.Abp.TextTemplating.HybridTemplateRendererProvider_Tests.HybridModel> |
||||
|
Hello @Model.Name, @Localizer["HowAreYou"] |
||||
@ -0,0 +1 @@ |
|||||
|
Hello {{model.name}}, {{L "HowAreYou" }} |
||||
Loading…
Reference in new issue