refactoring extension stuff to improve pebble engine initialization

much of this refactoring is built around the idea of absolutely NOT
wanting applications using this library to be required to explicitly
call some kind of "init" function before templates can be rendered.

however, for this library's (eventual) unit tests, we will want the
ability to reset the engine state (reset-engine! function), so a way
to add extensions to an arbitrary PebbleEngine object is needed
This commit is contained in:
Gered 2014-10-07 18:37:42 -04:00
parent b4533dad0d
commit 26c6eb2f06
2 changed files with 60 additions and 39 deletions

View file

@ -3,62 +3,35 @@
(java.util Map) (java.util Map)
(com.mitchellbosecke.pebble PebbleEngine) (com.mitchellbosecke.pebble PebbleEngine)
(com.mitchellbosecke.pebble.loader ClasspathLoader FileLoader StringLoader) (com.mitchellbosecke.pebble.loader ClasspathLoader FileLoader StringLoader)
(com.mitchellbosecke.pebble.template PebbleTemplate) (com.mitchellbosecke.pebble.template PebbleTemplate))
(com.mitchellbosecke.pebble.extension Function Filter Test)) (:require [clojure.walk :refer [stringify-keys]]
(:require [clojure.walk :refer [stringify-keys]])) [clj-pebble.extensions :as ext]
[clj-pebble.standard-extensions :as std]))
(defonce classpath-loader (ClasspathLoader.)) (defonce classpath-loader (ClasspathLoader.))
(defonce file-loader (FileLoader.)) (defonce file-loader (FileLoader.))
(defonce string-loader (StringLoader.)) (defonce string-loader (StringLoader.))
(defn- make-pebble-engine [] (defn- make-pebble-engine []
(PebbleEngine. classpath-loader)) (-> (PebbleEngine. classpath-loader)
(ext/add-extensions-library! std/extensions)))
(defonce engine (atom (make-pebble-engine))) (defonce engine (atom (make-pebble-engine)))
(defn reset-engine! [] (defn reset-engine! []
(reset! engine (make-pebble-engine))) (reset! engine (make-pebble-engine)))
(defn- get-sorted-args [args-map]
(->> args-map
(map
(fn [[k v]]
[(Integer/parseInt k) v]))
(sort-by first)
(map second)))
(defn make-function [f]
(reify Function
(getArgumentNames [_] nil)
(execute [_ args]
(apply f (get-sorted-args args)))))
(defn make-filter [f]
(reify Filter
(getArgumentNames [_] nil)
(apply [_ input args]
(apply f (concat [input] (get-sorted-args args))))))
(defn make-test [f]
(reify Test
(getArgumentNames [_] nil)
(apply [_ input args]
(boolean (apply f (concat [input] (get-sorted-args args)))))))
(defmacro defpebblefn [fn-name args & body] (defmacro defpebblefn [fn-name args & body]
`(let [f# (fn ~args ~@body) `(let [f# (fn ~args ~@body)]
pebble-fn# (make-function f#)] (ext/add-function! @engine ~fn-name f#)))
(.put (.getFunctions @engine) ~fn-name pebble-fn#)))
(defmacro defpebblefilter [filter-name args & body] (defmacro defpebblefilter [filter-name args & body]
`(let [f# (fn ~args ~@body) `(let [f# (fn ~args ~@body)]
pebble-fn# (make-filter f#)] (ext/add-filter! @engine ~filter-name f#)))
(.put (.getFilters @engine) ~filter-name pebble-fn#)))
(defmacro defpebbletest [test-name args & body] (defmacro defpebbletest [test-name args & body]
`(let [f# (fn ~args ~@body) `(let [f# (fn ~args ~@body)]
pebble-fn# (make-test f#)] (ext/add-test! @engine ~test-name f#)))
(.put (.getTests @engine) ~test-name pebble-fn#)))
(defn- prepare-context-map [context] (defn- prepare-context-map [context]
(if context (if context

View file

@ -0,0 +1,48 @@
(ns clj-pebble.extensions
(:import (java.util Map)
(com.mitchellbosecke.pebble PebbleEngine)
(com.mitchellbosecke.pebble.extension Function Filter Test)))
(defn- get-sorted-args [args-map]
(->> args-map
(map
(fn [[k v]]
[(Integer/parseInt k) v]))
(sort-by first)
(map second)))
(defn make-function [f]
(reify Function
(getArgumentNames [_] nil)
(execute [_ args]
(apply f (get-sorted-args args)))))
(defn make-filter [f]
(reify Filter
(getArgumentNames [_] nil)
(apply [_ input args]
(apply f (concat [input] (get-sorted-args args))))))
(defn make-test [f]
(reify Test
(getArgumentNames [_] nil)
(apply [_ input args]
(boolean (apply f (concat [input] (get-sorted-args args)))))))
(defn add-function! [^PebbleEngine engine ^String name f]
(.put (.getFunctions engine) name (make-function f)))
(defn add-filter! [^PebbleEngine engine ^String name f]
(.put (.getFilters engine) name (make-filter f)))
(defn add-test! [^PebbleEngine engine ^String name f]
(.put (.getTests engine) name (make-test f)))
(defn add-extensions-library! [^PebbleEngine engine {:keys [functions filters tests]}]
(doseq [[name func] functions]
(add-function! engine name func))
(doseq [[name func] filters]
(add-filter! engine name func))
(doseq [[name func] tests]
(add-test! engine name func))
engine)