From c75ba4bc50546d93b48a3d9299bec701187707a5 Mon Sep 17 00:00:00 2001 From: Brit Butler Date: Sat, 16 Apr 2011 15:45:37 -0400 Subject: [PATCH] Restructuring and API rewrite. --- README | 13 ++++++++++- TODO | 22 +++++++++++++++++ coleslaw-dynamic.asd | 12 ---------- coleslaw-static.asd | 10 -------- coleslaw-core.asd => coleslaw.asd | 16 +++++++------ core/coleslaw.lisp | 4 ---- core/config.lisp | 11 --------- core/indices.lisp | 17 -------------- core/packages.lisp | 2 -- core/posts.lisp | 19 --------------- core/storage.lisp | 19 --------------- dynamic/admin.lisp | 2 -- dynamic/comments.lisp | 20 ---------------- src/coleslaw.lisp | 17 ++++++++++++++ src/comments.lisp | 39 +++++++++++++++++++++++++++++++ src/indices.lisp | 13 +++++++++++ src/packages.lisp | 37 +++++++++++++++++++++++++++++ src/posts.lisp | 38 ++++++++++++++++++++++++++++++ src/themes.lisp | 26 +++++++++++++++++++++ static/comments.lisp | 3 --- 20 files changed, 213 insertions(+), 127 deletions(-) delete mode 100644 coleslaw-dynamic.asd delete mode 100644 coleslaw-static.asd rename coleslaw-core.asd => coleslaw.asd (58%) delete mode 100644 core/coleslaw.lisp delete mode 100644 core/config.lisp delete mode 100644 core/indices.lisp delete mode 100644 core/packages.lisp delete mode 100644 core/posts.lisp delete mode 100644 core/storage.lisp delete mode 100644 dynamic/admin.lisp delete mode 100644 dynamic/comments.lisp create mode 100644 src/coleslaw.lisp create mode 100644 src/comments.lisp create mode 100644 src/indices.lisp create mode 100644 src/packages.lisp create mode 100644 src/posts.lisp create mode 100644 src/themes.lisp delete mode 100644 static/comments.lisp diff --git a/README b/README index 0e5f75a..17e65de 100644 --- a/README +++ b/README @@ -1 +1,12 @@ -Coleslaw aims to be flexible blog software suitable for replacing a single-user wordpress install or jekyll. The primary difference is that the coleslaw-dynamic backend uses PostgreSQL and RESTAS to generate and serve the site while the coleslaw-static backend compiles a static site to be served by Amazon S3. +Coleslaw aims to be flexible blog software suitable for replacing a single-user wordpress install or jekyll. + +There will be at least two backends: a dynamic one using RESTAS and PostgreSQL and a static one served by Hunchentoot or, optionally, S3. + +References: +Static Backend +-- Jekyll +-- Hakyll +-- Hyde +Dynamic Backend +-- Wordpress +-- Nuclblog diff --git a/TODO b/TODO index fe67489..06c25a9 100644 --- a/TODO +++ b/TODO @@ -1 +1,23 @@ Everything. + +Ideas: +-- Replace cl-markdown with 3bmd down the line? +-- Use cl-inotify or similar for notifications instead of timers? + -- plugins -> lastfm widget, analytics, rss/atom, disqus, akismet, etc. + +;; TODO: +;; consider add-to-index/setf-index, create-index, create-post. +;; then ensure the indices API is okay and GET GOING. + +;;;; rendering hooks (eg. :pygmentize, :xpost-lj?) +;; may need pre- and post- but for now stick to post-. +;; get run on rendered html before "storage" +;; xposting may be a rendering hook but may necessitate publishing hooks +;; again, these should be methods on a generic function + +;;;; template hooks *ARE* pre-rendering-hooks. or methods on GFs. +;;;; they're methods on GFs you fool! work on the classes/constructors for post+indices +;;;; that's the only thing that makes sense. (eg 'disqus, 'mathjax) +;; run before the template is called to generate html or javascript includes +;; for a given template property (eg. comments, includes). they should probably be +;; methods on a generic function (eg. blog-comments, blog-includes) diff --git a/coleslaw-dynamic.asd b/coleslaw-dynamic.asd deleted file mode 100644 index e850055..0000000 --- a/coleslaw-dynamic.asd +++ /dev/null @@ -1,12 +0,0 @@ -(defsystem :coleslaw-dynamic - :name "coleslaw-dynamic" - :description "Flexible Lisp Blogware, Dynamic+PostgreSQL edition" - :version "0.0.1" - :maintainer "Brit Butler " - :author "Brit Butler " - :licence "LLGPL" - :depends-on (:coleslaw-core :postmodern :restas) - :components ((:module dynamic - :components ((:file "comments") - (:file "admin" - :depends-on ("comments")))))) diff --git a/coleslaw-static.asd b/coleslaw-static.asd deleted file mode 100644 index 6974946..0000000 --- a/coleslaw-static.asd +++ /dev/null @@ -1,10 +0,0 @@ -(defsystem :coleslaw-static - :name "coleslaw-static" - :description "Flexible Lisp Blogware, Static+S3 edition" - :version "0.0.1" - :maintainer "Brit Butler " - :author "Brit Butler " - :licence "LLGPL" - :depends-on (:coleslaw-core :zs3 :trivial-timers) - :components ((:module static - :components ((:file "comments"))))) diff --git a/coleslaw-core.asd b/coleslaw.asd similarity index 58% rename from coleslaw-core.asd rename to coleslaw.asd index de8bb1c..0203d79 100644 --- a/coleslaw-core.asd +++ b/coleslaw.asd @@ -1,19 +1,21 @@ -(defsystem :coleslaw-core +(defsystem :coleslaw :name "coleslaw-core" - :description "Flexible Lisp Blogware, Core utilities" + :description "Flexible Lisp Blogware" :version "0.0.1" :maintainer "Brit Butler " :author "Brit Butler " :licence "LLGPL" - :depends-on (:cl-markdown :docutils :closure-template - :external-program :local-time) ; parenscript? - :components ((:module core + :depends-on (:cl-markdown :docutils + :closure-template :cl-fad) + :components ((:module src :components ((:file "packages") (:file "coleslaw" :depends-on ("packages")) - (:file "storage" + (:file "themes" + :depends-on ("coleslaw")) + (:file "comments" :depends-on ("coleslaw")) (:file "posts" - :depends-on ("storage")) + :depends-on ("coleslaw")) (:file "indices" :depends-on ("posts")))))) diff --git a/core/coleslaw.lisp b/core/coleslaw.lisp deleted file mode 100644 index 1979084..0000000 --- a/core/coleslaw.lisp +++ /dev/null @@ -1,4 +0,0 @@ -(in-package :coleslaw) - -(defgeneric start-coleslaw (&rest options) - (:documentation "Start the coleslaw server with any specified OPTIONS.")) diff --git a/core/config.lisp b/core/config.lisp deleted file mode 100644 index 8ca6c20..0000000 --- a/core/config.lisp +++ /dev/null @@ -1,11 +0,0 @@ -(in-package :coleslaw) - -(defparameter *credentials* nil - "A map of names to credentials, potentially an alist. Names should be -keywords or symbols, credentials should be dotted pairs.") - -(defgeneric get-credentials (name) - (:documentation "Retrieve the credentials keyed by NAME from *credentials*.")) - -(defgeneric set-credentials (name credentials) - (:documentation "Store the given CREDENTIALS in *credentials* under NAME.")) diff --git a/core/indices.lisp b/core/indices.lisp deleted file mode 100644 index 5da7b52..0000000 --- a/core/indices.lisp +++ /dev/null @@ -1,17 +0,0 @@ -(in-package :coleslaw) - -(defgeneric create-index (name ids dates urls) - (:documentation "Create an index in *storage* with the given NAME, post IDs, -post DATEs and post URLs.")) - -(defgeneric get-index (name) - (:documentation "Retrieve the index matching NAME from *storage*.")) - -(defgeneric add-to-index (index post) - (:documentation "Add the given POST to INDEX.")) - -(defgeneric remove-from-index (index post) - (:documentation "Remove the given POST from INDEX.")) - -(defgeneric render-index (index) - (:documentation "Generate the final HTML for INDEX.")) diff --git a/core/packages.lisp b/core/packages.lisp deleted file mode 100644 index 6d5862a..0000000 --- a/core/packages.lisp +++ /dev/null @@ -1,2 +0,0 @@ -(defpackage :coleslaw - (:use :cl :closure-template :local-time)) diff --git a/core/posts.lisp b/core/posts.lisp deleted file mode 100644 index 980415e..0000000 --- a/core/posts.lisp +++ /dev/null @@ -1,19 +0,0 @@ -(in-package :coleslaw) - -(defgeneric add-post (id title timestamp permalink tags - content &key &allow-other-keys) - (:documentation "Create a post with the given ID, TITLE, TIMESTAMP, -PERMALINK, TAGS and CONTENT and add it to *storage*.")) - -(defgeneric prettify-code (post) - (:documentation "Ensure that any escaped code in POST is prettified.")) - -(defgeneric prettify-math-p (post) - (:documentation "Returns T if post needs MathJAX loaded, NIL otherwise.")) - -(defgeneric render-post (post) - (:documentation "Generate the final HTML for POST.")) - -(defgeneric remove-post (post) - (:documentation "Remove POST from *storage* and, if necessary, -update the running site.")) diff --git a/core/storage.lisp b/core/storage.lisp deleted file mode 100644 index a561784..0000000 --- a/core/storage.lisp +++ /dev/null @@ -1,19 +0,0 @@ -(in-package :coleslaw) - -(defparameter *storage* nil - "A db-spec for postmodern or a hash-table cache of metadata. -It is expected that *storage* has methods for each Generic Function -in coleslaw-core implemented.") - -(defgeneric find-by-id (id) - (:documentation "Retrieve a POST object from *storage* matching ID.")) - -(defgeneric find-by-tag (tag) - (:documentation "Retrieve all POST objects from *storage* tagged with TAG.")) - -(defgeneric find-by-date (date) - (:documentation "Retrieve all POST objects from *storage* matching DATE.")) - -(defgeneric find-by-range (start end) - (:documentation "Retrieve all POST objects from *storage* with ids between -START and END.")) diff --git a/dynamic/admin.lisp b/dynamic/admin.lisp deleted file mode 100644 index fb7f3d6..0000000 --- a/dynamic/admin.lisp +++ /dev/null @@ -1,2 +0,0 @@ -(in-package :coleslaw) - diff --git a/dynamic/comments.lisp b/dynamic/comments.lisp deleted file mode 100644 index ef96fc2..0000000 --- a/dynamic/comments.lisp +++ /dev/null @@ -1,20 +0,0 @@ -(in-package :coleslaw) - -(defclass comment () - ((id :initarg :id - :accessor id) - (post-id :initarg :post-id - :accessor post-id) - (author-ip :initarg :author-ip - :accessor author-ip) - (author-name :initarg :author-name - :accessor author-name) - (author-url :initarg :author-url - :accessor author-url) - (timestamp :initarg :timestamp - :accessor timestamp) - (content :initarg :content - :accessor content) - (parent :initarg :parent - :accessor parent)) - (:metaclass dao-class)) diff --git a/src/coleslaw.lisp b/src/coleslaw.lisp new file mode 100644 index 0000000..f4539d1 --- /dev/null +++ b/src/coleslaw.lisp @@ -0,0 +1,17 @@ +(in-package :coleslaw) + +(defgeneric start-coleslaw (&rest options) + (:documentation "Start the coleslaw server with any specified OPTIONS.")) + +(defgeneric stop-coleslaw (&rest options) + (:documentation "Stop the coleslaw server with any specified OPTIONS.")) + +(defparameter *storage* nil + "A db-spec for postmodern or a hash-table cache. It is expected that +*storage* has methods for each Generic Function in coleslaw implemented.") + +(defgeneric get-credentials (name) + (:documentation "Retrieve the credentials keyed by NAME from *storage*.")) + +(defgeneric set-credentials (name credentials) + (:documentation "Store the given CREDENTIALS in *storage* under NAME.")) diff --git a/src/comments.lisp b/src/comments.lisp new file mode 100644 index 0000000..67426a8 --- /dev/null +++ b/src/comments.lisp @@ -0,0 +1,39 @@ +(in-package :coleslaw) + +(defclass author () + ((name :initform nil + :accessor author-name) + (url :initform nil + :accessor author-url) + (ip :initform nil + :accessor author-ip))) + +(defclass comment () + ((id :initform nil + :accessor comment-id) + (post :initform nil + :accessor comment-post) + (author :initform nil + :accessor comment-author) + (timestamp :initform nil + :accessor comment-timestamp) + (content :initform nil + :accessor comment-content) + (parent :initform nil + :accessor comment-parent))) + +(defgeneric make-comment (post author timestamp content + parent &key &allow-other-key) + (:documentation "Create a COMMENT with the given data.")) + +(defgeneric add-comment (comment post-id) + (:documentation "Add COMMENT to POST-ID.")) + +(defgeneric delete-comment (comment post-id) + (:documentation "Delete COMMENT from POST-ID.")) + +(defgeneric render-comments (post-id) + (:documentation "Render the comments for POST-ID.")) + +(defgeneric find-comments (post-id) + (:documentation "Find the comments for POST-ID.")) diff --git a/src/indices.lisp b/src/indices.lisp new file mode 100644 index 0000000..f7b75d8 --- /dev/null +++ b/src/indices.lisp @@ -0,0 +1,13 @@ +(in-package :coleslaw) + +(defgeneric add-index (index id) + (:documentation "Insert INDEX into *storage* with the given ID.")) + +(defgeneric remove-index (id) + (:documentation "Remove the index matching ID from *storage*.")) + +(defgeneric render-index (index) + (:documentation "Generate the final HTML for INDEX.")) + +(defgeneric find-index (id) + (:documentation "Retrieve the index matching ID from *storage*.")) diff --git a/src/packages.lisp b/src/packages.lisp new file mode 100644 index 0000000..1f4b52f --- /dev/null +++ b/src/packages.lisp @@ -0,0 +1,37 @@ +(defpackage :coleslaw + (:use :cl :closure-template) + (:export ;; coleslaw-core + #:*storage* + #:start-coleslaw + #:stop-coleslaw + #:get-credentials + #:set-credentials + + ;; themes + #:*current-theme* + #:*theme-dir* + + ;; WARNING: STILL IN FLUX + ;; posts + #:make-post + #:add-post + #:remove-post + #:render-post + #:find-post + #:find-by-tag + #:find-by-date + #:find-by-range + + ;; comments + #:make-comment + #:add-comment + #:remove-comment + #:render-comments + #:find-comments + + ;; indices + #:add-index + #:remove-index + #:render-index + #:find-index + )) diff --git a/src/posts.lisp b/src/posts.lisp new file mode 100644 index 0000000..3d669a8 --- /dev/null +++ b/src/posts.lisp @@ -0,0 +1,38 @@ +(in-package :coleslaw) + +(defclass post () + ((id :initform nil + :accessor post-id) + (title :initform nil + :accessor post-title) + (tags :initform nil + :accessor post-tags) + (date :initform nil + :accessor post-date) + (content :initform nil + :accessor post-content))) + +(defgeneric make-post (title tags date content &key &allow-other-keys) + (:documentation "Create a POST with the given data.")) + +(defgeneric add-post (post id) + (:documentation "Insert a post into *storage* with the given ID.")) + +(defgeneric remove-post (id) + (:documentation "Remove a post from *storage* matching ID.")) + +(defgeneric render-post (id) + (:documentation "Generate the final HTML for post.")) + +(defgeneric find-post (id) + (:documentation "Retrieve a post from *storage* matching ID.")) + +(defgeneric find-by-tag (tag) + (:documentation "Retrieve all posts from *storage* tagged with TAG.")) + +(defgeneric find-by-date (date) + (:documentation "Retrieve all posts from *storage* matching DATE.")) + +(defgeneric find-by-range (start end) + (:documentation "Retrieve all posts from *storage* with ids between +START and END.")) diff --git a/src/themes.lisp b/src/themes.lisp new file mode 100644 index 0000000..98968d9 --- /dev/null +++ b/src/themes.lisp @@ -0,0 +1,26 @@ +(in-package :coleslaw) + +(defparameter *current-theme* "hyde" + "The name of a directory containing templates for HTML generation.") + +(defparameter *theme-dir* (merge-pathnames + (concatenate 'string "themes/" *current-theme*) + (asdf:system-source-directory 'coleslaw)) + "The directory containing the current theme and other site templates.") + +(defun theme-package (&key (name *current-theme*)) + (find-package (string-upcase (concatenate 'string "coleslaw.theme." name)))) + +(defun compile-theme (&key (theme-dir *theme-dir*)) + (loop for file in (cl-fad:list-directory theme-dir) do + (let ((extension (pathname-type file))) + (when (and extension (string= extension "tmpl")) + (compile-template :common-lisp-backend file))))) + +;; DOCUMENTATION +;; A theme directory should be named after the theme and contain *.tmpl files +;; that define the following functions in a coleslaw.theme.$NAME namespace. +;; Required templates follow with suggested args (args will be in plists): +;; {template base} // title navigation siteroot content credits &key license headInject bodyInject +;; {template post} // title tags date content prev next &key comments +;; {template index} // title posts prev next &key taglinks monthlinks count diff --git a/static/comments.lisp b/static/comments.lisp deleted file mode 100644 index 79bd31e..0000000 --- a/static/comments.lisp +++ /dev/null @@ -1,3 +0,0 @@ -(in-package :coleslaw) - -;; disqus integration?