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 std.stdio; 12 import std.variant; 13 } 14 15 struct TempleHtmlFilter { 16 17 private static struct SafeString { 18 const string payload; 19 } 20 21 static void temple_filter(ref TempleOutputStream stream, string unsafe) { 22 filterHTMLEscape(stream, unsafe); 23 } 24 25 static void temple_filter(ref TempleOutputStream stream, Variant variant) { 26 temple_filter(stream, variant.toString); 27 } 28 29 static string temple_filter(SafeString safe) { 30 return safe.payload; 31 } 32 33 static SafeString safe(string str) { 34 return SafeString(str); 35 } 36 37 static SafeString safe(Variant variant) { 38 return SafeString(variant.toString); 39 } 40 } 41 42 private enum SetupContext = q{ 43 static if(is(Ctx == HTTPServerRequest)) { 44 TempleContext context = new TempleContext(); 45 copyContextParams(context, req); 46 } 47 else { 48 TempleContext context = req; 49 } 50 }; 51 52 private template isSupportedCtx(Ctx) { 53 enum isSupportedCtx = is(Ctx : HTTPServerRequest) || is(Ctx == TempleContext); 54 } 55 56 void renderTemple(string temple, Ctx = TempleContext) 57 (HTTPServerResponse res, Ctx req = null) 58 if(isSupportedCtx!Ctx) 59 { 60 mixin(SetupContext); 61 62 auto t = compile_temple!(temple, TempleHtmlFilter); 63 t.render(res.bodyWriter, context); 64 } 65 66 void renderTempleFile(string file, Ctx = TempleContext) 67 (HTTPServerResponse res, Ctx req = null) 68 if(isSupportedCtx!Ctx) 69 { 70 mixin(SetupContext); 71 72 auto t = compile_temple_file!(file, TempleHtmlFilter); 73 t.render(res.bodyWriter, context); 74 } 75 76 void renderTempleLayoutFile(string layout_file, string partial_file, Ctx = TempleContext) 77 (HTTPServerResponse res, Ctx req = null) 78 if(isSupportedCtx!Ctx) 79 { 80 mixin(SetupContext); 81 82 auto layout = compile_temple_file!(layout_file, TempleHtmlFilter); 83 auto partial = compile_temple_file!(partial_file, TempleHtmlFilter); 84 auto composed = layout.layout(&partial); 85 composed.render(res.bodyWriter, context); 86 } 87 88 private void copyContextParams(ref TempleContext ctx, ref HTTPServerRequest req) { 89 90 if(!req || !(req.params)) 91 return; 92 93 foreach(key, val; req.params) { 94 ctx[key] = val; 95 } 96 }