From c040acba1a8c389d1e4da7332eb4ba2cc58d7edb Mon Sep 17 00:00:00 2001
From: Adam <adam@adambard.com>
Date: Fri, 5 Sep 2014 22:56:25 +0200
Subject: Added compojure

---
 compojure.html.markdown | 225 ++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 225 insertions(+)
 create mode 100644 compojure.html.markdown

(limited to 'compojure.html.markdown')

diff --git a/compojure.html.markdown b/compojure.html.markdown
new file mode 100644
index 00000000..56f43cb7
--- /dev/null
+++ b/compojure.html.markdown
@@ -0,0 +1,225 @@
+---
+category: tool
+tool: compojure
+contributors:
+    - ["Adam Bard", "http://adambard.com/"]
+filename: learncompojure.clj
+---
+
+## Getting Started with Compojure
+
+Compojure is a DSL for *quickly* creating *performant* web applications
+in Clojure with minimal effort:
+
+```clojure
+(ns myapp.core
+  (:require [compojure.core :refer :all]
+            [org.httpkit.server :refer [run-server]])) ; httpkit is a server
+
+(defroutes myapp
+  (GET "/" [] "Hello World"))
+
+(defn -main []
+  (run-server myapp {:port 5000}))
+```
+
+Create a project with [Leiningen](http://leiningen.org/):
+
+```
+lein new myapp
+```
+
+Add your dependencies:
+
+```
+[compojure "1.1.8"]
+[http-kit "2.1.16"]
+```
+
+And run:
+
+```
+lein run -m myapp.core
+```
+
+View at: <http://localhost:5000/>
+
+Compojure apps will run on any ring-compatible server, but we recommend
+[http-kit](http://http-kit.org/) for its performance and
+[massive concurrency](http://http-kit.org/600k-concurrent-connection-http-kit.html).
+
+### Routes
+
+In compojure, each route is an HTTP method paired with a URL-matching pattern,
+an argument list, and a body.
+
+```clojure
+(defroutes myapp
+  (GET "/" [] "Show something")
+  (POST "/" [] "Create something")
+  (PUT "/" [] "Replace something")
+  (PATCH "/" [] "Modify Something")
+  (DELETE "/" [] "Annihilate something")
+  (OPTIONS "/" [] "Appease something")
+  (HEAD "/" [] "Preview something"))
+```
+
+Compojure route definitions are just functions which
+[accept request maps and return response maps](https://github.com/mmcgrana/ring/blob/master/SPEC):
+
+```clojure
+(myapp {:uri "/" :request-method :post})
+; => {:status 200
+;     :headers {"Content-Type" "text/html; charset=utf-8}
+;     :body "Create Something"}
+```
+
+The body may be a function, which must accept the request as a parameter:
+
+```clojure
+(defroutes myapp
+  (GET "/" [] (fn [req] "Do something with req")))
+```
+
+Route patterns may include named parameters,
+
+```clojure
+(defroutes myapp
+  (GET "/hello/:name" [name] (str "Hello " name)))
+```
+
+You can match entire paths with *
+
+```clojure
+(defroutes myapp
+  (GET "/file/*.*" [*] (str *)))
+```
+
+Handlers may utilize query parameters:
+
+```clojure
+(defroutes myapp
+  (GET "/posts" []
+       (fn [req]
+         (let [title (get (:params req) "title")
+               author (get (:params req) "title")]
+           " Do something with title and author"))))
+```
+
+Or, for POST and PUT requests, form parameters
+
+```clojure
+(defroutes myapp
+  (POST "/posts" []
+       (fn [req]
+         (let [title (get (:params req) "title")
+               author (get (:params req) "title")]
+           "Do something with title and author"))))
+```
+
+
+### Return values
+
+The return value of a route block determines at least the response body
+passed on to the HTTP client, or at least the next middleware in the
+ring stack. Most commonly, this is a string, as in the above examples.
+But, you may also return a [response body](https://github.com/mmcgrana/ring/blob/master/SPEC):
+
+```clojure
+(defroutes myapp
+  (GET "/" []
+       {:status 200 :body "Hello World"})
+  (GET "/is-403" []
+       {:status 403 :body ""})
+  (GET "/is-json" []
+       {:status 200 :headers {"Content-Type" "application/json"} :body "{}"}))
+```
+
+### Static Files
+
+To serve up static files, use `compojure.route.resources`.
+Resources will be served from your project's `resources/` folder.
+
+```clojure
+(require '[compojure.route :as route])
+
+(defroutes myapp
+  (GET "/")
+  (route/resources "/")) ; Serve static resources at the root path
+
+(myapp {:uri "/js/script.js" :request-method :get})
+; => Contents of resources/public/js/script.js
+```
+
+### Views / Templates
+
+To use templating with Compojure, you'll need a template library. Here are a few:
+
+#### [Stencil](https://github.com/davidsantiago/stencil)
+
+[Stencil](https://github.com/davidsantiago/stencil) is a [Mustache](http://mustache.github.com/) template library:
+
+```clojure
+(require '[stencil.core :refer [render-string]])
+
+(defroutes myapp
+  (GET "/hello/:name" [name]
+       (render-string "Hello {{name}}" {:name name})))
+```
+
+You can easily read in templates from your resources directory. Here's a helper function
+
+```clojure
+(require 'clojure.java.io)
+
+(defn read-template [filename]
+  (slurp (clojure.java.io/resource filename)))
+
+(defroutes myapp
+  (GET "/hello/:name" [name]
+       (render-string (read-template "templates/hello.html") {:name name})))
+```
+
+#### [Selmer](https://github.com/yogthos/Selmer)
+
+[Selmer](https://github.com/yogthos/Selmer) is a Django and Jinja2-inspired templating language:
+
+```clojure
+(require '[selmer.parser :refer [render-file]])
+
+(defroutes myapp
+  (GET "/hello/:name" [name]
+       (render-file "templates/hello.html" {:name name})))
+```
+
+#### [Hiccup](https://github.com/weavejester/hiccup)
+
+[Hiccup](https://github.com/weavejester/hiccup) is a library for representing HTML as Clojure code
+
+```clojure
+(require '[hiccup.core :as hiccup])
+
+(defroutes myapp
+  (GET "/hello/:name" [name]
+       (hiccup/html
+         [:html
+           [:body
+             [:h1 {:class "title"}
+                  (str "Hello " name)]]])))
+```
+
+#### [Markdown](https://github.com/yogthos/markdown-clj)
+
+[Markdown-clj](https://github.com/yogthos/markdown-clj) is a Markdown implementation.
+
+```clojure
+(require '[markdown.core :refer [md-to-html-string]])
+
+(defroutes myapp
+  (GET "/hello/:name" [name]
+       (md-to-html-string "## Hello, world")))
+```
+
+Further reading:
+
+[Clojure for the Brave and True](http://www.braveclojure.com/)
-- 
cgit v1.2.3


From 014262f5c62ae1904b5e70135aca8c56540abc78 Mon Sep 17 00:00:00 2001
From: Adam <adam@adambard.com>
Date: Sat, 6 Sep 2014 10:18:31 +0200
Subject: Updated compojure per weavejester's suggestions

---
 compojure.html.markdown | 60 ++++++++++++++++++++++++++++---------------------
 1 file changed, 35 insertions(+), 25 deletions(-)

(limited to 'compojure.html.markdown')

diff --git a/compojure.html.markdown b/compojure.html.markdown
index 56f43cb7..1644dfb7 100644
--- a/compojure.html.markdown
+++ b/compojure.html.markdown
@@ -81,18 +81,26 @@ The body may be a function, which must accept the request as a parameter:
   (GET "/" [] (fn [req] "Do something with req")))
 ```
 
-Route patterns may include named parameters,
+Or, you can just use the request directly:
+
+```clojure
+(defroutes myapp
+  (GET "/" req "Do something with req"))
+```
+
+Route patterns may include named parameters:
 
 ```clojure
 (defroutes myapp
   (GET "/hello/:name" [name] (str "Hello " name)))
 ```
 
-You can match entire paths with *
+You can adjust what each parameter matches by supplying a regex:
 
 ```clojure
 (defroutes myapp
-  (GET "/file/*.*" [*] (str *)))
+  (GET ["/file/:name.:ext" :name #".*", :ext #".*"] [name ext]
+    (str "File: " name ext)) 
 ```
 
 Handlers may utilize query parameters:
@@ -100,10 +108,10 @@ Handlers may utilize query parameters:
 ```clojure
 (defroutes myapp
   (GET "/posts" []
-       (fn [req]
-         (let [title (get (:params req) "title")
-               author (get (:params req) "title")]
-           " Do something with title and author"))))
+    (fn [req]
+      (let [title (get (:params req) "title")
+            author (get (:params req) "title")]
+        " Do something with title and author"))))
 ```
 
 Or, for POST and PUT requests, form parameters
@@ -111,10 +119,10 @@ Or, for POST and PUT requests, form parameters
 ```clojure
 (defroutes myapp
   (POST "/posts" []
-       (fn [req]
-         (let [title (get (:params req) "title")
-               author (get (:params req) "title")]
-           "Do something with title and author"))))
+    (fn [req]
+      (let [title (get (:params req) "title")
+            author (get (:params req) "title")]
+        "Do something with title and author"))))
 ```
 
 
@@ -123,16 +131,16 @@ Or, for POST and PUT requests, form parameters
 The return value of a route block determines at least the response body
 passed on to the HTTP client, or at least the next middleware in the
 ring stack. Most commonly, this is a string, as in the above examples.
-But, you may also return a [response body](https://github.com/mmcgrana/ring/blob/master/SPEC):
+But, you may also return a [response map](https://github.com/mmcgrana/ring/blob/master/SPEC):
 
 ```clojure
 (defroutes myapp
   (GET "/" []
-       {:status 200 :body "Hello World"})
+    {:status 200 :body "Hello World"})
   (GET "/is-403" []
-       {:status 403 :body ""})
+    {:status 403 :body ""})
   (GET "/is-json" []
-       {:status 200 :headers {"Content-Type" "application/json"} :body "{}"}))
+    {:status 200 :headers {"Content-Type" "application/json"} :body "{}"}))
 ```
 
 ### Static Files
@@ -164,7 +172,7 @@ To use templating with Compojure, you'll need a template library. Here are a few
 
 (defroutes myapp
   (GET "/hello/:name" [name]
-       (render-string "Hello {{name}}" {:name name})))
+    (render-string "Hello {{name}}" {:name name})))
 ```
 
 You can easily read in templates from your resources directory. Here's a helper function
@@ -177,7 +185,7 @@ You can easily read in templates from your resources directory. Here's a helper
 
 (defroutes myapp
   (GET "/hello/:name" [name]
-       (render-string (read-template "templates/hello.html") {:name name})))
+    (render-string (read-template "templates/hello.html") {:name name})))
 ```
 
 #### [Selmer](https://github.com/yogthos/Selmer)
@@ -189,7 +197,7 @@ You can easily read in templates from your resources directory. Here's a helper
 
 (defroutes myapp
   (GET "/hello/:name" [name]
-       (render-file "templates/hello.html" {:name name})))
+    (render-file "templates/hello.html" {:name name})))
 ```
 
 #### [Hiccup](https://github.com/weavejester/hiccup)
@@ -201,11 +209,11 @@ You can easily read in templates from your resources directory. Here's a helper
 
 (defroutes myapp
   (GET "/hello/:name" [name]
-       (hiccup/html
-         [:html
-           [:body
-             [:h1 {:class "title"}
-                  (str "Hello " name)]]])))
+    (hiccup/html
+      [:html
+        [:body
+          [:h1 {:class "title"}
+            (str "Hello " name)]]])))
 ```
 
 #### [Markdown](https://github.com/yogthos/markdown-clj)
@@ -217,9 +225,11 @@ You can easily read in templates from your resources directory. Here's a helper
 
 (defroutes myapp
   (GET "/hello/:name" [name]
-       (md-to-html-string "## Hello, world")))
+    (md-to-html-string "## Hello, world")))
 ```
 
 Further reading:
 
-[Clojure for the Brave and True](http://www.braveclojure.com/)
+* [Official Compojure Documentation](https://github.com/weavejester/compojure/wiki)
+
+* [Clojure for the Brave and True](http://www.braveclojure.com/)
-- 
cgit v1.2.3


From c0d8a18b08d114dd0142a09f6787c7221b423802 Mon Sep 17 00:00:00 2001
From: Adam <adam@adambard.com>
Date: Sat, 6 Sep 2014 10:28:58 +0200
Subject: Made beginning easier

---
 compojure.html.markdown | 8 +++++---
 1 file changed, 5 insertions(+), 3 deletions(-)

(limited to 'compojure.html.markdown')

diff --git a/compojure.html.markdown b/compojure.html.markdown
index 1644dfb7..96555273 100644
--- a/compojure.html.markdown
+++ b/compojure.html.markdown
@@ -23,20 +23,22 @@ in Clojure with minimal effort:
   (run-server myapp {:port 5000}))
 ```
 
-Create a project with [Leiningen](http://leiningen.org/):
+**Step 1:** Create a project with [Leiningen](http://leiningen.org/):
 
 ```
 lein new myapp
 ```
 
-Add your dependencies:
+**Step 2:** Put the above code in `src/myapp/core.clj`
+
+**Step 3:** Add some dependencies to `project.clj`:
 
 ```
 [compojure "1.1.8"]
 [http-kit "2.1.16"]
 ```
 
-And run:
+**Step 4:** Run:
 
 ```
 lein run -m myapp.core
-- 
cgit v1.2.3