Skip to content

Commit

Permalink
Templating WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
zk committed Oct 17, 2011
1 parent 27f0556 commit dbf9ed1
Show file tree
Hide file tree
Showing 4 changed files with 139 additions and 2 deletions.
46 changes: 46 additions & 0 deletions notes/general.org
Expand Up @@ -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!




5 changes: 3 additions & 2 deletions project.clj
Expand Up @@ -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"]])


58 changes: 58 additions & 0 deletions 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?))

32 changes: 32 additions & 0 deletions 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)))))


0 comments on commit dbf9ed1

Please sign in to comment.