|
| 1 | + |
| 2 | +;;; |
| 3 | +;;; Demo of flash messages: |
| 4 | +;;; anywhere in a route, easily add flash messages to the session. |
| 5 | +;;; They are rendered at the next rendering of a template. |
| 6 | +;;; They are removed from the session once rendered. |
| 7 | +;;; |
| 8 | + |
| 9 | +;; inspired by https://github.com/rudolfochrist/booker/blob/main/app/controllers.lisp |
| 10 | + |
| 11 | +(uiop:add-package-local-nickname :ht :hunchentoot) |
| 12 | + |
| 13 | +(djula:add-template-directory ".") |
| 14 | + |
| 15 | +(defparameter *flash-template* (djula:compile-template* "flash-template.html")) |
| 16 | + |
| 17 | +(defparameter *port* 9876) |
| 18 | + |
| 19 | +(defvar *server* nil "Our Hunchentoot acceptor") |
| 20 | + |
| 21 | +(defun flash (type message) |
| 22 | + "Add a flash message in the session. |
| 23 | +
|
| 24 | + TYPE: can be anything as you do what you want with it in the template. |
| 25 | + Here, it is a string that represents the Bulma CSS class for notifications: is-primary, is-warning etc. |
| 26 | + MESSAGE: string" |
| 27 | + (let* ((session (ht:start-session)) |
| 28 | + (flash (ht:session-value :flash session))) |
| 29 | + (setf (ht:session-value :flash session) |
| 30 | + ;; With a cons, REST returns 1 element |
| 31 | + ;; (when with a list, REST returns a list) |
| 32 | + (cons (cons type message) flash)))) |
| 33 | + |
| 34 | +;;; delete flash after it is used. |
| 35 | +(defmethod ht:handle-request :after (acceptor request) |
| 36 | + (ht:delete-session-value :flash)) |
| 37 | + |
| 38 | +#+another-solution |
| 39 | +(defun render (template &rest args) |
| 40 | + (apply |
| 41 | + #'djula:render-template* template nil |
| 42 | + (list* |
| 43 | + :flashes (or (ht:session-value :flash) |
| 44 | + (list (cons "is-primary" "No more flash messages were found in the session. This is a default notification."))) |
| 45 | + args))) |
| 46 | + |
| 47 | + |
| 48 | +(easy-routes:defroute flash-route ("/flash/" :method :get) () |
| 49 | + #-another-solution |
| 50 | + (djula:render-template* *flash-template* nil |
| 51 | + :flashes (or (ht:session-value :flash) |
| 52 | + (list (cons "is-primary" "No more flash messages were found in the session. This is a default notification.")))) |
| 53 | + #+another-solution |
| 54 | + (render *flash-template*) |
| 55 | + ) |
| 56 | + |
| 57 | +(easy-routes:defroute flash-redirect-route ("/tryflash/") () |
| 58 | + (flash "is-warning" "This is a warning message held in the session. It should appear only once: reload this page and you won't see the flash message again.") |
| 59 | + (ht:redirect "/flash/")) |
| 60 | + |
| 61 | +(defun start (&key (port *port*)) |
| 62 | + (format t "~&Starting the web server on port ~a~&" port) |
| 63 | + (force-output) |
| 64 | + (setf *server* (make-instance 'easy-routes:easy-routes-acceptor :port port)) |
| 65 | + (ht:start *server*)) |
| 66 | + |
| 67 | +(defun stop () |
| 68 | + (ht:stop *server*)) |
0 commit comments