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и вы можете использовать это напрямую, если хотите.

Другие вопросы по тегам