1 module temple.vibe; 2 3 version(Have_vibe_d): 4 5 pragma(msg, "Compiling Temple with Vibed support"); 6 7 private { 8 import temple; 9 import vibe.http.server; 10 import vibe.textfilter.html; 11 import vibe.utils.dictionarylist; 12 import std.stdio; 13 import std.variant; 14 } 15 16 struct TempleHtmlFilter { 17 18 private static struct SafeString { 19 const string payload; 20 } 21 22 static void temple_filter(ref TempleOutputStream stream, string unsafe) { 23 filterHTMLEscape(stream, unsafe); 24 } 25 26 static void temple_filter(ref TempleOutputStream stream, Variant variant) { 27 temple_filter(stream, variant.toString); 28 } 29 30 static string temple_filter(SafeString safe) { 31 return safe.payload; 32 } 33 34 static SafeString safe(string str) { 35 return SafeString(str); 36 } 37 38 static SafeString safe(Variant variant) { 39 return SafeString(variant.toString); 40 } 41 } 42 43 private enum SetupContext = q{ 44 static if(is(Ctx == HTTPServerRequest)) { 45 TempleContext context = new TempleContext(); 46 copyContextParams(context, req); 47 } 48 else { 49 TempleContext context = req; 50 } 51 }; 52 53 private template isSupportedCtx(Ctx) { 54 enum isSupportedCtx = is(Ctx : HTTPServerRequest) || is(Ctx == TempleContext); 55 } 56 57 void renderTemple(string temple, Ctx = TempleContext) 58 (HTTPServerResponse res, Ctx req = null) 59 if(isSupportedCtx!Ctx) 60 { 61 mixin(SetupContext); 62 63 auto t = compile_temple!(temple, TempleHtmlFilter); 64 t.render(res.bodyWriter, context); 65 } 66 67 void renderTempleFile(string file, Ctx = TempleContext) 68 (HTTPServerResponse res, Ctx req = null) 69 if(isSupportedCtx!Ctx) 70 { 71 mixin(SetupContext); 72 73 auto t = compile_temple_file!(file, TempleHtmlFilter); 74 t.render(res.bodyWriter, context); 75 } 76 77 void renderTempleLayoutFile(string layout_file, string partial_file, Ctx = TempleContext) 78 (HTTPServerResponse res, Ctx req = null) 79 if(isSupportedCtx!Ctx) 80 { 81 mixin(SetupContext); 82 83 auto layout = compile_temple_file!(layout_file, TempleHtmlFilter); 84 auto partial = compile_temple_file!(partial_file, TempleHtmlFilter); 85 auto composed = layout.layout(&partial); 86 composed.render(res.bodyWriter, context); 87 } 88 89 private void copyContextParams(ref TempleContext ctx, ref HTTPServerRequest req) { 90 static if(is(typeof(req.params) == string[string])) { 91 if(!req || !(req.params)) 92 return; 93 } else if(is(typeof(req.params) == DictionaryList!(string, true, 32))) { 94 if(!req || req.params.length < 1) 95 return; 96 } 97 98 foreach(key, val; req.params) { 99 ctx[key] = val; 100 } 101 }