Clojure, оживить, мульти-сайт
Попытка загрузить определенный шаблон на основе того, что: 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")))
Это работает для localhost, который возвращает /home/usr/rosay/resources/localhost/base.html, но когда я проверяю другой хост, скажем "hostname2", я вижу, где get-template смотрит /home/usr/rosay/resources/hostname2/base.html, но при рендеринге в браузере он всегда указывает на../resources/localhost/base.html.
Есть ли макрос или другой способ обработки этого варианта использования?
1 ответ
Как уже упоминалось в комментариях, 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
и вы можете использовать это напрямую, если хотите.