Priyatam Mudivarti
Templates
client apis
Build Tools
Responsive Design
Events
Dom
Performance
Modules
3rd party libs
Javascript
event handling, dynamic, ajax, json
CSS3/Less/Sass
rules, selectors,
responsive design
HTML5
markup , templating, dom
(def a-vector [1 2 3 4 5])
(def a-nested-map
{:customer-id 1e6
:preferences {:nickname "Bob"
:avatar "http://en.gravatar.com/userimage/0/0.jpg"}
:services {:alerts {:daily true}}})
(def complex-map
{[1 2] :one-two
[3 4] :three-four})
(def a-set
#{:cat :dog :bird})
;; Unlike JavaScript there is no hoisting in ClojureScript. ClojureScript has lexical scoping.
(def some-x 1)
(let [some-x 2]
some-x)
;; functions parameters, let bindings locals, and loop locals are not mutable!
(let [fns (loop [i 0 ret []]
(if (< i 10)
(recur (inc i) (conj ret (fn [] i)))
ret))]
(map #(%) fns))
; simple function
(defn add [a b]
(+ a b))
;; function with multiple args and default values
(defn another-function
([x] (defaults x :default))
([x y] [x y]))
;; closure
(let [a 1e3]
(defn foo []
(* a a))
(defn bar []
(+ (foo) a)))
;; higher order functions
;; list comprehension
(for [x (range 1 10)
y (range 1 10)
:when (and (zero? (rem x y))
(even? (quot x y)))]
[x y])
;; higher order functions over sequences
(map inc [0 1 2 3 4 5 6 7 8 9])
(filter even? (range 10))
(reduce + (range 100))
(partition 2 [:a 1 :b 2 :c 3 :d 4 :e 5])
(remove odd? (range 10))
(take 5 (interleave (repeat "red") (repeat "blue")))
;; Protocols, a.k,a Interfaces
(defprotocol MyProtocol (awesome [this]))
(extend-protocol MyProtocol
js/Date
(awesome [_] "Having an awesome time!")
number
(awesome [_] "I'm an awesome number!"))
(awesome #inst "2014")
(awesome 5)
;; handler
(defn my-ip [request]
{:status 200
:headers {"Content-Type" "text/plain"}
:body (:remote-addr request)})
;; middleware
(defn wrap-content-type [handler content-type]
(fn [request]
(let [response (handler request)]
(assoc-in response [:headers "Content-Type"] content-type))))
(defn wrap-content-type [handler content-type]
(fn [request]
(let [response (handler request)]
(assoc-in response [:headers "Content-Type"] content-type))))
(defn json-response [data & [status]]
{:status (or status 200)
:headers {"Content-Type" "application/edn"}
:body (pr-str data)})
(def app
(wrap-content-type my-ip "text/html"))
(defn serve [request]
(app request))
;; Routes
(defroutes routes
(GET "/" [] (str "Server is running"))
(GET "/ws" [] handle-websocket)
(context
"/api" []
(GET "/languages" []
(let [prog (get-in db/data [:languages])]
(when prog
(edn-response prog))))
(GET "/languages/:id/:type" [id type]
(let [stats (filter #(and
(= (:id %) id) (= (:type %) type))
(get-in db/data [:stats]))]
(when stats
(response stats)))))))
(def app
(->
(handler/site router/routes)
(wrap-json-body)
(wrap-json-response)
(wrap-edn-params)
(wrap-defaults api-defaults)
(wrap-cors
:access-control-allow-origin #".+"
:access-control-allow-methods [:get :post :put :delete :head]
:access-control-allow-headers ["Content-Type" "X-Requested-With"])))
(defn -main [& _]
(let [port (Integer. (or (System/getenv "SERVER_PORT") 8000))]
(server/run-server app {:port port :join? false})
(log/info "Server started and listening at port..." port)))
Abstract HTTP
Write idiomatic code
Run on any web server
Bare Metal
Easy to Test
Live Coding
no namespaces
can't compose HTML and CSS in the same syntax
css doesn’t “talk to dom”
math impl is hard
can we pass css as functions at runtime?
mixins are not composable
constrained by limitations—not by choice
(defn create-minimal-grid [clazz pad]
[[:* {:box-sizing "border-box"}]
[clazz {:background "white"
:margin [[0 0 pad 0]]}
[:&:after {:content ""
:display "table"
:clear "both"}]
["[class*='col-']" {:float "left"
:padding-right pad }]
[:.col-1-3 {:width "33.33%"}]
[:.col-2-3 {:width "66.66%"}]
[:.col-1-2 {:width "50.00%"}]
[:.col-1-4 {:width "25.00%"}]
[:.col-1-8 {:width "12.50%"}]
[:.out-padding {:padding [[pad 0 pad pad pad]]}
["[class*='col-']:last-of-type"
{:padding-right pad}]]]])
(defn default-layout
"Creates a tiled layout with n 'views' stacked on top, with a help
view floated to the right.
For more info see https://bulma.io/documentation/layout/tiles/"
[help-section & views]
[:div {:class "tile is-ancestor"}
[:div {:class "tile is-1 is-vertical"}]
[:div {:class "tile is-7 is-vertical is-parent"}
(for [view views]
^{:key view} [:div {:class "tile is-child"}
view])]
[:div {:class "tile is-2 is-parent"}
help-section]])