Add prev/next support.

This commit is contained in:
Brit Butler 2012-08-21 21:20:01 -04:00
parent fa33345f82
commit 0326e6ff2e
4 changed files with 26 additions and 16 deletions

2
TODO
View file

@ -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

View file

@ -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)

View file

@ -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 ()

View file

@ -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."