Clojure, animate, multisite

Trying to load a specific template based on what: the server name is returned in the request:

(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"))) 

It works for localhost, which returns /home/usr/rosay/resources/localhost/base.html, but when I test another host I say "hostname2", I see where the get-template is looking for / home / usr / rosay / resources / hostname 2 / base.html, but when it is displayed in the browser, it always points to .. /resources/localhost/base.html.

Is there a macro or other way to handle this use case?

+4
source share
1 answer

As pointed out in the comments, deftemplate is a macro that defines a template as a function in your namespace - only once when it is first evaluated. You can easily write code for lazy template creation and eliminate some of the overhead by caching the template after it is created:

 (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#))))))) 

In your case, you could say (defservertemplate base "/base.html"...

You can probably clean this up a bit. All you really need to know is that deftemplate just calls template , and you can use it directly if you want.

+2
source

All Articles