2022-06-05 18:44:51 +00:00
|
|
|
using System;
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
|
|
|
using FluentValidation;
|
|
|
|
|
|
|
|
using Gallium;
|
|
|
|
|
|
|
|
using HandlebarsDotNet;
|
|
|
|
|
|
|
|
using Nitride.Contents;
|
|
|
|
|
|
|
|
namespace Nitride.Handlebars;
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// An operation that applies a common or shared template on the content of
|
|
|
|
/// a document that includes theme or styling information.
|
|
|
|
/// </summary>
|
|
|
|
public class ApplyStyleTemplate<TModel> : OperationBase
|
|
|
|
{
|
|
|
|
// TODO: This does not use [WithProperties] because the source generator hasn't been taught how to do generics.
|
|
|
|
|
|
|
|
private readonly HandlebarsTemplateCache cache;
|
|
|
|
|
|
|
|
private readonly IValidator<ApplyStyleTemplate<TModel>> validator;
|
|
|
|
|
2022-06-07 02:46:31 +00:00
|
|
|
public ApplyStyleTemplate(HandlebarsTemplateCache cache)
|
2022-06-05 18:44:51 +00:00
|
|
|
{
|
2022-06-07 02:46:31 +00:00
|
|
|
// TODO: Figure out why Autofac won't let us register IValidator of generic classes.
|
|
|
|
this.validator = new ApplyStyleTemplateValidator<TModel>();
|
2022-06-05 18:44:51 +00:00
|
|
|
this.cache = cache;
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets or sets the callback used to create a model from a given
|
|
|
|
/// entity. This allows for the website to customize what information is
|
|
|
|
/// being passed to the template.
|
|
|
|
/// </summary>
|
|
|
|
public Func<Entity, TModel>? CreateModelCallback { get; set; }
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Gets or sets the callback used to determine which template to use
|
|
|
|
/// for a given entity. This lets one have a per-page template change.
|
|
|
|
/// </summary>
|
|
|
|
public Func<Entity, string>? GetTemplateName { get; set; }
|
|
|
|
|
|
|
|
public IHandlebars? Handlebars { get; set; }
|
|
|
|
|
|
|
|
/// <inheritdoc />
|
|
|
|
public override IEnumerable<Entity> Run(IEnumerable<Entity> input)
|
|
|
|
{
|
|
|
|
// Make sure we have sane data.
|
|
|
|
this.validator.ValidateAndThrow(this);
|
|
|
|
|
|
|
|
// Create and set up the Handlebars.
|
|
|
|
return input.ForEachEntity<ITextContent>(this.Apply);
|
|
|
|
}
|
|
|
|
|
|
|
|
/// <summary>
|
|
|
|
/// Sets the callback for the template and returns the operation to
|
|
|
|
/// chain operations.
|
|
|
|
/// </summary>
|
|
|
|
/// <param name="callback">The callback to set.</param>
|
|
|
|
/// <returns>The ApplyContentHandlebarsTemplate to chain requests.</returns>
|
|
|
|
public ApplyStyleTemplate<TModel> WithCreateModelCallback(Func<Entity, TModel>? callback)
|
|
|
|
{
|
|
|
|
this.CreateModelCallback = callback;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public ApplyStyleTemplate<TModel> WithGetTemplateName(Func<Entity, string>? callback)
|
|
|
|
{
|
|
|
|
this.GetTemplateName = callback;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
public ApplyStyleTemplate<TModel> WithHandlebars(IHandlebars? handlebars)
|
|
|
|
{
|
|
|
|
this.Handlebars = handlebars;
|
|
|
|
return this;
|
|
|
|
}
|
|
|
|
|
|
|
|
private Entity Apply(Entity entity, ITextContent content)
|
|
|
|
{
|
|
|
|
TModel model = this.CreateModelCallback!(entity);
|
|
|
|
string name = this.GetTemplateName!(entity);
|
|
|
|
HandlebarsTemplate<object, object> template = this.cache.GetNamedTemplate(name);
|
|
|
|
string result = template(model!);
|
|
|
|
|
|
|
|
return entity.SetTextContent(result);
|
|
|
|
}
|
|
|
|
}
|