public IncludeStatement(FluidParser parser, Expression path, Expression with = null, IList <AssignStatement> assignStatements = null) { _parser = parser; Path = path; With = with; AssignStatements = assignStatements; }
public async Task ShouldNotReleaseScopeAsynchronously() { var parser = new FluidParser(); parser.RegisterEmptyBlock("sleep", async(statements, writer, encoder, context) => { context.EnterChildScope(); context.IncrementSteps(); context.SetValue("id", "0"); await Task.Delay(100); await statements.RenderStatementsAsync(writer, encoder, context); context.ReleaseScope(); return(Completion.Normal); }); var context = new TemplateContext { }; context.SetValue("id", "1"); var template = parser.Parse(@"{{id}}{%sleep%}{{id}}{%endsleep%}{{id}}"); var output = await template.RenderAsync(context); Assert.Equal("101", output); }
public void ShouldParseFunctionCall() { var options = new FluidParserOptions { AllowFunctions = true }; #if COMPILED var _parser = new FluidParser(options).Compile(); #else var _parser = new FluidParser(options); #endif _parser.TryParse("{{ a() }}", out var template, out var errors); var statements = ((FluidTemplate)template).Statements; Assert.Single(statements); var outputStatement = statements[0] as OutputStatement; Assert.NotNull(outputStatement); var memberExpression = outputStatement.Expression as MemberExpression; Assert.Equal(2, memberExpression.Segments.Count); Assert.IsType <IdentifierSegment>(memberExpression.Segments[0]); Assert.IsType <FunctionCallSegment>(memberExpression.Segments[1]); }
public async Task <string> RenderTemplateForModel <K>(string liquidTemplatePath, K model) { //Put some caching mechanism here. var path = Path.Combine(_webHostEnvironment.ContentRootPath, "Pages", liquidTemplatePath); var template = new FluidParser().Parse(await File.ReadAllTextAsync(path)); return(await template.RenderAsync(new TemplateContext(model, _templateOptions).SetValue(typeof(K).Name, model))); }
public IncludeStatement(FluidParser parser, Expression path, Expression with = null, Expression @for = null, string alias = null, IList <AssignStatement> assignStatements = null) { _parser = parser; Path = path; With = with; For = @for; Alias = alias; AssignStatements = assignStatements; }
public void ShouldNotParseFunctionCall() { var options = new FluidParserOptions { AllowFunctions = false }; #if COMPILED var parser = new FluidParser(options).Compile(); #else var parser = new FluidParser(options); #endif Assert.False(parser.TryParse("{{ a() }}", out var template, out var errors)); Assert.Contains(ErrorMessages.FunctionsNotAllowed, errors); }
public Task <IActionResult> DfmGetOrchestrationTabMarkupFunction( [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = Globals.ApiRoutePrefix + "/orchestrations('{instanceId}')/custom-tab-markup('{templateName}')")] HttpRequest req, [DurableClient(TaskHub = Globals.HubNameRouteParamName)] IDurableClient defaultDurableClient, string connName, string hubName, string instanceId, string templateName, ILogger log) { return(this.HandleAuthAndErrors(defaultDurableClient, req, connName, hubName, log, async(durableClient) => { var status = await GetInstanceStatusWithHistory(connName, instanceId, durableClient, log); if (status == null) { return new NotFoundObjectResult($"Instance {instanceId} doesn't exist"); } // The underlying Task never throws, so it's OK. var templatesMap = await CustomTemplates.GetTabTemplatesAsync(); string templateCode = templatesMap.GetTemplate(status.GetEntityTypeName(), templateName); if (templateCode == null) { return new NotFoundObjectResult("The specified template doesn't exist"); } try { var fluidTemplate = new FluidParser().Parse(templateCode); var options = new TemplateOptions(); options.MemberAccessStrategy.Register <JObject, object>((obj, fieldName) => obj[fieldName]); options.ValueConverters.Add(x => x is JObject obj ? new ObjectValue(obj) : null); options.ValueConverters.Add(x => x is JValue val ? val.Value : null); string fluidResult = fluidTemplate.Render(new TemplateContext(status, options)); return new ContentResult() { Content = fluidResult, ContentType = "text/html; charset=UTF-8" }; } catch (Exception ex) { return new BadRequestObjectResult(ex.Message); } })); }
public void DefaultContextShouldUseTemplateOptionsProperties() { var parser = new FluidParser(); var options = new TemplateOptions(); options.TimeZone = TimeZoneInfo.Utc; options.CultureInfo = new CultureInfo("fr-FR"); options.Now = () => new DateTime(2020, 01, 01); var context = new TemplateContext(options); Assert.Equal(TimeZoneInfo.Utc, context.TimeZone); Assert.Equal(new CultureInfo("fr-FR"), context.CultureInfo); Assert.Equal(new DateTime(2020, 01, 01), context.Now()); }
public void LiquidModelHasDictionry_KeyAccessShouldWork() { /// Arrange var model = new TestModel(); model.Bar["Baz"] = "abc"; /// Act var context = new TemplateContext(model) { CultureInfo = CultureInfo.InvariantCulture }; var parser = new FluidParser(); var template = parser.Parse("Hi {{ Foo }} {{ Bar[\"Baz\"] }}"); var text = template.Render(context); /// Assert Assert.Equal("Hi Foo. abc", text); }
public void UseDifferentModelsWithSameMemberName() { // Arrange var parser = new FluidParser(); var template = parser.Parse("Hi {{Name}}"); var model1 = new TestClass { Name = "TestClass" }; var model2 = new AnotherTestClass { Name = "AnotherTestClass" }; // Act template.Render(new TemplateContext(model1)); template.Render(new TemplateContext(model2)); template.Render(new TemplateContext(model2)); template.Render(new TemplateContext(model2)); template.Render(new TemplateContext(model1)); template.Render(new TemplateContext(model2)); }
public void ScopeShouldFallbackToTemplateOptions() { var parser = new FluidParser(); parser.TryParse("{{ p.NaMe }}", out var template, out var error); var options = new TemplateOptions(); options.Scope.SetValue("o1", new StringValue("o1")); options.Scope.SetValue("o2", new StringValue("o2")); var context = new TemplateContext(options); context.SetValue("o2", "new o2"); context.SetValue("o3", "o3"); Assert.Equal("o1", context.GetValue("o1").ToStringValue()); Assert.Equal("new o2", context.GetValue("o2").ToStringValue()); Assert.Equal("o3", context.GetValue("o3").ToStringValue()); }
public async Task TemplateIsRendered(string filename, string templatename) { var content = File.ReadAllText(filename); var report = JsonSerializer.Deserialize <Report>(content); var template = File.ReadAllText(templatename); var parseIsSuccessful = new FluidParser().TryParse(template, out var fluidTemplate, out var errors); Assert.True(parseIsSuccessful, String.Join("\n", errors)); var context = new TemplateContext(report); var body = await fluidTemplate.RenderAsync(context); _output.WriteLine(body); Assert.NotEmpty(body); }
public async Task ShouldRenderReadmeSample() { var options = new TemplateOptions(); // When a property of a JObject value is accessed, try to look into its properties options.MemberAccessStrategy.Register <JObject, object>((source, name) => source[name]); // Convert JToken to FluidValue options.ValueConverters.Add(x => x is JObject o ? new ObjectValue(o) : null); options.ValueConverters.Add(x => x is JValue v ? v.Value : null); var model = JObject.Parse("{\"Name\": \"Bill\"}"); var parser = new FluidParser(); parser.TryParse("His name is {{ Name }}", out var template); var context = new TemplateContext(model, options); Assert.Equal("His name is Bill", await template.RenderAsync(context)); }
static void Main(string[] args) { var parser = new FluidParser(); Dictionary <string, IFluidTemplate> templates = new Dictionary <string, IFluidTemplate>(); var templateFiles = Directory.GetFiles(Directory.GetCurrentDirectory(), "*.tpl"); foreach (var item in templateFiles) { var fluidTemplate = parser.Parse(File.ReadAllText(item, Encoding.UTF8)); templates.Add(Path.GetFileName(item), fluidTemplate); } Dictionary <string, Language[]> languages = JsonSerializer.Deserialize <Dictionary <string, Language[]> >(File.ReadAllText("Languages.json", Encoding.UTF8)); foreach (var item in templates) { StringBuilder sqlBuilder = new StringBuilder(); foreach (var lan in languages.SelectMany(m => { foreach (var item in m.Value) { item.LanKey = m.Key; } return(m.Value); })) { Console.WriteLine("{0}: {1}", item.Key, lan.LanKey); lan.LanValue = lan.LanValue.Replace("'", "''"); var context = new TemplateContext(lan); string sql = item.Value.Render(context); sqlBuilder.AppendLine(sql); sqlBuilder.AppendLine(); } if (!Directory.Exists("Script")) { Directory.CreateDirectory("Script"); } File.WriteAllText(Path.Combine("Script", item.Key.Replace(".tpl", ".sql")), sqlBuilder.ToString(), Encoding.UTF8); } }
static Templates() { var assembly = Assembly.GetExecutingAssembly(); var templateResourceNames = assembly .GetManifestResourceNames() .Where(name => name.StartsWith(s_TemplateResourcePrefix) && name.EndsWith(s_TemplateResourceSuffix)); foreach (var resourceName in templateResourceNames) { var templateName = resourceName .Replace(s_TemplateResourcePrefix, "") .Replace(s_TemplateResourceSuffix, ""); s_Templates.Add(templateName, new Lazy <IFluidTemplate>(() => { var templateSource = EmbeddedResource.Load(resourceName); var parser = new FluidParser(); return(parser.Parse(templateSource)); })); } }
public void LiquidModelHasNestedDictionaryAndLists_KeyAccessAndListIterationShouldWork() { /// Arrange var model = new TestModel(); model.Bar["Baz"] = new[] { new Dictionary <string, object> { { "key1", "value1" }, { "key2", "value2" } } }; var liquid = "{% assign x = Bar[\"Baz\"] -%}{% for i in x -%}key1={{ i[\"key1\"] }},key2={{ i[\"key2\"] }}{% endfor -%}"; /// Act var context = new TemplateContext(model) { CultureInfo = CultureInfo.InvariantCulture }; var parser = new FluidParser(); var template = parser.Parse(liquid); var text = template.Render(context); /// Assert Assert.Equal("key1=value1,key2=value2", text); }
public LiquidMiddleware(FluidParser fluid) => _fluid = fluid;
public PatchTemplateBehaviour() { _parser = new FluidParser().AddTags(); // _parser = new FluidParser(); }