Templates & Snippets

The deftemplate construct defines a function that performs a set of transforms on a remote or compiled resource and returns the resulting dom objects as a dom fragment. This allows the developer to bring in external html files, possibly developed by a designer, and work with them unaltered.

note: Remote resources are pulled down through ajax and cached on the client as dom fragments. Compiled resources are bundled with the exported javascript.

;remote
(deftemplate my-template resource-uri [arg1 arg2 ...] 
  selector1 (transform arg1)
  selector2 (transform arg2))

;compiled - recommended
(deftemplate my-template :compiled resource-uri [arg1 arg2 ...] 
  selector1 (transform arg1)
  selector2 (transform arg2))

Example: view remote resource

table will appear here

The following action is triggered when we click the button

(em/deftemplate template-demo "/templates/template-demo.html" [fruit-data] 
   "#heading1" (em/content "fruit")  
   "thead tr > *:last-child" (em/content "quantity")
   "tbody > tr:not(:first-child)" (em/remove-node)
   "tbody > tr:first-child" (em/clone-for [fr (vec fruit-data)]
                               "*:first-child" (em/content (first fr))
                               "*:last-child" (em/content (str (second fr)))))

(em/at "#button1" (em/listen :click 
                    #(em/at "#template-demo" (em/content (template-demo)))))             
The code above pulls back template-demo.html, replaces the heading with "fruit" and "quantity", deletes all but the first row of the table and finally uses clone-for to duplicate the first row and build the table.

defsnippet defines a function that performs a set of transforms on a subsection of a remote or compiled resource and returns the resulting dom objects as a dom fragment. This allows the developer to bring in external html files and use pieces to build the final view.

note: Remote resources are pulled down and cached on the client as dom fragments. Compiled resources are bundled with the exported javascript.

;remote
(defsnippet my-snippet resource-uri [selector] [arg1 arg2 ...]
  selector1 (transform arg1)
  selector2 (transform arg2))

;compiled
(defsnippet my-snippet :compiled resource-uri [selector] [arg1 arg2 ...]
  selector1 (transform arg1)
  selector2 (transform arg2))

Example: view remote resource

table will appear here

The following action is triggered when we click the button

(em/defsnippet snippet2 "templates/template-demo.html" "tbody > *:first-child" 
  [fruit quantity] 
  "tr > *:first-child" (em/content fruit)
  "tr > *:last-child" (em/content (str quantity)))
  
(em/deftemplate template-demo2 "/templates/template-demo.html" [fruit-data] 
  "#heading1" (em/content "fruit")  
  "thead tr > *:last-child" (em/content "quantity")
  "tbody" (em/content
            (map #(snippet2 % (fruit-data %)) (keys fruit-data)))) 
                           
(em/at "#button2" (em/listen :click 
                    #(em/at "#snippet-demo" 
                             (em/content (template-demo2 {"apple" 6, "pear" 5})))))              

The code above pull back template-demo.html, replaces the heading with "fruit" and "quantity", and finally iterates over the fruit data and calls our snippet to build the rows of the table.

This type of template allows you to construct an html dom fragment by passing in a clojure data structure representing the html elements.

(html [:tag1#id1  [:tag2.class2 {:atr1 "v1" :art2 "v2"}]])

Example:

Input box will appear here.

The following action is triggered when we click the button

(defn my-hic-template [val]
  (ef/html [:tr '([:td "hiccup"] [:td "test"]) {:name "form1"}]))

(em/defaction hiccup-demo []
  "#hic-demo tbody" (ef/append (my-hic-template "testing")))

Due to the asynchronous nature of pulling in remote resources this helper function is needed. It takes an function and calls the function once all templates have been loaded.

note: Remote resources are pulled down and cached on the client as dom fragments.

(wait-for-load (fn []...))