feat(grfn/bbbg): Display flash messages
Get flash working via a functioning cookie-store session middleware, and display flash messages if present at the top of every page. Change-Id: If5f267dee3f41ef7954ea82667822c596e1b0474
This commit is contained in:
parent
e7899e6c0b
commit
0286d63df7
5 changed files with 98 additions and 18 deletions
|
@ -8,7 +8,8 @@
|
||||||
[cheshire.core :as json]
|
[cheshire.core :as json]
|
||||||
[compojure.core :refer [GET POST routes]]
|
[compojure.core :refer [GET POST routes]]
|
||||||
[honeysql.helpers :refer [merge-where]]
|
[honeysql.helpers :refer [merge-where]]
|
||||||
[ring.util.response :refer [content-type redirect response]]))
|
[ring.util.response :refer [content-type redirect response]]
|
||||||
|
[bbbg.views.flash :as flash]))
|
||||||
|
|
||||||
(defn attendees-routes [{:keys [db]}]
|
(defn attendees-routes [{:keys [db]}]
|
||||||
(routes
|
(routes
|
||||||
|
@ -38,5 +39,20 @@
|
||||||
(db.event/attended! db {::event/id event_id
|
(db.event/attended! db {::event/id event_id
|
||||||
::attendee/id attendee_id})
|
::attendee/id attendee_id})
|
||||||
(-> (redirect (str "/signup-forms/" event_id))
|
(-> (redirect (str "/signup-forms/" event_id))
|
||||||
(assoc :flash "Thank you for signing in! Enjoy the event.")))
|
(assoc-in [:session :test] 1)
|
||||||
|
(flash/add-flash
|
||||||
|
#:flash{:type :success
|
||||||
|
:message "Thank you for signing in! Enjoy the event."})))
|
||||||
(response "Something went wrong")))))
|
(response "Something went wrong")))))
|
||||||
|
|
||||||
|
(comment
|
||||||
|
(def db (:db bbbg.core/system))
|
||||||
|
(db/list db
|
||||||
|
(->
|
||||||
|
(db.attendee/search "gr")
|
||||||
|
(db.attendee/for-event #uuid "9f4f3eae-3317-41a7-843c-81bcae52aebf")))
|
||||||
|
(honeysql.format/format
|
||||||
|
(->
|
||||||
|
(db.attendee/search "gr")
|
||||||
|
(db.attendee/for-event #uuid "9f4f3eae-3317-41a7-843c-81bcae52aebf")))
|
||||||
|
)
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
(ns bbbg.handlers.core
|
(ns bbbg.handlers.core
|
||||||
(:require
|
(:require
|
||||||
|
[bbbg.views.flash :as flash]
|
||||||
[hiccup.core :refer [html]]
|
[hiccup.core :refer [html]]
|
||||||
[ring.util.response :refer [content-type response]]))
|
[ring.util.response :refer [content-type response]]))
|
||||||
|
|
||||||
|
@ -7,7 +8,7 @@
|
||||||
(let [[{:keys [title]} body]
|
(let [[{:keys [title]} body]
|
||||||
(if (map? opts)
|
(if (map? opts)
|
||||||
[opts body]
|
[opts body]
|
||||||
[{} (into [opts] body)])]
|
[{} (concat [opts] body)])]
|
||||||
(html
|
(html
|
||||||
[:html {:lang "en"}
|
[:html {:lang "en"}
|
||||||
[:head
|
[:head
|
||||||
|
@ -19,7 +20,9 @@
|
||||||
:type "text/css"
|
:type "text/css"
|
||||||
:href "/main.css"}]]
|
:href "/main.css"}]]
|
||||||
[:body
|
[:body
|
||||||
(into [:div.content] body)
|
[:div.content
|
||||||
|
(flash/render-flash)
|
||||||
|
body]
|
||||||
[:script {:src "https://cdnjs.cloudflare.com/ajax/libs/tarekraafat-autocomplete.js/10.2.6/autoComplete.js"}]
|
[:script {:src "https://cdnjs.cloudflare.com/ajax/libs/tarekraafat-autocomplete.js/10.2.6/autoComplete.js"}]
|
||||||
[:script {:src "/main.js"}]]])))
|
[:script {:src "/main.js"}]]])))
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,8 @@
|
||||||
[bbbg.event :as event]
|
[bbbg.event :as event]
|
||||||
[bbbg.handlers.core :refer [page-response]]
|
[bbbg.handlers.core :refer [page-response]]
|
||||||
[compojure.core :refer [context GET POST]]
|
[compojure.core :refer [context GET POST]]
|
||||||
[ring.util.response :refer [redirect]]))
|
[ring.util.response :refer [redirect]]
|
||||||
|
[bbbg.views.flash :as flash]))
|
||||||
|
|
||||||
(defn events-index [events]
|
(defn events-index [events]
|
||||||
[:ul.events-list
|
[:ul.events-list
|
||||||
|
@ -41,4 +42,5 @@
|
||||||
(let [event (db.event/create! db {::event/date date})]
|
(let [event (db.event/create! db {::event/date date})]
|
||||||
(-> (str "/signup-forms/" (::event/id event))
|
(-> (str "/signup-forms/" (::event/id event))
|
||||||
redirect
|
redirect
|
||||||
(assoc-in [:flash :message] "Event Created"))))))
|
(flash/add-flash {:flash/type :success
|
||||||
|
:flash/message "Event Created"}))))))
|
||||||
|
|
33
users/grfn/bbbg/src/bbbg/views/flash.clj
Normal file
33
users/grfn/bbbg/src/bbbg/views/flash.clj
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
(ns bbbg.views.flash
|
||||||
|
(:require [clojure.spec.alpha :as s]))
|
||||||
|
|
||||||
|
(s/def :flash/type #{:success :error :warning})
|
||||||
|
(s/def :flash/message string?)
|
||||||
|
(s/def ::flash (s/keys :req [:flash/type :flash/message]))
|
||||||
|
(s/fdef add-flash :args (s/cat :resp map? :flash ::flash) :ret map?)
|
||||||
|
|
||||||
|
;;;
|
||||||
|
|
||||||
|
(def ^:dynamic *flash* nil)
|
||||||
|
|
||||||
|
(defn wrap-page-flash [handler]
|
||||||
|
(fn
|
||||||
|
([request]
|
||||||
|
(binding [*flash* (:flash request)]
|
||||||
|
(handler request)))
|
||||||
|
([request respond raise]
|
||||||
|
(binding [*flash* (:flash request)]
|
||||||
|
(handler request respond raise)))))
|
||||||
|
|
||||||
|
(defn add-flash [resp flash]
|
||||||
|
(update-in resp [:flash :flash/messages] conj flash))
|
||||||
|
|
||||||
|
(defn render-flash
|
||||||
|
([] (render-flash *flash*))
|
||||||
|
([flash]
|
||||||
|
(when-some [messages (not-empty (:flash/messages flash))]
|
||||||
|
[:ul.flash-messages
|
||||||
|
(for [message messages]
|
||||||
|
[:li.flash-message
|
||||||
|
{:class (str "flash-" (-> message :flash/type name))}
|
||||||
|
(:flash/message message)])])))
|
|
@ -5,6 +5,8 @@
|
||||||
[bbbg.handlers.home :as home]
|
[bbbg.handlers.home :as home]
|
||||||
[bbbg.handlers.signup-form :as signup-form]
|
[bbbg.handlers.signup-form :as signup-form]
|
||||||
[bbbg.styles :refer [stylesheet]]
|
[bbbg.styles :refer [stylesheet]]
|
||||||
|
[bbbg.util.core :as u]
|
||||||
|
[bbbg.views.flash :refer [wrap-page-flash]]
|
||||||
[clojure.spec.alpha :as s]
|
[clojure.spec.alpha :as s]
|
||||||
[com.stuartsierra.component :as component]
|
[com.stuartsierra.component :as component]
|
||||||
[compojure.core :refer [GET routes]]
|
[compojure.core :refer [GET routes]]
|
||||||
|
@ -13,23 +15,44 @@
|
||||||
[ring.middleware.flash :refer [wrap-flash]]
|
[ring.middleware.flash :refer [wrap-flash]]
|
||||||
[ring.middleware.keyword-params :refer [wrap-keyword-params]]
|
[ring.middleware.keyword-params :refer [wrap-keyword-params]]
|
||||||
[ring.middleware.params :refer [wrap-params]]
|
[ring.middleware.params :refer [wrap-params]]
|
||||||
[ring.util.response :refer [content-type response resource-response]]))
|
[ring.middleware.session :refer [wrap-session]]
|
||||||
|
[ring.middleware.session.cookie :refer [cookie-store]]
|
||||||
|
[ring.util.response :refer [content-type resource-response response]])
|
||||||
|
(:import
|
||||||
|
java.util.Base64))
|
||||||
|
|
||||||
(s/def ::port pos-int?)
|
(s/def ::port pos-int?)
|
||||||
|
|
||||||
|
(s/def ::cookie-secret
|
||||||
|
(s/and bytes? #(= 16 (count %))))
|
||||||
|
|
||||||
(s/def ::config
|
(s/def ::config
|
||||||
(s/keys :req [::port]))
|
(s/keys :req [::port]
|
||||||
|
:opt [::cookie-secret]))
|
||||||
|
|
||||||
(s/fdef make-server
|
(s/fdef make-server
|
||||||
:args (s/cat :config ::config))
|
:args (s/cat :config ::config))
|
||||||
|
|
||||||
|
|
||||||
|
(defn- string->cookie-secret [raw]
|
||||||
|
(s/assert
|
||||||
|
::cookie-secret
|
||||||
|
(when raw
|
||||||
|
(.decode (Base64/getDecoder)
|
||||||
|
(.getBytes raw "UTF-8")))))
|
||||||
|
|
||||||
(defn env->config []
|
(defn env->config []
|
||||||
(s/assert
|
(s/assert
|
||||||
::config
|
::config
|
||||||
{::port (:port env 8888)}))
|
(u/remove-nils
|
||||||
|
{::port (:port env 8888)
|
||||||
|
::cookie-secret (some-> env :cookie-secret string->cookie-secret)})))
|
||||||
|
|
||||||
(defn dev-config []
|
(defn dev-config []
|
||||||
(s/assert ::config {::port 8888}))
|
(s/assert
|
||||||
|
::config
|
||||||
|
{::port 8888
|
||||||
|
::cookie-secret (into-array Byte/TYPE (repeat 16 0))}))
|
||||||
|
|
||||||
;;;
|
;;;
|
||||||
|
|
||||||
|
@ -47,17 +70,19 @@
|
||||||
(events/events-routes env)
|
(events/events-routes env)
|
||||||
(home/home-routes env)))
|
(home/home-routes env)))
|
||||||
|
|
||||||
(defn middleware [app]
|
(defn middleware [app env]
|
||||||
(-> app
|
(-> app
|
||||||
wrap-keyword-params
|
wrap-keyword-params
|
||||||
wrap-params
|
wrap-params
|
||||||
wrap-flash))
|
wrap-page-flash
|
||||||
|
wrap-flash
|
||||||
|
(wrap-session {:store (cookie-store {:key (:cookie-secret env)})})))
|
||||||
|
|
||||||
(defn handler [this]
|
(defn handler [env]
|
||||||
(middleware
|
(-> (app-routes env)
|
||||||
(app-routes this)))
|
(middleware env)))
|
||||||
|
|
||||||
(defrecord WebServer [port db]
|
(defrecord WebServer [port cookie-secret db]
|
||||||
component/Lifecycle
|
component/Lifecycle
|
||||||
(start [this]
|
(start [this]
|
||||||
(assoc this
|
(assoc this
|
||||||
|
@ -71,7 +96,8 @@
|
||||||
(dissoc this ::shutdown-fn))
|
(dissoc this ::shutdown-fn))
|
||||||
this)))
|
this)))
|
||||||
|
|
||||||
(defn make-server [{::keys [port]}]
|
(defn make-server [{::keys [port cookie-secret]}]
|
||||||
(component/using
|
(component/using
|
||||||
(map->WebServer {:port port})
|
(map->WebServer {:port port
|
||||||
|
:cookie-secret cookie-secret})
|
||||||
[:db]))
|
[:db]))
|
||||||
|
|
Loading…
Reference in a new issue