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 }