3

現在、私はVibe.dを使用して Web サイトを作成しています。この Web サイトには、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.dtres.render!メソッドに a を渡していますが、変数を渡したい:

void render(string action, HTTPServerResponse res) {
  res.render!(action);
}

しかし、次のエラーが表示されます。

Error: variable action cannot be read at compile time

を呼び出しているすべての場所でrender、文字列をハードコーディングしました。

render("foo.dt");

しかし、それはコンパイラを満足させません。どうすればこれを機能させることができますか?

4

2 に答える 2

3

できません。ダイエット テンプレートはコンパイル時に完全に前処理されるため、コンパイル時定数としてダイエット テンプレート ファイル名を知る必要があります。任意の量の変数パラメーターをテンプレートに渡して動的に処理できますが、テンプレート ファイル自体は厳密にコンパイル時です。

実行時にテンプレートをレンダリングするオプションは何度か尋ねられており、概念的には承認されていますが、積極的に取り組んでいません。

于 2014-04-04T22:28:48.987 に答える
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) 。 .

于 2014-04-06T06:49:58.237 に答える