Update Slmer: include << macro
This commit is contained in:
parent
3ec7ced8cd
commit
a888a340ae
6 changed files with 98 additions and 24 deletions
8
deps.edn
8
deps.edn
|
|
@ -37,7 +37,7 @@
|
||||||
org.clojure/core.match {:mvn/version "1.0.0"}
|
org.clojure/core.match {:mvn/version "1.0.0"}
|
||||||
hiccup/hiccup {:mvn/version "2.0.0-alpha2"}
|
hiccup/hiccup {:mvn/version "2.0.0-alpha2"}
|
||||||
rewrite-clj/rewrite-clj {:mvn/version "1.0.605-alpha"}
|
rewrite-clj/rewrite-clj {:mvn/version "1.0.605-alpha"}
|
||||||
selmer/selmer {:mvn/version "1.12.40"}
|
selmer/selmer {:mvn/version "1.12.44"}
|
||||||
com.taoensso/timbre {:mvn/version "5.1.2"}
|
com.taoensso/timbre {:mvn/version "5.1.2"}
|
||||||
org.clojure/tools.logging {:mvn/version "1.1.0"}}
|
org.clojure/tools.logging {:mvn/version "1.1.0"}}
|
||||||
:aliases {:babashka/dev
|
:aliases {:babashka/dev
|
||||||
|
|
@ -87,9 +87,9 @@
|
||||||
com.grammarly/omniconf {:mvn/version "0.4.3"}
|
com.grammarly/omniconf {:mvn/version "0.4.3"}
|
||||||
crispin/crispin {:mvn/version "0.3.8"}
|
crispin/crispin {:mvn/version "0.3.8"}
|
||||||
org.clojure/data.json {:mvn/version "2.4.0"}}
|
org.clojure/data.json {:mvn/version "2.4.0"}}
|
||||||
:classpath-overrides {org.clojure/clojure nil
|
:classpath-overrides {org.clojure/clojure nil
|
||||||
org.clojure/spec.alpha nil
|
org.clojure/spec.alpha nil
|
||||||
org.clojure/core.specs.alpha nil}}
|
org.clojure/core.specs.alpha nil}}
|
||||||
:clj-nvd
|
:clj-nvd
|
||||||
{:extra-deps {clj-nvd/clj-nvd {:git/url "https://github.com/miikka/clj-nvd.git"
|
{:extra-deps {clj-nvd/clj-nvd {:git/url "https://github.com/miikka/clj-nvd.git"
|
||||||
:sha "f2ec98699e057a379baf170cb49cf7ad76874a70"}}
|
:sha "f2ec98699e057a379baf170cb49cf7ad76874a70"}}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
(ns babashka.impl.selmer
|
(ns babashka.impl.selmer
|
||||||
{:no-doc true}
|
{:no-doc true}
|
||||||
(:require [babashka.impl.classpath :refer [resource]]
|
(:require [babashka.impl.classpath :refer [resource]]
|
||||||
|
[babashka.impl.common :refer [ctx]]
|
||||||
[sci.core :as sci]
|
[sci.core :as sci]
|
||||||
[selmer.filters :as filters]
|
[selmer.filters :as filters]
|
||||||
[selmer.parser]
|
[selmer.parser]
|
||||||
|
|
@ -10,20 +11,23 @@
|
||||||
|
|
||||||
(def spns (sci/create-ns 'selmer.parser nil))
|
(def spns (sci/create-ns 'selmer.parser nil))
|
||||||
|
|
||||||
|
(def include #{'env-map})
|
||||||
|
|
||||||
(defn make-ns [ns sci-ns]
|
(defn make-ns [ns sci-ns]
|
||||||
(reduce (fn [ns-map [var-name var]]
|
(reduce (fn [ns-map [var-name var]]
|
||||||
(let [m (meta var)
|
(let [m (meta var)
|
||||||
no-doc (:no-doc m)
|
no-doc (:no-doc m)
|
||||||
doc (:doc m)
|
doc (:doc m)
|
||||||
arglists (:arglists m)]
|
arglists (:arglists m)]
|
||||||
(if no-doc ns-map
|
(if (and no-doc (not (contains? include var-name)))
|
||||||
(assoc ns-map var-name
|
ns-map
|
||||||
(sci/new-var (symbol var-name) @var
|
(assoc ns-map var-name
|
||||||
(cond-> {:ns sci-ns
|
(sci/new-var (symbol var-name) @var
|
||||||
:name (:name m)}
|
(cond-> {:ns sci-ns
|
||||||
(:macro m) (assoc :macro true)
|
:name (:name m)}
|
||||||
doc (assoc :doc doc)
|
(:macro m) (assoc :macro true)
|
||||||
arglists (assoc :arglists arglists)))))))
|
doc (assoc :doc doc)
|
||||||
|
arglists (assoc :arglists arglists)))))))
|
||||||
{}
|
{}
|
||||||
(ns-publics ns)))
|
(ns-publics ns)))
|
||||||
|
|
||||||
|
|
@ -55,11 +59,37 @@
|
||||||
(binding [util/*escape-variables* @escape-variables]
|
(binding [util/*escape-variables* @escape-variables]
|
||||||
(selmer.parser/render-template template context-map)))
|
(selmer.parser/render-template template context-map)))
|
||||||
|
|
||||||
|
(defn sci-ns-resolve [ns fqs]
|
||||||
|
(sci/eval-form @ctx (list 'clojure.core/ns-resolve ns (list 'quote fqs))))
|
||||||
|
|
||||||
|
(defn force! [x]
|
||||||
|
(if (instance? clojure.lang.IDeref x) @x x))
|
||||||
|
|
||||||
|
(defn ^:no-doc resolve-var-from-kw [ns env kw]
|
||||||
|
(if (namespace kw)
|
||||||
|
(when-let [v (sci-ns-resolve ns (symbol (str (namespace kw) "/" (name kw))))] {kw (force! v)})
|
||||||
|
(or
|
||||||
|
;; check local env first
|
||||||
|
(when-let [[_ v] (find env kw)] {kw v})
|
||||||
|
(when-let [v (sci-ns-resolve ns (symbol (name kw)))] {kw (force! v)}))))
|
||||||
|
|
||||||
|
(defmacro <<
|
||||||
|
"Resolves the variables from your template string from the local-env, or the
|
||||||
|
namespace and puts them into your template for you.
|
||||||
|
e.g. (let [a 1] (<< \"{{a}} + {{a}} = 2\")) ;;=> \"1 + 1 = 2\" "
|
||||||
|
[s]
|
||||||
|
`(->> (selmer.parser/known-variables ~s)
|
||||||
|
(mapv #(selmer.parser/resolve-var-from-kw ~(deref sci/ns) (selmer.parser/env-map) %))
|
||||||
|
(apply merge)
|
||||||
|
(selmer.parser/render ~s)))
|
||||||
|
|
||||||
(def selmer-parser-namespace
|
(def selmer-parser-namespace
|
||||||
(-> selmer-parser-ns
|
(-> selmer-parser-ns
|
||||||
(assoc 'render-file (sci/copy-var render-file spns)
|
(assoc 'render-file (sci/copy-var render-file spns)
|
||||||
'render (sci/copy-var render spns)
|
'render (sci/copy-var render spns)
|
||||||
'render-template (sci/copy-var render-template spns))))
|
'render-template (sci/copy-var render-template spns)
|
||||||
|
'resolve-var-from-kw (sci/copy-var resolve-var-from-kw spns)
|
||||||
|
'<< (sci/copy-var << spns))))
|
||||||
|
|
||||||
(def stns (sci/create-ns 'selmer.tags nil))
|
(def stns (sci/create-ns 'selmer.tags nil))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -59,7 +59,7 @@
|
||||||
:feature/rewrite-clj {:source-paths ["feature-rewrite-clj"]
|
:feature/rewrite-clj {:source-paths ["feature-rewrite-clj"]
|
||||||
:dependencies [[rewrite-clj/rewrite-clj "1.0.605-alpha"]]}
|
:dependencies [[rewrite-clj/rewrite-clj "1.0.605-alpha"]]}
|
||||||
:feature/selmer {:source-paths ["feature-selmer"]
|
:feature/selmer {:source-paths ["feature-selmer"]
|
||||||
:dependencies [[selmer/selmer "1.12.40"]]}
|
:dependencies [[selmer/selmer "1.12.44"]]}
|
||||||
:test [:feature/xml
|
:test [:feature/xml
|
||||||
:feature/lanterna
|
:feature/lanterna
|
||||||
:feature/yaml
|
:feature/yaml
|
||||||
|
|
|
||||||
|
|
@ -11,14 +11,17 @@
|
||||||
(or (empty? ns-args)
|
(or (empty? ns-args)
|
||||||
(contains? ns-args ns)))
|
(contains? ns-args ns)))
|
||||||
|
|
||||||
(defn test-namespaces [& namespaces]
|
(defmacro test-namespaces [& namespaces]
|
||||||
(let [namespaces (seq (filter test-namespace? namespaces))]
|
(let [namespaces (map second namespaces)
|
||||||
(when namespaces
|
namespaces (seq (filter test-namespace? namespaces))
|
||||||
(doseq [ns namespaces]
|
quoted-namespaces (map #(list 'quote %) namespaces)
|
||||||
(require ns))
|
requires (map #(list 'require %) quoted-namespaces)]
|
||||||
(let [m (apply t/run-tests namespaces)]
|
(when (seq requires)
|
||||||
(swap! status (fn [status]
|
`(do
|
||||||
(merge-with + status (dissoc m :type))))))))
|
~@requires
|
||||||
|
(let [m# (t/run-tests ~@quoted-namespaces)]
|
||||||
|
(swap! status (fn [status#]
|
||||||
|
(merge-with + status# (dissoc m# :type)))))))))
|
||||||
|
|
||||||
(def windows? (-> (System/getProperty "os.name")
|
(def windows? (-> (System/getProperty "os.name")
|
||||||
(str/lower-case)
|
(str/lower-case)
|
||||||
|
|
|
||||||
4
test-resources/lib_tests/selmer/benchmark.clj
Normal file
4
test-resources/lib_tests/selmer/benchmark.clj
Normal file
|
|
@ -0,0 +1,4 @@
|
||||||
|
(ns selmer.benchmark)
|
||||||
|
|
||||||
|
(def user (repeat 10 [{:name "test"}]))
|
||||||
|
|
||||||
|
|
@ -7,8 +7,10 @@
|
||||||
[clojure.test :refer [deftest are is testing]]
|
[clojure.test :refer [deftest are is testing]]
|
||||||
[selmer.filters :as f]
|
[selmer.filters :as f]
|
||||||
[selmer.parser :as p :refer [render render-file render-template
|
[selmer.parser :as p :refer [render render-file render-template
|
||||||
parse parse-input known-variables]]
|
parse parse-input known-variables
|
||||||
[selmer.tags :as tags])
|
<< resolve-var-from-kw env-map]]
|
||||||
|
[selmer.tags :as tags]
|
||||||
|
[clojure.set :as set])
|
||||||
(:import (java.io StringReader ByteArrayInputStream)
|
(:import (java.io StringReader ByteArrayInputStream)
|
||||||
java.io.File
|
java.io.File
|
||||||
java.util.Locale))
|
java.util.Locale))
|
||||||
|
|
@ -1257,3 +1259,38 @@
|
||||||
"debug-value"))
|
"debug-value"))
|
||||||
(testing "basic rendering escapes HTML"
|
(testing "basic rendering escapes HTML"
|
||||||
(is (str/includes? (basic-edn->html {:a "<pre>"}) """))))
|
(is (str/includes? (basic-edn->html {:a "<pre>"}) """))))
|
||||||
|
|
||||||
|
(deftest allow-whitespace-in-filter-test
|
||||||
|
(is (= "bar" (render "{{ foo | default:bar }}" {:dude 1}))))
|
||||||
|
|
||||||
|
;; String interopolation
|
||||||
|
|
||||||
|
;; setup namespaces, vars + alias for << tests
|
||||||
|
(def one "one")
|
||||||
|
(def y 1)
|
||||||
|
(require '[selmer.benchmark :as sb])
|
||||||
|
|
||||||
|
(deftest string-interpolation-test
|
||||||
|
(is (= "one plus one is two."
|
||||||
|
(<< "{{one}} plus {{one}} is two.")))
|
||||||
|
|
||||||
|
(let [one 1]
|
||||||
|
(is (= "1 + 1 = 2"
|
||||||
|
(<< "{{one}} + {{one}} = 2"))))
|
||||||
|
|
||||||
|
(let [one 1
|
||||||
|
one 11]
|
||||||
|
(is (= "11 + 11 = 2"
|
||||||
|
(<< "{{one}} + {{one}} = 2"))))
|
||||||
|
|
||||||
|
(is (= "selmer.benchmark/user has 10 items."
|
||||||
|
(<< "selmer.benchmark/user has {{selmer..benchmark/user|count}} items.")))
|
||||||
|
|
||||||
|
(is (= "sb/user has 10 items."
|
||||||
|
(<< "sb/user has {{sb/user|count}} items.")))
|
||||||
|
|
||||||
|
(is (= "" (let [y nil] (<< "{{y}}")))
|
||||||
|
"<< picks up local values even if they are nil")
|
||||||
|
|
||||||
|
(is (= "false" (let [y false] (<< "{{y}}")))
|
||||||
|
"<< picks up local values even if they are false"))
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue