Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Templating WIP

  • Loading branch information...
commit dbf9ed1ecf3a37cec933056143a60996e8cede65 1 parent 27f0556
@zk authored
View
46 notes/general.org
@@ -23,3 +23,49 @@ Basic directory structure
+<2011-10-16 Sun 16:47>
+
+* Template Dependencies
+
+Need a way to define dependencies (html, css, javascript) locally, and
+have them bubble up to the top level:
+
+#+BEGIN_SRC
+{:html
+#+END_SRC
+
+** HTML
+Options:
++ hiccup format [:div {:class "foo"}], etc.
+ + Allows for easier instrospection (has html? has etc).
++ String
+ + More difficult, need to use string manipulation to insert.
+
+Going with hiccup format for now.
+
+
+* Ordering
+
+Asset ordering (order of css, javascript) matters. How am I going to
+handle this?
+
+I'd like to provide
+
+* Escaping
+
+Have to provide a way to 'escape' templates, meaning that js and css
+tags aren't pulled out of source.
+
++ [:link {:rel "stylesheet" :href "foo.css" :escape true]
++ Require each template be wrapped in a top-level structure denoting a
+ template:
+ - {:template [:link {:rel "stylesheet" :href "foo.css"]
+ :escape true}
+
+I kind of like the first one, but the template marker will be passed
+on to the rendered html. Or not... Pull it from the structure on
+parsing!
+
+
+
+
View
5 project.clj
@@ -10,8 +10,9 @@
[net.cgrand/moustache "1.0.0"]
[nstools "0.2.4"]
[slingshot "0.2.0"]
- [clj-http "0.1.3"]]
- :dev-dependencies [[swank-clojure "1.2.0"]
+ [clj-http "0.1.3"]
+ [midje "1.2.0"]]
+ :dev-dependencies [[swank-clojure "1.4.0-SNAPSHOT"]
[lein-clojars "0.6.0"]])
View
58 src/nsfw/templating.clj
@@ -0,0 +1,58 @@
+(ns nsfw.templating
+ "Dependency management for web templates."
+ (:require [clojure.zip :as zip]))
+
+(defn has-tag?
+ "DFS for tag."
+ [tag template]
+ (loop [ptr (zip/vector-zip template)]
+ (cond
+ (zip/end? ptr) false
+ (= tag (zip/node ptr)) true
+ :else (recur (zip/next ptr)))))
+
+(def has-html? (partial has-tag? :html))
+
+(defn is-stylesheet-link? [node]
+ (and (coll? node)
+ (= :link (first node))
+ (map? (second node))
+ (= "stylesheet" (get (second node) :rel))))
+
+(defn is-style-tag? [node]
+ (and (coll? node)
+ (= :style (first node))))
+
+(defn is-css-tpl? [tpl]
+ (or (is-stylesheet-link? tpl)
+ (is-style-tag? tpl)))
+
+(defn is-css-ptr? [ptr]
+ (is-css-tpl? (zip/node ptr)))
+
+(defn is-js-tpl? [node]
+ (and (coll? node)
+ (= :script (first node))
+ (map? (second node))
+ (= "text/javascript" (get (second node) :type))))
+
+(defn is-js-ptr? [ptr]
+ (is-js-tpl? (zip/node ptr)))
+
+
+(defn collect-tags [tag-pred tpl]
+ (loop [ptr (zip/vector-zip tpl)
+ css-coll []]
+ (if (zip/end? ptr)
+ {:template (zip/root ptr) :css-coll css-coll}
+ (recur (if (tag-pred ptr)
+ (zip/next (zip/remove ptr))
+ (zip/next ptr))
+ (if (tag-pred ptr)
+ (conj css-coll (zip/node ptr))
+ css-coll)))))
+
+(def collect-css (partial collect-tags is-css-ptr?))
+
+(def collect-js (partial collect-tags is-js-ptr?))
+
View
32 test/nsfw/test/templating.clj
@@ -0,0 +1,32 @@
+(ns nsfw.test.templating
+ (:use nsfw.templating :reload)
+ (:use clojure.test)
+ (:require [clojure.zip :as zip]))
+
+(deftest test-has-html?
+ (are [res template] (= res (has-html? template))
+ true [:html [:div.foo "bar"]]
+ true [:div.bar [:html [:head [:title "foobar"]]]]
+ false [:div [:div [:div]]]))
+
+(deftest test-is-css-tpl?
+ (are [res template] (= res (is-css-tpl? template))
+ true [:link {:rel "stylesheet"}]
+ true [:style "p { color: blue; }"]
+ false [:foo [:link {:rel "stylesheet"}]]))
+
+(deftest test-is-js-tpl?
+ (are [res template] (= res (is-js-tpl? template))
+ true [:script {:type "text/javascript"}]
+ false [:script]))
+
+(deftest test-collect-css
+ (let [res (collect-css [:html
+ [:head
+ [:link {:rel "stylesheet" :href "foo.css"}]
+ [:link {:rel "stylesheet" :href "bar.css"}]]])]
+ (is (= [[:link {:rel "stylesheet" :href "foo.css"}]
+ [:link {:rel "stylesheet" :href "bar.css"}]]
+ (:css-coll res)))))
+
+
Please sign in to comment.
Something went wrong with that request. Please try again.