(in-package :kira) (defclass book (post) ((author :accessor author :initarg :author :initform nil) (isbn :accessor isbn :initarg :isbn :initform nil))) (defcollection books ((node node) &key by) (ecase by (title (cached-collection node 'books-by-title)) ((nil) (cached-collection node 'books :descending t)))) (defhandler ((entity books-mixin) :books) (:title "Books") (with-query ((by symbol)) (html (:p (render-link entity 'create :type 'book)) ((:ul :class "tabs") (flet ((render-tab (^by label) (html ((:li :class (:when (eq by ^by) "current")) (:a (:uri-to (request-uri) :by ^by) label))))) (render-tab nil "Date Added") (render-tab 'title "Title"))) (:when (eq by 'title) (:p (with-query ((start character)) (loop for code from (char-code #\A) upto (char-code #\Z) for char = (code-char code) do (html (:unless (eql char #\A) " | ") (:if (eql start char) (:b char) (:a (:uri-to (request-uri) :start char) char))))))) (:grid (books entity :by by))))) (defmethod render-in-style ((book book) (style (eql 'lines))) (html ((:ul :class "lines") (:li "by " (render-inline-markup (author book))) (:whereas ((isbn (isbn book))) (:li* "ISBN" isbn) (:li (render-link book :buy)))))) (defmethod render-in-style ((book book) (style (eql 'caption))) (html (:li (:i (render-title book))) (:li "by " (render-inline-markup (author book))))) (defmethod render-editor ((book book)) (html (:field "Title" (text-field 'title book)) (:field "Author" (text-field 'author book)) (:fieldset "Cover" (file-field 'image book)) (:field "ISBN" (text-field 'isbn book :size 20)) (:field "Description" (markup-field 'body book)))) (defmethod watched-slots append ((book book)) '(title)) (defmethod update-instance-from-query progn ((book book)) (setf-accessors-from-query book author isbn)) (define-update-methods instance ((entity books-mixin) (book book)) (update-collection (books entity) book) (update-map (books entity :by 'title) (title book) book)) (define-canonical-uri ((book book)) (let ((title (title book))) (if (and title (eq (get-value (books *root* :by 'title) title) book)) (make-instance 'uri :path (list :absolute "books" title)) (call-next-method)))) (define-internal-redirect (:books) path (whereas ((title (pop path))) (values (get-value (books *root* :by 'title) title) path))) (define-canonical-uri ((book book) :buy) (:title "Buy at Amazon.com") (format nil "http://www.amazon.com/gp/search/ref=sr_adv_b/?search-alias=stripbooks&field-isbn=~a" (isbn book))) (defmethod text ((book book) (symbol (eql 'realize))) "Add")