using System; using System.Collections.Generic; using FluentValidation; using Gallium; using HandlebarsDotNet; using Nitride.Contents; namespace Nitride.Handlebars; /// /// An operation that uses the content to create a template that is then /// applied against the content and metadata and then replaces the content /// of that entity. /// public class RenderContentTemplate : OperationBase { private readonly HandlebarsTemplateCache cache; // TODO: This does not use [WithProperties] because the source generator hasn't been taught how to do generics. private readonly IValidator> validator; public RenderContentTemplate(IValidator> validator, HandlebarsTemplateCache cache) { this.validator = validator; this.cache = cache; } /// /// 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. /// public Func? CreateModelCallback { get; set; } /// public override IEnumerable Run(IEnumerable input) { this.validator.ValidateAndThrow(this); return input.ForEachEntity(this.Apply); } /// /// Sets the callback for the template and returns the operation to /// chain operations. /// /// The callback to set. /// The ApplyContentHandlebarsTemplate to chain requests. public RenderContentTemplate WithCreateModelCallback(Func? callback) { this.CreateModelCallback = callback; return this; } private Entity Apply(Entity entity, HasHandlebarsTemplate _, ITextContent content) { // Create the model using the callback. TModel model = this.CreateModelCallback!(entity); // Create a template from the contents. string text = content.GetText(); HandlebarsTemplate template = this.cache.GetLiteralTemplate(text); // Render the template and create a new entity with the updated // text. string result = template(model!); return entity.Remove().SetTextContent(new StringTextContent(result)); } }