Both of our wikis will have very similar functionality: we will allow users to view and edit pages; when viewing a page words written in StudlyCaps will be converted into hyperlinks to like named wiki pages; pages will be editable by anyone at any time; every change will record the name of the author and a brief summary of the changes.
We won't worry about "RecentChanges" or search functionality (though this may be added later).
(defvar *wiki* (make-hash-table :test 'equal))
(defun find-wiki-page (page-name) (gethash page-name *wiki*))
(defun (setf find-wiki-page) (page page-name) (setf (gethash page-name *wiki*) page))
(defclass wiki-page () ((page-name :accessor page-name :initarg :page-name) (contents :accessor contents :initarg :contents :initform "")))
(defmacro defwiki-page (name body) (rebinding (name) `(setf (find-wiki-page ,name) (make-instance 'wiki-page :page-name ,name :contents ,body))))
Both of the wikis use "WelcomePage" as the default page name, by creating the page here we simplify some of the control flow.
(defwiki-page "WelcomePage" "Welcome to the wiki.")
(defclass wiki-edit () ((author :accessor author :initarg :author :initform nil) (summary :accessor summary :initarg :summary :initform nil) (contents :accessor contents :initarg :contents)) (:documentation "An object representing a single change to a single wiki page."))
(defun update-wiki-page (page-name change) (symbol-macrolet ((page (find-wiki-page page-name))) (unless page (setf page (make-instance 'wiki-page :page-name page-name))) (setf (contents page) (contents change)) page))