Browse files

generate templates now 2x faster

  • Loading branch information...
1 parent db974bd commit 2acd0b0966704021b3f4c5d2f9a22997b08a2fd8 @shenfeng committed Dec 17, 2012
Showing with 48 additions and 43 deletions.
  1. +3 −4 README.md
  2. +1 −1 Rakefile
  3. +39 −33 src/me/shenfeng/mustache.clj
  4. +5 −5 test/me/shenfeng/mustache_test.clj
View
7 README.md
@@ -61,7 +61,6 @@ I initally write it for my part time project: [Rssminer](http://rssminer.net)
</ul>
```
-
### Generate functions from templates folder
templates folder:
@@ -80,15 +79,15 @@ templates
```
```clj
-(mktmpls-from-folder "templates" [".tpl"]) ; generates the clojure fn
+(gen-tmpls-from-folder "templates" [".tpl"]) ; generates the clojure fn
; now you can write something like this
(admin {:key "str" :array [1 2 3 5]})
```
### Generate functions from classpath resources
-`mktmpls-from-resouces` just like mktmpls-from-folder, except find templates files from classpath
+`gen-tmpls-from-resources` just like mktmpls-from-folder, except find templates files from classpath
### Transform template data before apply it to the template
@@ -102,7 +101,7 @@ You can pass a function (optional) to `deftemplate`, `mktmpls-from-folder`, `mkt
;; other data, like different data based on local => for i18n
))
-(mktmpls-from-folder "templates" [".tpl"] add-gloal-data)
+(gen-tmpls-from-folder "templates" [".tpl"] add-gloal-data)
```
## Performance
View
2 Rakefile
@@ -6,7 +6,7 @@ end
desc "Install in local repository"
task :install_local => :test do
sh 'lein install'
- sh 'cd ~/workspace/rssminer && lein deps'
+ # sh 'cd ~/workspace/rssminer && lein deps'
end
desc "Install in clojars repository"
View
72 src/me/shenfeng/mustache.clj
@@ -2,6 +2,7 @@
(:require [clojure.string :as str]
[clojure.java.io :as io])
(:import [me.shenfeng.mustache ResourceList Mustache Context]
+ clojure.lang.Keyword
java.io.File))
(defn mk-template [template]
@@ -20,13 +21,9 @@
(defmacro deftemplate [name template & [partials tran]]
`(let [tmpl# (Mustache/preprocess ~template)
f# (or ~tran identity)]
- (defn ~name
- ([]
- (.render tmpl# (Context. (f# {})) ~partials))
- ([data#]
- (.render tmpl# (Context. (f# data#)) ~partials))
- ([data# partial#]
- (.render tmpl# (Context. (f# data#)) (or partial# ~partials))))))
+ (defn ~name [& [data# partials#]]
+ (let [cxt# (Context. (f# (or data# {})))]
+ (.render tmpl# cxt# (or partials# ~partials))))))
(defn- get-content [file]
(slurp (or (io/resource file)
@@ -39,32 +36,41 @@
(keyword (.substring remain 0
(.lastIndexOf remain (int \.))))))
-(defn deftemplates [tmpls & [tran]]
- (doseq [[^clojure.lang.Keyword name template] tmpls]
- (let [name (str/replace (str (.sym name)) #"_|/" "-")]
- (eval `(deftemplate ~(symbol name) ~template ~tmpls ~tran)))))
+(defn- get-tmpls [files folder]
+ (reduce (fn [m f]
+ (assoc m
+ (get-name f folder) (get-content f)))
+ {} files))
-(defn- gen-vars [folder files tran]
- (let [tmpls (reduce (fn [m f]
- (assoc m
- (get-name f folder) (get-content f)))
- {} files)]
- (deftemplates tmpls tran)))
-
-;;; clear? to prent OOM when development => clears partials cache
-;;; tempalte get constantly modified and reloaded
-(defn mktmpls-from-folder [folder extentions & [tran clear?]]
- (when clear? (.clear Mustache/CACHE))
+(defn- tmpls-from-rerouces [folder extentions]
(let [^File dir (if (instance? File folder) folder (File. ^String folder))]
- (gen-vars (.getName dir)
- (map str (filter
- (fn [^File f]
- (and (.isFile f)
- (some (fn [e]
- (.endsWith (.getName f) e)) extentions)))
- (file-seq dir)))
- tran)))
+ (get-tmpls (map str
+ (filter
+ (fn [^File f]
+ (and (.isFile f)
+ (some (fn [e]
+ (.endsWith (.getName f) e)) extentions)))
+ (file-seq dir)))
+ (.getName dir))))
+
+(defn- tmpls-from-folder [folder extentions]
+ (get-tmpls (ResourceList/getResources folder extentions) folder))
+
+(defn- fn-name [name] ; app/search_result => app-search-result
+ (symbol (str/replace (str (.sym ^Keyword name)) #"_|/" "-")))
+
+(defmacro gen-tmpls-from-folder [folder extentions & [tran]]
+ (.clear Mustache/CACHE) ; clear paritials cache
+ (let [tmpls (tmpls-from-folder folder extentions)
+ defs (map (fn [[name template]]
+ `(deftemplate ~(fn-name name) ~template ~tmpls ~tran))
+ tmpls)]
+ `(do ~@defs)))
-(defn mktmpls-from-resouces [folder extentions & [tran clear?]]
- (when clear? (.clear Mustache/CACHE))
- (gen-vars folder (ResourceList/getResources folder extentions) tran))
+(defmacro gen-tmpls-from-resources [folder extentions & [tran]]
+ (.clear Mustache/CACHE) ; clear paritials cache
+ (let [tmpls ^:const (tmpls-from-rerouces folder extentions)
+ defs (map (fn [[name template]]
+ `(deftemplate ~(fn-name name) ~template ~tmpls ~tran))
+ tmpls)]
+ `(do ~@defs)))
View
10 test/me/shenfeng/mustache_test.clj
@@ -46,12 +46,12 @@
(dotimes [i 100000] ; warm up
(template data))
-(deftemplates {:name_one "{{name}}"
- :name_two "Hello {{name}}, {{>name_one}}"})
+;; (deftemplates {:name_one "{{name}}"
+;; :name_two "Hello {{name}}, {{>name_one}}"})
-(deftest test-deftemplates
- (is (= (name-one {:name "abc"}) "abc"))
- (is (= (name-two {:name "abc"}) "Hello abc, abc")))
+;; (deftest test-deftemplates
+;; (is (= (name-one {:name "abc"}) "abc"))
+;; (is (= (name-two {:name "abc"}) "Hello abc, abc")))
(println "Perf test: Render 100k Times\n"
(slurp "test/tpl.tpl")

0 comments on commit 2acd0b0

Please sign in to comment.