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 |
|||
{ |
|||
[DependsOn( |
|||
typeof(AbpTextTemplatingAbstractionsModule) |
|||
typeof(AbpTextTemplatingCoreModule) |
|||
)] |
|||
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! |
|||
@ -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 |
|||
@ -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! |
|||
@ -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! |
|||
@ -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