From 2be10a3b137d7bcc75b02884ddbe72608f85f9b0 Mon Sep 17 00:00:00 2001 From: colin Date: Mon, 20 Feb 2023 17:49:42 -0800 Subject: Refactor: to use render protocol --- pages.lisp | 105 ++++++++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 90 insertions(+), 15 deletions(-) (limited to 'pages.lisp') diff --git a/pages.lisp b/pages.lisp index c435e8f..f279aa9 100644 --- a/pages.lisp +++ b/pages.lisp @@ -2,26 +2,57 @@ (in-package :dnd) +;;; RENDER PROTOCOL + +(defgeneric render (view object &key) + (:documentation "Render OBJECT as VIEW. VIEW could be anything, but it is intended to +be a keyword for usin in EQL method specializers.")) + +(defmacro defrender (view (spec &rest kwargs) &body body) + "A helper macro for defining specializations of render." + (let ((viewvar (gensym))) + `(defmethod render ((,viewvar (eql ,view)) ,spec &key ,@kwargs) + ,@body))) + +(defrender :list ((data list) (class "listview") (item-class "listitem")) + "A catch all for rendering lists of renderable data items as unordered +lists. CLASS is the lass string for the containing list. ITEM-CLASS is +the class string for the contained list items." + (with-html + (:ol :class class + (dolist (item data) + (:li (render :list-item item :class item-class)))))) + +(defrender :three-column-layout (data) + "A catch all specialization for rendering data in three columns. You +must specialize :left :milsddle :right on your desired data type." + (with-html + (:div :class "three-column-layout" + (:div :class "left-column" (render :left data)) + (:div :class "middle-column" (render :middle data)) + (:div :class "right-column" (render :right data))))) + +;;; PAGES + (defmacro with-page ((&key title) &body body) + "A helper macro fordefining some standard page boilerplate." `(with-html-string (:doctype) (:html (:head (:title ,title)) - (:body ,@body)))) + (:body + ,@body)))) -(defun godess-shrine () - (with-page (:title "A Sacred Shrine") - (:header - (:h1 "Pray and become a hero...")) - (:form :method "POST" :action "/godess-shrine" - (:label :for "NAME" "Enter the epithet by which the ages shall know thy hero:") - (:input :name "NAME") - (:button :type "submit" "Pray To The Goddess")))) +(defclass/std doorkeeper () + ((message))) (defun doorkeeper (&key (message "Come ye player, Wot's yer name?")) + (render :page (make-instance 'doorkeeper :message message ))) + +(defrender :page ((page doorkeeper)) (with-page (:title "Tavern Door") - (:h1 message) + (:h1 (message page)) (:form :method "POST" :action "/tavern-door" (:label :for "NICK" "Wut's yer handle?:") (:input :name "NICK") @@ -29,7 +60,20 @@ (:h2 "Eh? Ye need to announce thyeself?") (:a :href "/register" "Follow me..."))) -(defun register () +(defclass/std goddess-shrine () ()) + +(defrender :page ((page goddess-shrine)) + (with-page (:title "A Sacred Shrine") + (:header + (:h1 "Pray and become a hero...")) + (:form :method "POST" :action "/godess-shrine" + (:label :for "NAME" "Enter the epithet by which the ages shall know thy hero:") + (:input :name "NAME") + (:button :type "submit" "Pray To The Goddess")))) + +(defclass/std player-registration () ()) + +(defrender :page ((page player-registration)) (with-page (:title "Register Player") (:header (:h1 "Choose a Nickname Player")) @@ -38,13 +82,44 @@ (:input :name "NICK" :placeholder "superbob") (:button :type "submit" "Register")))) +(defun register () + (render :page (make-instance 'player-registration))) + +(defclass/std tavern () + ((player alerts))) + (defun tavern (player) + (print "MOO") + (render :page (make-instance 'tavern :player player))) + +(defrender :page ((tavern tavern)) (with-page (:title "A Bustling Tavern") (navbar) - (:div - :class "heroes-container" - (:h2 "Heroes of rampant renown:") - (hall-of-heroes)))) + (render :three-column-layout tavern))) + +(defrender :left ((tavern tavern)) + (let ((player (player tavern))) + (with-html + (render :details player) + (:h4 "Your Heroes") + (render :list (player-heroes player))))) + +(defrender :middle ((tavern tavern)) + (with-html + (:h4 "Your Campaigns ") + (render :list (player-campaigns (player tavern))))) + +(defrender :right ((tavern tavern)) + (with-html + (:h4 "Gossip & Gab") + (render :list (alerts tavern)) + (:h4 "Comrades in Arms") + (render :list (fetch-comrades (player tavern))))) + +(defrender :details ((player player)) + (with-html + (:div :class "player details" + (:h3 "Welcome " (player-nick player))))) (defun navbar () (with-html -- cgit v1.2.3