-
Notifications
You must be signed in to change notification settings - Fork 443
/
Copy pathLiquidParser.cs
84 lines (69 loc) · 2.72 KB
/
LiquidParser.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text.Encodings.Web;
using System.Threading.Tasks;
using Fluid;
using Fluid.Ast;
public class LiquidParser : FluidParser
{
public LiquidParser()
{
RegisterExpressionTag("layout", OnRegisterLayoutTag);
RegisterEmptyTag("renderbody", OnRegisterRenderBodyTag);
RegisterIdentifierBlock("section", OnRegisterSectionBlock);
RegisterIdentifierTag("rendersection", OnRegisterSectionTag);
}
private async ValueTask<Completion> OnRegisterLayoutTag(Expression expression, TextWriter writer, TextEncoder encoder, TemplateContext context)
{
const string viewExtension = ".liquid";
var relativeLayoutPath = (await expression.EvaluateAsync(context)).ToStringValue();
if (!relativeLayoutPath.EndsWith(viewExtension, StringComparison.OrdinalIgnoreCase))
{
relativeLayoutPath += viewExtension;
}
context.AmbientValues["Layout"] = relativeLayoutPath;
return Completion.Normal;
}
private async ValueTask<Completion> OnRegisterRenderBodyTag(TextWriter writer, TextEncoder encoder, TemplateContext context)
{
static void ThrowParseException()
{
throw new ParseException("Could not render body, Layouts can't be evaluated directly.");
}
if (context.AmbientValues.TryGetValue("Body", out var body))
{
await writer.WriteAsync((string)body);
}
else
{
ThrowParseException();
}
return Completion.Normal;
}
private ValueTask<Completion> OnRegisterSectionBlock(string sectionName, IReadOnlyList<Statement> statements, TextWriter writer, TextEncoder encoder, TemplateContext context)
{
if (context.AmbientValues.TryGetValue("Sections", out var sections))
{
var dictionary = (Dictionary<string, List<Statement>>) sections;
dictionary[sectionName] = statements.ToList();
}
return new ValueTask<Completion>(Completion.Normal);
}
private async ValueTask<Completion> OnRegisterSectionTag(string sectionName, TextWriter writer, TextEncoder encoder, TemplateContext context)
{
if (context.AmbientValues.TryGetValue("Sections", out var sections))
{
var dictionary = (Dictionary<string, List<Statement>>) sections;
if (dictionary.TryGetValue(sectionName, out var section))
{
foreach(var statement in section)
{
await statement.WriteToAsync(writer, encoder, context);
}
}
}
return Completion.Normal;
}
}