src/view/components/root.lisp

DOWNLOAD
(defpackage murja.view.components.root
  (:use :cl :spinneret :binding-arrows
   :murja.settings
   :murja.middleware.auth
	:murja.model.user)

  (:export :*inject-to-head* :*inject-to-sidebar* :root-component)
  (:import-from :murja.posts.post-db :get-titles-by-year))

(in-package :murja.view.components.root)

(defun sidebar-tree ()
  (let* ((sidebar-titles (->>
			   (get-titles-by-year)
			   (lisp-fixup:group-by "Year"))))
    (with-html 
      (:ul :id "grouper"
	   (loop for year being the hash-keys of sidebar-titles
		 collecting (:li
			     (:details
			      (:summary (format nil "~a (~d)" year (length (gethash year sidebar-titles))))
			      (:ul 
			       (let ((by-month (lisp-fixup:group-by "Month" (gethash year sidebar-titles))))
				 (loop for month being the hash-keys of by-month
				       collecting (:li
						   (:details
						    (:summary (format nil "~a (~d)" month (length (gethash month by-month))))
						    (:ul 
						     (map 'list
							  (lambda (title)
							    (cl-hash-util:with-keys ("Id" "Title") title
							      (:li (:a :href (format nil "/blog/post/~d" Id)
								       Title))))
							  (gethash month by-month)))))))))))))))

(defun sidebar/new-post ()
  (let ((disabled-routes (list "/blog/new-post"
			       "/blog/post/editor")))
    (with-html
      (if (and *user*
	       (not (member (cl-ppcre:regex-replace "/\\d+$" (hunchentoot:request-uri*) "")
			    disabled-routes
			    :test 'equal)))
	  (:form :action "/blog/new-post" :method "post"
		 (:input :type :submit :value "NEW POST"))))))
	

(defun loginform/user-widget ()
  (with-html 
    (if *user*
	(:p :data-testid "welcome-user-label"
	    "Welcome, " (:a :href "/blog/usersettings" (user-nickname *user*)))
	(:form :method "post" :action "/api/login"
	       (:label "Username "
		       (:input :id "username" :name "username" :data-testid "username-input-field"))
	       (:label "Password "
		       (:input :id "password" :name "password" :type "password" :data-testid "password-input-field"))
	       (:input :type :submit :value "Log in")))))
  


(defvar *inject-to-head* nil)
(defvar *inject-to-sidebar* nil)
(defmacro root-component (inner-component)
  (assert inner-component)
  "Returns the root html element of murja with `inner-component` embedded inside it"
  `(format nil "<!DOCTYPE html>~%~a"
	   ;; let's make *inject-to-sidebar* request-scoped 
	   (let ((*inject-to-sidebar* nil))
	     (with-html-string 
	       (:html
		(:head
		 (:link :href "/resources/murja.css" :rel "stylesheet" :type "text/css")
		 (:meta :charset "UTF-8")
		 (dolist (head-element *inject-to-head*)
		   (funcall head-element)))
		
		(:body
		 (:header
		  (:a :href "/" (gethash "blog-title" *settings* )))

		 (:div :class "sidebar-flex"
		       ,inner-component
		       (:div :id "sidebar"
			     (sidebar/new-post)
			     (loginform/user-widget)
			     (sidebar-tree)
			     (if *inject-to-sidebar*
				 (progn (format t "*inject-to-sidebar* is something~%")
					(funcall *inject-to-sidebar*))
				 (format t "*inject-to-sidebar* is nothing~%"))))))))))