Wie kann man dynamisch Argumente eines Clojure -Makros erzeugen?
Frage
Ich entwickle derzeit ein kleines CMS mit dem Wonderful En leben als Vorlagenmotor. Enlive hat ein Makro namens at
Dies erfordert einen Knoten (eine Karte), das den HTML -Snippet und eine willkürliche Anzahl von Tupeln angibt, die jeweils aus einem Selektor (einem Vektor) und einer Transformation (ein Verschluss) bestehen.
(at a-node
[:a :selector] a-transformation
[:another :selector] another-transformation
...)
Jetzt möchte ich die Tupel in Abhängigkeit von eingehenden Daten/Kontext generieren. Ich habe viele verschiedene Dinge ohne Erfolg ausprobiert. Zum Beispiel
(let [this (repository/u "http://example.com/ACMECorp")
statements (repository/find-by-subject this)
context {:depth 1}]
`(at (snippet-for 'this 'context)
[root] (set-attr :about (str 'this))
~@(loop [rules []
st statements]
(if-not (seq st)
rules
(recur (conj rules
`[:> (attr= :property ~(str (repository/predicate (first st))))]
`(content (renderit ~(repository/object (first st)) 'context)))
(rest st))))))
Jede Hilfe wird sehr geschätzt.
-Jochen
Lösung
Clojure ist ein Lispeln, sodass Sie jederzeit den gewünschten Code als Liste erstellen und anrufen können eval
darauf. Ich bin mir nicht 100% sicher über den Code, den Sie gegeben haben, aber ich würde vermuten, dass Sie nur Ihre gesamte Syntax-Quote in einem beischließen möchten eval
Anruf.
(let [this (repository/u "http://example.com/ACMECorp")
statements (repository/find-by-subject this)
context {:depth 1}]
(eval `(at (snippet-for 'this 'context)
[root] (set-attr :about (str 'this))
~@(loop [rules []
st statements]
(if-not (seq st)
rules
(recur (conj rules
`[:> (attr= :property ~(str (repository/predicate (first st))))]
`(content (renderit ~(repository/object (first st)) 'context)))
(rest st)))))))
Andere Tipps
Ich bin mir nicht sicher, ob sie austauschbar sind, aber schauen Sie sich die AT* -Funktion an. Mir scheint, dass Ihr Problem darin besteht, ein Makro zu sein.
BEARBEITEN: Sie sind nicht. Nennen Sie es so:
(at* a-node
[[:a :selector] a-transformation
[:another :selector] another-transformation
...])