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 }