From 0326e6ff2eedbb13882237540ccbcb874536f914 Mon Sep 17 00:00:00 2001 From: Brit Butler Date: Tue, 21 Aug 2012 21:20:01 -0400 Subject: [PATCH] Add prev/next support. --- TODO | 2 +- coleslaw.asd | 6 +++--- src/indices.lisp | 13 +++++++------ src/posts.lisp | 21 +++++++++++++++------ 4 files changed, 26 insertions(+), 16 deletions(-) diff --git a/TODO b/TODO index dbcc304..e43ec24 100644 --- a/TODO +++ b/TODO @@ -13,7 +13,7 @@ Plugins? Injection support for HEAD and BODY. What about predicate-based injecti How is it served? Hunchentoot, Lighttpd, S3, whomever! TODO: -; blockers to use this for redlinernotes: prev/next, rss/atom feed, markdown support +; blockers to use this for redlinernotes: rss/atom feed, markdown support ; after that, focus on injections for code highlighting and latex ; doc themes and plugins diff --git a/coleslaw.asd b/coleslaw.asd index 34e9574..744e0fa 100644 --- a/coleslaw.asd +++ b/coleslaw.asd @@ -10,11 +10,11 @@ :components ((:file "packages") (:file "config") (:file "git") - (:file "coleslaw") (:file "themes") + (:file "plugins") + (:file "coleslaw") (:file "posts") - (:file "indices") - (:file "plugins")) + (:file "indices")) :in-order-to ((test-op (load-op coleslaw-tests))) :perform (test-op :after (op c) (funcall (intern "RUN!" :coleslaw-tests) diff --git a/src/indices.lisp b/src/indices.lisp index eef69d4..01bc2e3 100644 --- a/src/indices.lisp +++ b/src/indices.lisp @@ -30,7 +30,7 @@ "Sort POSTS in reverse chronological order." (sort posts #'string> :key #'post-date)) -(defun write-index (posts filename title) +(defun write-index (posts filename title &optional prev next) "Write out the HTML for POSTS to FILENAME.html." (let ((content (loop for post in posts collect (list :url (format nil "~a/posts/~a.html" @@ -45,18 +45,19 @@ :monthlinks (monthlinks) :title title :posts content - ; TODO: Populate prev and next with links. - :prev nil - :next nil))))) + :prev (and prev (format nil "~d.html" prev)) + :next (and next (format nil "~d.html" next))))))) (defun render-by-20 () "Render the indices to view posts in reverse chronological order by 20." (flet ((by-20 (posts start) (let ((index (* 20 (1- start)))) (subseq posts index (min (length posts) (+ index 20)))))) - (let ((posts (by-date (hash-table-value *posts*)))) + (let ((posts (by-date (hash-table-values *posts*)))) (loop for i = 1 then (1+ i) - do (write-index (by-20 posts i) (format nil "~d.html" i) "Recent Posts") + do (write-index (by-20 posts i) (format nil "~d.html" i) "Recent Posts" + (and (plusp (1- i)) (1- i)) + (and (< (* i 20) (length posts)) (1+ i))) until (> (* i 20) (length posts)))))) (defun render-by-tag () diff --git a/src/posts.lisp b/src/posts.lisp index d3730c2..6ce5c41 100644 --- a/src/posts.lisp +++ b/src/posts.lisp @@ -22,10 +22,20 @@ (post-slug post)) (setf (gethash (post-slug post) *posts*) post)))))) +(defun post-url (post) + "Return the relative URL for a given post." + (format nil "posts/~a.html" (post-slug post))) + (defun render-posts () "Iterate through the files in the repo to render+write the posts out to disk." (load-posts) - (maphash #'write-post *posts*)) + (loop with posts = (sort (hash-table-values *posts*) #'string< :key #'post-date) + for i from 1 upto (length posts) + for prev = nil then post + for post = (nth (1- i) posts) + for next = (nth (1+ i) posts) + do (write-post post :prev (and prev (post-url prev)) + :next (and next (post-url next))))) (defgeneric render-content (text format) (:documentation "Compile TEXT from the given FORMAT to HTML for display.") @@ -51,18 +61,17 @@ (append args (list :content (read-line in nil) :slug (slugify (getf args :title)))))))) -(defun write-post (slug post) +(defun write-post (post &key prev next) "Write out the HTML for POST in SLUG.html." - (render-page (format nil "posts/~a.html" slug) + (render-page (post-url post) (funcall (theme-fn "POST") (list :title (post-title post) :tags (post-tags post) :date (post-date post) :content (render-content (post-content post) (post-format post)) - ; TODO: Populate prev and next with links. - :prev nil - :next nil)))) + :prev prev + :next next)))) (defun slug-char-p (char) "Determine if CHAR is a valid slug (i.e. URL) character."