/// <summary> /// Returns a template-generated text file that is evaluated based on the given <paramref name="templateId"/>. /// The text generation will implicitly contain a variable $ that evaluates to the results of the query specified in <paramref name="args"/>. /// </summary> public async Task <FileResult> PrintEntities(int templateId, PrintEntitiesArguments <TKey> args, CancellationToken cancellation) { await Initialize(cancellation); var collection = typeof(TEntity).Name; var defId = DefinitionId; // (1) The Template Plan var template = await FactBehavior.GetPrintingTemplate(templateId, cancellation); var nameP = new TemplatePlanLeaf(template.DownloadName, TemplateLanguage.Text); var bodyP = new TemplatePlanLeaf(template.Body, TemplateLanguage.Html); var printoutP = new TemplatePlanTuple(nameP, bodyP); TemplatePlan plan; if (string.IsNullOrWhiteSpace(template.Context)) { plan = printoutP; } else { plan = new TemplatePlanDefine("$", template.Context, printoutP); } QueryInfo contextQuery = BaseUtil.EntitiesPreloadedQuery(args, collection, defId); plan = new TemplatePlanDefineQuery("$", contextQuery, plan); // (2) Functions + Variables var globalFunctions = new Dictionary <string, EvaluationFunction>(); var localFunctions = new Dictionary <string, EvaluationFunction>(); var globalVariables = new Dictionary <string, EvaluationVariable>(); var localVariables = BaseUtil.EntitiesLocalVariables(args, collection, defId); await FactBehavior.SetPrintingFunctions(localFunctions, globalFunctions, cancellation); await FactBehavior.SetPrintingVariables(localVariables, globalVariables, cancellation); // (3) Generate the output CultureInfo culture = GetCulture(args.Culture); var genArgs = new TemplateArguments(globalFunctions, globalVariables, localFunctions, localVariables, culture); await _templateService.GenerateFromPlan(plan : plan, args : genArgs, cancellation : cancellation); var downloadName = nameP.Outputs[0]; var body = bodyP.Outputs[0]; // Change the body to bytes var bodyBytes = Encoding.UTF8.GetBytes(body); // Use a default download name if none is provided if (string.IsNullOrWhiteSpace(downloadName)) { var meta = await GetMetadata(cancellation); var titlePlural = meta.PluralDisplay(); if (args.I != null && args.I.Count > 0) { downloadName = $"{titlePlural} ({args.I.Count})"; } else { int from = args.Skip + 1; int to = Math.Max(from, args.Skip + args.Top); downloadName = $"{titlePlural} {from}-{to}"; } } if (!downloadName.ToLower().EndsWith(".html")) { downloadName += ".html"; } // Return as a file return(new FileResult(bodyBytes, downloadName)); }
/// <summary> /// Returns a template-generated text file that is evaluated based on the given <paramref name="templateId"/>. /// The text generation will implicitly contain a variable $ that evaluates to the entity whose id matches <paramref name="id"/>. /// </summary> public async Task <(byte[] FileBytes, string FileName)> PrintEntity(TKey id, int templateId, PrintEntityByIdArguments args, CancellationToken cancellation) { await Initialize(cancellation); // (1) Collection & DefId var collection = typeof(TEntity).Name; var defId = DefinitionId; // (2) The Template Plan var template = await FactBehavior.GetPrintingTemplate(templateId, cancellation); var nameP = new TemplatePlanLeaf(template.DownloadName, TemplateLanguage.Text); var bodyP = new TemplatePlanLeaf(template.Body, TemplateLanguage.Html); var printoutP = new TemplatePlanTuple(nameP, bodyP); TemplatePlan plan; if (string.IsNullOrWhiteSpace(template.Context)) { plan = printoutP; } else { plan = new TemplatePlanDefine("$", template.Context, printoutP); } QueryInfo contextQuery = BaseUtil.EntityPreloadedQuery(id, args, collection, defId); plan = new TemplatePlanDefineQuery("$", contextQuery, plan); // (3) Functions + Variables var globalFunctions = new Dictionary <string, EvaluationFunction>(); var localFunctions = new Dictionary <string, EvaluationFunction>(); var globalVariables = new Dictionary <string, EvaluationVariable>(); var localVariables = BaseUtil.EntityLocalVariables(id, args, collection, defId); await FactBehavior.SetPrintingFunctions(localFunctions, globalFunctions, cancellation); await FactBehavior.SetPrintingVariables(localVariables, globalVariables, cancellation); // (4) Generate the output CultureInfo culture = GetCulture(args.Culture); var genArgs = new TemplateArguments(globalFunctions, globalVariables, localFunctions, localVariables, culture); await _templateService.GenerateFromPlan(plan, genArgs, cancellation); var downloadName = nameP.Outputs[0]; var body = bodyP.Outputs[0]; // Change the body to bytes var bodyBytes = Encoding.UTF8.GetBytes(body); // Do some sanitization of the downloadName if (string.IsNullOrWhiteSpace(downloadName)) { downloadName = id.ToString(); } if (!downloadName.ToLower().EndsWith(".html")) { downloadName += ".html"; } // Return as a file return(bodyBytes, downloadName); }