4

リクエストで:server-nameが返す内容に基づいて、特定のテンプレートを読み込もうとしています。

(ns rosay.views.common
  (:use noir.core)
  (:require [noir.request :as req]
            [clojure.string :as string]
            [net.cgrand.enlive-html :as html]))

(defn get-server-name
  "Pulls servername for template definition"
  []
  (or (:server-name (req/ring-request)) "localhost"))

(defn get-template
  "Grabs template name for current server"
  [tmpl]
  (string/join "" (concat [(get-server-name) tmpl])))

(html/deftemplate base (get-template "/base.html")
  []
  [:p] (html/content (get-template "/base.html")))

/home/usr/rosay/resources/localhost/base.htmlを返すローカルホストで機能しますが、別のホストに対して「hostname2」とテストすると、get-templateが/ home / usr / rosay/resourcesを参照している場所がわかります。 /hostname2/base.htmlですが、ブラウザでレンダリングすると、常に../resources/localhost/base.htmlを指します。

このユースケースを処理するためのマクロまたは別の方法はありますか?

4

1 に答える 1

2

コメントで述べたように、deftemplateは、テンプレートを名前空間内の関数として定義するマクロです。最初に評価されたときに1回だけです。テンプレートを遅延作成するためのコードを簡単に記述し、作成後にテンプレートをキャッシュすることでオーバーヘッドの一部を排除できます。

(def templates (atom {}))

(defmacro defservertemplate [name source args & forms]
  `(defn ~name [& args#]
     (let [src# (get-template ~source)]
       (dosync
        (if-let [template# (get templates src#)]
          (apply template# args#)
          (let [template# (template src# ~args ~@forms)]
            (swap! templates assoc src# template#)
            (apply template# args#)))))))

あなたの場合、あなたはそれから言うことができるでしょう(defservertemplate base "/base.html"...

あなたはおそらくこれを少し片付けることができます。本当に知っておく必要があるのは、deftemplateを呼び出すだけで、必要に応じtemplateて直接使用できます。

于 2013-01-24T12:12:43.050 に答える