clojure,活跃,多站点

时间:2012-12-07 23:10:32

标签: clojure enlive

尝试根据以下内容加载特定模板: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。

是否有处理此用例的宏或不同方式?

1 个答案:

答案 0 :(得分:2)

正如评论中所提到的,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只需拨打template,如果您愿意,可以直接使用。