Skip to content

Commit 66ec255

Browse files
committed
wip
1 parent 885b831 commit 66ec255

File tree

5 files changed

+70
-19
lines changed

5 files changed

+70
-19
lines changed

src/pogonos/context.cljc

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
(ns pogonos.context
2+
(:require [clojure.string :as str]
3+
[pogonos.protocols :as proto]))
4+
5+
(defn- lookup* [stack keys]
6+
(if-let [k (peek keys)]
7+
(when-let [v (loop [stack stack]
8+
(when-let [v (peek stack)]
9+
(if (and (map? v)
10+
(not #?(:clj (identical? (v k ::none) ::none)
11+
:cljs (keyword-identical? (v k ::none) ::none))))
12+
v
13+
(recur (next stack)))))]
14+
(if (next keys)
15+
(get-in v keys)
16+
(v k)))
17+
(peek stack)))
18+
19+
(defrecord NonCheckingContext [stack]
20+
proto/IContext
21+
(lookup [_ keys]
22+
(lookup* stack keys))
23+
(push [_ val]
24+
(NonCheckingContext. (conj stack val))))
25+
26+
(defrecord CheckingContext [stack on-missing-key]
27+
proto/IContext
28+
(lookup [_ keys]
29+
(or (lookup* stack keys)
30+
(on-missing-key stack keys)))
31+
(push [_ val]
32+
(CheckingContext. (conj stack val) on-missing-key)))
33+
34+
(defmulti ^:private ->on-missing-key-fn (fn [x] x))
35+
36+
(defmethod ->on-missing-key-fn :default [x]
37+
(if (fn? x)
38+
x
39+
(throw
40+
(ex-info (str ":on-missing-key must be :error or a function, but got " (type x)) {}))))
41+
42+
(defmethod ->on-missing-key-fn :error [_]
43+
(fn [stack keys]
44+
(let [k (->> keys (map name) (str/join \.))]
45+
(throw (ex-info (str "Key \"" k "\" not found in the given context")
46+
{:key k :context (last stack)})))))
47+
48+
(defn make-context
49+
([data] (make-context data {}))
50+
([data {:keys [on-missing-key]}]
51+
(let [stack (list data)]
52+
(if on-missing-key
53+
(->CheckingContext stack (->on-missing-key-fn on-missing-key))
54+
(->NonCheckingContext stack)))))

src/pogonos/core.cljc

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
(ns pogonos.core
22
(:require #?(:clj [clojure.java.io :as io])
3+
[pogonos.context :as context]
34
[pogonos.error :as error]
45
[pogonos.nodes :as nodes]
56
[pogonos.output :as output]
@@ -103,14 +104,14 @@
103104
(merge opts)
104105
fixup-options)
105106
out (output)]
106-
(render/render (list data) out template opts)
107+
(render/render (context/make-context data opts) out template opts)
107108
(out))))
108109

109110
(defn render-input
110111
([in data]
111112
(render-input in data {}))
112113
([in data opts]
113-
(let [ctx (list data)
114+
(let [ctx (context/make-context data opts)
114115
{:keys [output]
115116
:as opts} (fixup-options opts #?(:clj partials/resource-partials))
116117
out (output)]

src/pogonos/protocols.cljc

+4
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,10 @@
99
(defprotocol ToReader
1010
(->reader [this]))
1111

12+
(defprotocol IContext
13+
(lookup [this keys])
14+
(push [this val]))
15+
1216
(defprotocol IRenderable
1317
(render [this ctx out]))
1418

src/pogonos/render.cljc

+4-15
Original file line numberDiff line numberDiff line change
@@ -35,18 +35,7 @@
3535
:cljs (gstr/htmlEscape s)))
3636

3737
(defn lookup [ctx keys]
38-
(if-let [k (peek keys)]
39-
(when-let [v (loop [ctx ctx]
40-
(when-let [v (peek ctx)]
41-
(if (and (map? v)
42-
(not #?(:clj (identical? (v k ::none) ::none)
43-
:cljs (keyword-identical? (v k ::none) ::none))))
44-
v
45-
(recur (next ctx)))))]
46-
(if (next keys)
47-
(get-in v keys)
48-
(v k)))
49-
(peek ctx)))
38+
(proto/lookup ctx keys))
5039

5140
(defn render* [ctx out x]
5241
(if (string? x)
@@ -93,12 +82,12 @@
9382

9483
(map? val)
9584
(doseq [node (:nodes this)]
96-
(render* (conj ctx val) out node))
85+
(render* (proto/push ctx val) out node))
9786

9887
(and (coll? val) (sequential? val))
9988
(when (seq val)
10089
(doseq [e val, node (:nodes this)]
101-
(render* (conj ctx e) out node)))
90+
(render* (proto/push ctx e) out node)))
10291

10392
(fn? val)
10493
(let [{:keys [open close]} (meta this)
@@ -113,7 +102,7 @@
113102

114103
:else
115104
(doseq [node (:nodes this)]
116-
(render* (conj ctx val) out node)))))
105+
(render* (proto/push ctx val) out node)))))
117106

118107
#?(:clj Inverted :cljs nodes/Inverted)
119108
(render [this ctx out]

test/pogonos/render_test.cljc

+5-2
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
(ns pogonos.render-test
22
(:require [clojure.string :as str]
33
[clojure.test :refer [deftest are testing]]
4+
[pogonos.context :as context]
45
[pogonos.render :as render]
56
[pogonos.nodes :as nodes]
67
[pogonos.output :as output]))
78

89
(deftest lookup-test
9-
(are [ctx keys expected] (= expected (render/lookup ctx keys))
10+
(are [ctx keys expected]
11+
(= expected (render/lookup (context/->NonCheckingContext ctx) keys))
1012
'({:x 42})
1113
'(:x)
1214
42
@@ -36,7 +38,8 @@
3638
(render template data nil))
3739
([template data partials]
3840
(let [out ((output/to-string))]
39-
(render/render (list data) out
41+
(render/render (context/make-context data)
42+
out
4043
(nodes/->Root template)
4144
{:partials partials})
4245
(out))))

0 commit comments

Comments
 (0)