尝试根据以下内容加载特定模板: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的localhost,但当我针对不同的主机测试时说“hostname2”时,我看到get-template在哪里查看/ home /usr/rosay / resources /hostname2/base.html但是当它在浏览器中呈现时,它总是指向../resources/localhost/base.html.
是否有宏或不同的方式来处理这个用例?
最佳答案 正如评论中所提到的,deftemplate是一个宏,它将模板定义为命名空间中的一个函数 – 只有一次,当它首次被评估时.您可以轻松编写一些代码来懒惰地创建模板,并通过在模板创建后缓存模板来消除一些开销:
(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只是调用模板,如果你愿意,你可以直接使用它.