Skip to content
Permalink
Browse files

Update docs

  • Loading branch information...
swlkr committed Mar 23, 2019
1 parent bd3acf5 commit 5b44ac2bc8f0d67ef6c0ea6e01b1a4edb1a4635e
Showing with 110 additions and 71 deletions.
  1. +9 −10 docs/authentication.md
  2. +9 −17 docs/middleware.md
  3. +2 −2 docs/request.md
  4. +53 −9 docs/routing.md
  5. +12 −14 docs/sessions.md
  6. +7 −5 docs/upgrading.md
  7. +4 −5 docs/validator.md
  8. +14 −9 docs/views.md
@@ -97,16 +97,15 @@ Let's start with the auth middleware, that checks that a session exists before c
[middleware]
(def routes
(coast/routes
(coast/site-routes
[:get "/sign-up" :member/build]
[:post "/members" :member/create]
[:get "/sign-in" :session/build]
[:post "/sessions" :session/create]
(coast/wrap-routes middleware/auth
[:get "/dashboard" :member/dashboard]
[:delete "/sessions" :sessions/delete]))))
(coast/site
[:get "/sign-up" :member/build]
[:post "/members" :member/create]
[:get "/sign-in" :session/build]
[:post "/sessions" :session/create]
(coast/with middleware/auth
[:get "/dashboard" :member/dashboard]
[:delete "/sessions" :sessions/delete]))))
```
Now create three new handler function definitions `build` and `create` in the `src/member.clj` file:
@@ -75,36 +75,28 @@ In fact, while coast is a "web app framework", the `app` function is really just
Route middleware can modify the request before the functions you write and modify the response map after.
Even `404`'s are middleware functions that come from `(coast/site-routes)`.
Even `404`'s are middleware functions that come from `(coast/site)`.
Coast calls four functions on every route defined underneath `site-routes`:
Coast calls one function on every route defined underneath `site`:
```clojure
(def routes
(coast/routes
(coast/site-routes :option-layout-fn
(coast/site
(coast/with-layout :layout-fn
[:get "/posts" :post/index]
[:post "/posts" :post/create]
[:404 :home/not-found]
[:500 :home/server-error])))
```
1. wrap-layout
2. wrap-site-defaults
3. wrap-not-found
4. wrap-site-errors
#### `wrap-layout`
This function wraps any [hiccup](https://github.com/weavejester/hiccup) vector returned from functions that you write in the `function` you specify as the fist argument to `site-routes`.
#### `wrap-site-defaults`
This function wraps common website options, csrf protection, content-type headers, etc. from [ring's own defaults](https://github.com/ring-clojure/ring-defaults)
#### `wrap-not-found`
This function catches any coast exception maps with a `:404` key and returns your specified `[:404 :home/not-found]` 404 function (in this case `:home/not-found` or `home.clj`'s `not-found` function).
This function wraps common website options, csrf protection, etc. from [ring's own defaults](https://github.com/ring-clojure/ring-defaults)
#### `with-layout`
#### `wrap-site-errors`
This is similar to not found, except it catches any exceptions thrown by your code and returns your specified `:500` handler, which is by default `:home/server-error`.
This function wraps all of the routes below it in the layout function defined which takes two arguments,
the
### Middleware Options
Coast can receive several options to the various middleware functions.
@@ -114,10 +114,10 @@ In Coast you can separate json responses and html responses at the router level
; routes.clj
(def routes
(coast/routes
(coast/site-routes
(coast/site
[:get "/" :home/index])
(coast/api-routes
(coast/api
[:get "/api" :api.home/index])))
```
@@ -24,7 +24,7 @@ The most basic route definition requires an http method, a url and a "pointer" t
{:status 200 :body "hello world!" :headers {"content-type" "text/html"}}
(def routes
(coast/routes
(coast/site
[:get "/" ::home]))
```
@@ -148,7 +148,7 @@ overrides any layouts or the coast default of rendering with html.
(defn json [request]
(coast/ok {:message "ok"} :json)) ; same as above, but shorter
(coast/api-routes
(coast/api
[:get "/" ::json)])
```
@@ -161,11 +161,11 @@ You can define separate routes for an api and a site:
(def routes
(coast/routes
; this route corresponds to the src/site/home.clj index function
(coast/site-routes
(coast/site
[:get "/" :home/index :site.home/index])
; these routes correspond to the src/api/home.clj index and status functions
(coast/api-routes
(coast/api
[:get "/api" :api.home/index]
[:get "/api/status" :api.home/status])))
@@ -174,7 +174,7 @@ You can define separate routes for an api and a site:
Coast uses a different set of middleware functions when responding to an api request vs a site request.
The `api-routes` do not check for layouts and a host of other things, making them lighter-weight than their site counterparts.
The `api` routes do not check for layouts and a host of other things, making them lighter-weight than their site counterparts.
## Route Resources
@@ -229,13 +229,13 @@ You can wrap middleware around any resource as you would with a single route:
(ns routes
(:require [coast]))
(defn wrap-auth [handler]
(defn auth [handler]
(fn [request]
(if (some? (:session request))
(handler request)
(coast/unauthorized [:h1 "HAL9000 says, \"Sorry Dave, I can't let you do that\""]))))
(coast/wrap-routes wrap-auth
(coast/with auth
[:resource :post]))
```
@@ -260,10 +260,54 @@ If your application routes share common urls, instead of repeating the same urls
Assign one or many middleware to the route group:
```clojure
(coast/wrap-routes wrap-auth
(coast/with auth
(coast/prefix-routes "/api/v1"
[:get "/members"
[:post "/members"]]))
```
NOTE: Route middleware executes before app middleware.
NOTE: Route middleware executes after app middleware during the request and before app middleware during the response.
Route middleware also executes from top to bottom:
```clojure
(ns routes
(:require [coast]
[middleware]))
(def routes
(coast/site
(coast/with middleware/set-title
(coast/with-layout :components/layout
[:get "/" :home/index]
[:get "/docs" :home/docs]
[:get "/docs/:doc.md" :home/doc]
[:get "/screencast" :home/screencast]
[:get "/sign-up" :member/build]
[:post "/members" :member/create]
[:get "/sign-in" :session/build]
[:post "/sessions" :session/create]
[:resource :invite :only [:build :create]]
(coast/with middleware/auth
[:get "/dashboard" :home/dashboard]
[:delete "/sessions" :session/delete]
[:resource :member :except [:index :view :build :create]]
[:resource :invite :except [:index :view :build :create]]
[:resource :post :only [:build :create :edit :change :delete]]
[:put "/invite/:invite-id/approve" :invite/approve])
[:resource :post :only [:view :index]]))
[:404 :home/not-found]
[:500 :home/server-error]))
```
In this example (from the coast docs site), the route middleware executes in this order:
1. coast/site <-- this wraps the routes in ring defaults functions for html returning routes
2. middleware/set-title
3. components/layout
4. middleware/auth
@@ -63,7 +63,7 @@ feel free to use middleware:
```clojure
; src/middleware.clj
(defn wrap-auth [handler]
(defn auth [handler]
(fn [request]
(let [person (get-in request [:session :person/id])]
(if (some? person)
@@ -77,14 +77,13 @@ Then you can wrap the routes that require auth:
; src/routes.clj
(def routes
(coast/routes
(coast/site-routes
[:get "/" :home/index]
[:get "/sign-in" :session/build]
[:post "/sessions" :sessions/create]
(coast/wrap-routes middleware/wrap-auth
[:get "/dashboard" :home/dashboard]))))
(coast/site
[:get "/" :home/index]
[:get "/sign-in" :session/build]
[:post "/sessions" :sessions/create]
(coast/with middleware/auth
[:get "/dashboard" :home/dashboard]))))
```
## Flash messages
@@ -109,11 +108,10 @@ Then, add the `/customers` routes to validate form data:
```clojure
(def routes
(coast/routes
(coast/site-routes
[:get "/customers/build" :customer/build]
[:post "/customers" :customer/create])))
[:get "/customers/:customer-id" :customer/view])))
(coast/site
[:get "/customers/build" :customer/build]
[:post "/customers" :customer/create]
[:get "/customers/:customer-id" :customer/view]))
```
...and implement the handler
@@ -218,8 +218,8 @@ Routing has changed in a few ways, before you had to nest route vectors in anoth
(:require [coast]))
(def routes
(coast/routes
(coast/site-routes :components/layout
(coast/site
(coast/with-layout :components/layout
[:get "/" :home/index]
[:get "/posts" :post/index]
[:get "/posts/:id" :post/view]
@@ -230,7 +230,9 @@ Routing has changed in a few ways, before you had to nest route vectors in anoth
[:post "/posts/:id/delete" :post/delete])))
```
Before you had to wrap all vectors in another vector, now you don't it makes things a little cleaner. Also multiple layout support per batch of routes is easier as well since you no longer have to pass layout in `app`.
Before you had to wrap all vectors in another vector, now you don't it makes things a little cleaner.
Also multiple layout support per batch of routes is easier as well since you no longer pass `:layout` into app. Simply wrap any routes with `with-layout` and give that a function with two arguments and you're in business.
Since the vector of vectors confusion is gone now, routes more naturally lend themselves to function helpers and resource-style url formats:
@@ -240,8 +242,8 @@ Since the vector of vectors confusion is gone now, routes more naturally lend th
(:require [coast]))
(def routes
(coast/routes
(coast/site-routes :components/layout
(coast/site
(coast/with-layout :components/layout
[:resource :posts]
; is equal to all of the below routes
@@ -18,11 +18,10 @@ Make the routes to show the form and handle the submission:
; src/routes.clj
(def routes
(coast/routes
(coast/site-routes
[:get "/posts/:post-id/edit" :post/edit]
[:put "/posts/:post-id" :post/change]
[:get "/posts/:post-id" :post/view])))
(coast/site
[:get "/posts/:post-id/edit" :post/edit]
[:put "/posts/:post-id" :post/change]
[:get "/posts/:post-id" :post/view])))
```
Make the handler functions to show the form
@@ -36,9 +36,8 @@ Make a route that will render some html:
```clojure
; src/routes.clj
(def routes
(coast/routes
(coast/site-routes
[:get "/" :home/index])))
(coast/site
[:get "/" :home/index])))
```
```clojure
@@ -104,15 +103,20 @@ Adds a `script` tag to a JS bundle
(coast/js "bundle.js")
; assuming the assets.edn looks like this
{"bundle.js" ["app.js"]}
{"bundle.js" ["app.js" "app2.js"]}
```
The code above outputs:
```html
<script type="text/javascript" src="/app.js"></script>
<script type="text/javascript" src="/app2.js"></script>
```
in development.
NOTE: In production, the assets are bundled and minified into one js file and one css file.
#### url-for
Returns the URL for a route.
@@ -286,12 +290,13 @@ Here's an example:
(def routes
(coast/routes
(coast/site-routes :my-layout-function
[:get "/" :home/index]
[:resource :customer]
(coast/site
(coast/with-layout :my-layout-function
[:get "/" :home/index]
[:resource :customer]
(coast/site-routes :my-other-layout-function
[:get "/other-route" :other/route]))))
(coast/with-layout :my-other-layout-function
[:get "/other-route" :other/route])))))
```
## Syntax

0 comments on commit 5b44ac2

Please sign in to comment.
You can’t perform that action at this time.