使用response.render呈现模板文件时,请使用带有Vibe.d的变量

时间:2014-04-04 18:53:57

标签: d vibed

目前我正在使用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");

但这不符合编译器。知道我怎么能做这个工作吗?

2 个答案:

答案 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)之前的字符串。