目前我正在使用Vibe.d创建一个网站,该网站有一个Response
类,可以传递给每个请求。看起来像这样:
import vibe.d;
void index(HTTPServerRequest req, HTTPServerResponse res)
{
res.render!("index.dt", req);
}
shared static this()
{
auto router = new URLRouter;
router.get("/", &index);
auto settings = new HTTPServerSettings;
settings.port = 8080;
listenHTTP(settings, router);
}
在示例中,我将const string
"index.dt
传递给res.render!
方法,但我想传递一个变量:
void render(string action, HTTPServerResponse res) {
res.render!(action);
}
但是我收到以下错误:
Error: variable action cannot be read at compile time
在我正在呼叫render
的每个地方,我都是硬编码的字符串:
render("foo.dt");
但这不符合编译器。知道我怎么能做这个工作吗?
答案 0 :(得分:3)
你做不到。饮食模板在编译期间完全预处理,因此有必要将Diet模板文件名称作为编译时常量。您可以将任意数量的变量参数传递给要动态处理的模板,但模板文件本身是严格编译时的。
在运行期间呈现模板的选项已被多次询问,并且在概念上得到批准,但未被主动处理。
答案 1 :(得分:3)
虽然原则上不能使用运行时变量(基本上需要在运行时编译D代码),但您可以使用编译时定义的enum
常量或模板参数来避免使用直接字符串常量:
void index(string templ)(HTTPServerRequest req, HTTPServerResponse res)
{
res.render!(templ, req);
}
shared static this()
{
// ...
router.get("/", &index!"index.dt");
// BTW, this special case is equal to
//router.get("/", staticTemplate!"index.dt");
// ...
}
或使用enum
:
enum indexTemplateFile = "index.dt";
void index(HTTPServerRequest req, HTTPServerResponse res)
{
res.render!(indexTemplateFile, req);
}
也可以使用这种使用命名enum
的替代形式:
enum TemplateFile {
index = "index.dt",
login = "login.dt"
}
void index(HTTPServerRequest req, HTTPServerResponse res)
{
res.render!(TemplateFile.index, req);
}
这两种方法也可以组合在一起,只要结果仍然可以在编译时计算(例如,可以调用std.string.toLower
之类在将字符串传递给render
)之前的字符串。