;;;; * Utilities (defmethod reorder-list ((list list) new-order) (loop for n in new-order collect (nth n list))) (defun find-all-subclasses (class) (loop for class in (mopp:class-direct-subclasses class) collect class into classes finally (return (nconc classes (loop for class in classes nconc (find-all-subclasses class)))))) ;;;; * Content Store ;;;; For the sake of keeping it simple, ;;;; we are going to store all the content in a single EQUAL hash-table. ;;;; this is somewhat naive, but will do for now. (defclass content-store () ((store :accessor store :initform (make-hash-table :test #'equalp)) (place :accessor place :initform "content-store"))) (defvar *content* (make-instance 'content-store)) (defmethod find-content ((store content-store) name) (gethash name (store store))) (defmethod (setf find-content) (content (store content-store) name) (setf (gethash name (store store)) content)) (defmethod save-content ((store content-store)) (cl-store:store store (place store))) (defmethod restore-content ((store content-store)) (cl-store:restore (place store))) (defun content (name) (find-content *content* name)) (defun (setf content) (value name) (setf (find-content *content* name) value)) (defun store-content () (save-content *content*)) ;;;; ;;;; ** Content Items ;;;; TODO: I'm missing a DEFCLASS/META macro and it shows. (defclass content () ((name :accessor name :initarg :name :initform nil)) (:documentation "The superclass of all content items")) (defmethod initialize-instance :around ((self content) &rest initargs) (let ((content (content (getf initargs :name)))) (cond (content (setf content (apply #'reinitialize-instance content initargs))) (t (setf content (call-next-method)))) (setf (content (name content)) content) content)) (defclass simple-content (content) ((title :accessor title :initarg :title :initform "") (show-title-p :accessor show-title-p :initarg :show-title-p :initform t) (body :accessor body :initarg :body :initform ""))) (lol:define-meta-model simple-content () ((title :type string) (body :type string) (name :type string) (show-title-p :type boolean))) (lol:set-default-attributes 'simple-content) (defclass content-container (content) ((contents :accessor contents :initarg :contents) (title :accessor title :initarg :title :initform nil))) (lol:define-meta-model content-container () ((contents :type string))) (lol:set-default-attributes 'content-container) ;;;; the lack of inheritance in the meta model shows here. ;;;; perhaps the next iteration should include that feature. (defclass faq-container (content-container) ((show-title-p :accessor show-title-p :initarg :show-title-p :initform t))) (lol:define-meta-model faq-container () ((contents :type string) (title :type string) (show-title-p :type boolean))) (lol:set-default-attributes 'faq-container) (defclass faq-item (simple-content) ()) (lol:define-meta-model faq-item () ((title :type string) (body :type string) (name :type string) (show-title-p :type boolean))) (lol:set-default-attributes 'faq-item) (lol:define-attributes (simple-content faq-item) (body mewa::text) (show-title-p mewa::mewa-boolean) (:one-line t :attributes (title)) (:viewer content-viewer) (:editor content-editor :attributes (name title show-title-p (body :type dojo-editor)))) (lol:define-attributes (content-container faq-container) (:viewer content-list-presentation) (:listing sortable-list-editor) (:one-line t :attributes (title))) (lol:define-attributes (faq-container) (:viewer faq-presentation)) (lol:define-attributes (faq-item) (:viewer faq-item-presentation)) ;;;; ** Restore Content on Startup : ;;;; *** This should perhaps be moved to start.lisp (let ((content (restore-content *content*))) (if content (setf *content* content))) (defcomponent content-presentation (lol::mewa-viewer) ()) (defmethod editablep ((self content-presentation)) (get-session-value :editablep)) (defmethod lol:present ((self content-presentation)) (<:div :class "content" (when (show-title-p (lol:instance self)) (<:h2 (lol:present-slot-view self 'title))) (lol:present-slot-view self 'body) (when (editablep self) (