1 /*
2 * Hunt - A high-level D Programming Language Web framework that encourages rapid development and clean, pragmatic design.
3 *
4 * Copyright (C) 2015-2019, HuntLabs
5 *
6 * Website: https://www.huntlabs.net/
7 *
8 * Licensed under the Apache-2.0 License.
9 *
10 */
11
12 module hunt.framework.view.Template;
13
14 private
15 {
16 import std.meta;
17 import std.traits;
18
19 import hunt.framework.view.Render;
20 import hunt.framework.view.Lexer;
21 import hunt.framework.view.Parser;
22 import hunt.framework.view.Uninode;
23 import hunt.framework.view.ast;
24 }
25
26 struct TemplateConfig
27 {
28 string exprOpBegin = "{{";
29 string exprOpEnd = "}}";
30 string stmtOpBegin = "{%";
31 string stmtOpEnd = "%}";
32 string cmntOpBegin = "{#";
33 string cmntOpEnd = "#}";
34 string cmntOpInline = "##!";
35 string stmtOpInline = "#!";
36 }
37
38 TemplateNode loadData(TemplateConfig config = defaultConfig)(string tmpl)
39 {
40 alias TemplateLexer = Lexer!(
41 config.exprOpBegin,
42 config.exprOpEnd,
43 config.stmtOpBegin,
44 config.stmtOpEnd,
45 config.cmntOpBegin,
46 config.cmntOpEnd,
47 config.stmtOpInline,
48 config.cmntOpInline
49 );
50
51 Parser!TemplateLexer parser;
52 return parser.parseTree(tmpl);
53 }
54
55 TemplateNode loadFile(TemplateConfig config = defaultConfig)(string path)
56 {
57 alias TemplateLexer = Lexer!(
58 config.exprOpBegin,
59 config.exprOpEnd,
60 config.stmtOpBegin,
61 config.stmtOpEnd,
62 config.cmntOpBegin,
63 config.cmntOpEnd,
64 config.stmtOpInline,
65 config.cmntOpInline
66 );
67
68 Parser!TemplateLexer parser;
69 return parser.parseTreeFromFile(path);
70 }
71
72 string render(T...)(TemplateNode tree)
73 {
74 alias Args = AliasSeq!T;
75 alias Idents = staticMap!(Ident, T);
76
77 auto render = new Render(tree);
78
79 auto data = UniNode.emptyObject();
80
81 foreach (i, arg; Args)
82 {
83 static if (isSomeFunction!arg)
84 render.registerFunction!arg(Idents[i]);
85 else
86 data[Idents[i]] = arg.serialize;
87 }
88
89 return render.render(data.serialize);
90 }
91
92 string renderData(T...)(string tmpl)
93 {
94 static if (T.length > 0 && is(typeof(T[0]) == TemplateConfig))
95 return render!(T[1 .. $])(loadData!(T[0])(tmpl));
96 else
97 return render!(T)(loadData!defaultConfig(tmpl));
98 }
99
100 string renderFile(T...)(string path)
101 {
102 static if (T.length > 0 && is(typeof(T[0]) == TemplateConfig))
103 return render!(T[1 .. $])(loadFile!(T[0])(path));
104 else
105 return render!(T)(loadFile!defaultConfig(path));
106 }
107
108
109
110 void print(TemplateNode tree)
111 {
112 auto printer = new Printer;
113 tree.accept(printer);
114 }
115
116 private:
117
118 enum defaultConfig = TemplateConfig.init;
119
120 template Ident(alias A)
121 {
122 enum Ident = __traits(identifier, A);
123 }