diff options
-rw-r--r-- | pages.lisp | 58 |
1 files changed, 58 insertions, 0 deletions
@@ -64,3 +64,61 @@ "the" (hero-class hero) (hero-title hero)))))) + +(defgeneric render (element) + (:documentation "Render an element as HTML")) + +(defclass page () + ((title + :reader title + :initarg :title + :documentation "Page title ") + (main + :reader main + :initarg :main + :initform "" + :documentation "Main content for a page."))) + +(defmethod render ((doc page)) + (with-html + (:doctype) + (:html + (:head (:title (title doc))) + (:body + (main doc))))) + +(defclass navable () + ((nav-links + :reader nav-links + :initarg :nav-links + :type list)) + (:documentation "Mixin for a PAGE class with navigation.")) + +(defclass nav-link () + ((target :initarg :target) + (text :initarg :text) + (icon :initarg :icon :initform nil) + (label :initarg :label :initform nil))) + +(defmethod render ((element nav-link)) + (with-slots (target icon label text) element + (with-html + (:li (:a :href target :aria-label label icon text))))) + +(defclass page-with-nav (page navable) + ()) + +(defmethod render ((doc page-with-nav)) + (with-html + (:doctype) + (:html + (:head (:title (title doc))) + (:body + (:nav (:ul (mapc #'render (nav-links doc)))) + (:main (main doc)))))) + +;; (let* ((link (make-instance +;; 'nav-link :target "/moo" :label "goo" :icon "🍺" :text "Tavern")) +;; (foo (make-instance +;; 'page-with-nav :title "goober" :main "Content" :nav-links (list link link)))) +;; (render foo)) |