| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- (in-package :cl-user)
- (restas:define-module #:assboard.web
- (:use :cl :hunchentoot :assboard.utils))
- (in-package #:assboard.web)
- ;; Parameters
- (setf (who:html-mode) :html5)
- (defclass renderer () ())
- (restas::register-pkgmodule-traits
- 'assboard.web
- :render-method (lambda () (make-instance 'assboard.web::renderer)))
- ;; Rendering
- (defgeneric finalize-page (data)
- (:documentation "Final rendering step"))
- (defgeneric render-route-data (route data)
- (:documentation "Process route-specific data"))
- (defmethod finalize-page ((data list))
- (who:with-html-output-to-string (out nil :prologue t)
- (:html
- (:head
- (:meta :charset "utf-8")
- (:meta :http-equiv "X-UA-Compatible" :content "IE=edge")
- (:meta :name "viewport" :content "width=device-width, initial-scale=1")
- (:title (who:str (getf data :title)))
- (:link :rel "stylesheet" :href (restas:genurl 'static/css :file "styles.css")))
- (:body
- (who:str (getf data :menu))
- (who:str (getf data :content))))))
- (defmethod render-route-data (route data)
- (list*
- :title (getf data :title "AssBoard")
- data))
- (defmethod restas:render-object ((designer renderer) (object list))
- (let ((full-data (render-route-data (restas:route-symbol restas:*route*)
- object)))
- (finalize-page full-data)))
- (defun posts-list (posts)
- (who:with-html-output-to-string (out)
- (:ul
- (loop for post in posts
- :do (who:htm
- (:li
- (:a :href (restas:genurl 'posting :id (data::posting-id post))
- (who:str (data::posting-title post)))
- " by "
- (:a :href (restas:genurl 'author
- :author (data::posting-author post))
- (who:str (data::posting-author post)))))))))
- (defmethod render-route-data ((route (eql 'index)) (posts list))
- (list
- :title "AssBoard"
- :content
- (who:with-html-output-to-string (out)
- (:h1 "AssBoard open postings")
- (who:str (posts-list posts)))))
- (restas:define-route index ("")
- (pomo:query-dao
- 'data::posting
- (:select 'id 'author 'status 'title 'maintainer 'created-on
- :from 'posting)))
- (defmethod restas:render-object ((designer renderer) (object data::posting))
- (finalize-page
- (list
- :title (format nil "~A by ~A @ AssBoard"
- (data::posting-title object)
- (data::posting-author object))
- :content
- (who:with-html-output-to-string (out)
- (:h1 (who:str (data::posting-title object)))
- (:p (who:str (data::posting-body object)))))))
- (restas:define-route posting ("posting/:id/")
- (let ((post (pomo:get-dao 'data::posting id)))
- (if post post
- hunchentoot:+HTTP-NOT-FOUND+)))
- (defmethod render-route-data ((route (eql 'author)) (data list))
- (list
- :title (format nil "~A's postings @ AssBoard" (getf data :author))
- :content
- (who:with-html-output-to-string (out)
- (:h1 (who:str (getf data :author)) "'s postings")
- (who:str (posts-list (getf data :posts))))))
- (restas:define-route author ("author/:author/")
- (let ((posts (pomo:query-dao
- 'data::posting
- (:select 'id 'author 'status 'title 'maintainer 'created-on
- :from 'posting
- :where (:= 'author author)))))
- (if posts
- (list :author author :posts posts)
- hunchentoot:+HTTP-NOT-FOUND+)))
- (restas:define-route static/css ("css/:file" :content-type "text/css")
- (let ((css-path (merge-pathnames "css/" +project-path+)))
- (merge-pathnames file css-path)))
|