INDEX rendering cleanup.

This commit is contained in:
Brit Butler 2012-09-12 11:00:21 -04:00
parent 939c0be318
commit f1ea9e89ae
2 changed files with 62 additions and 75 deletions

View file

@ -1,24 +1,31 @@
(in-package :coleslaw) (in-package :coleslaw)
(defclass index ()
((path :initform nil :initarg :path :accessor index-path)
(posts :initform nil :initarg :posts :accessor index-posts)
(title :initform nil :initarg :title :accessor index-title)))
(defmethod render ((content index) &key prev next)
(funcall (theme-fn 'index)
(list :tags (all-tags)
:months (all-months)
:config *config*
:title (index-title index)
:posts (index-posts index)
:prev prev
:next next)))
(defun all-months () (defun all-months ()
"Retrieve a list of all months with published posts." "Retrieve a list of all months with published posts."
(remove-duplicates (mapcar (lambda (x) (get-month (post-date x))) (sort (remove-duplicates (mapcar (lambda (x) (get-month (post-date x)))
(hash-table-values *posts*)) :test #'string=)) (hash-table-values *posts*)) :test #'string=)
#'string>))
(defun all-tags () (defun all-tags ()
"Retrieve a list of all tags used in posts." "Retrieve a list of all tags used in posts."
(reduce (lambda (x y) (union x y :test #'string=)) (sort (reduce (lambda (x y) (union x y :test #'string=))
(mapcar #'post-tags (hash-table-values *posts*)))) (mapcar #'post-tags (hash-table-values *posts*)))
#'string<))
(defun taglinks (&optional (tags (all-tags)))
"Generate links to all the tag indices or those in TAGS."
(loop for tag in (sort tags #'string<)
collect (list :url (format nil "tag/~a.html" tag) :name tag)))
(defun monthlinks (&optional (months (all-months)))
"Generate links to all the month indices."
(loop for month in (sort months #'string<)
collect (list :url (format nil "date/~a.html" month) :name month)))
(defun get-month (timestamp) (defun get-month (timestamp)
"Extract the YYYY-MM portion of TIMESTAMP." "Extract the YYYY-MM portion of TIMESTAMP."
@ -28,61 +35,41 @@
"Sort POSTS in reverse chronological order." "Sort POSTS in reverse chronological order."
(sort posts #'string> :key #'post-date)) (sort posts #'string> :key #'post-date))
(defun write-index (posts filename title &key prev next (relative t)) (defun render-by-n (posts &optional n)
"Write out the HTML for POSTS to FILENAME.html." "Render the indices to view POSTS in reverse chronological order by N."
(let ((content (loop for post in posts
collect (list :url (if relative
(format nil "../posts/~a" (post-url post))
(format nil "~a/posts/~a"
(domain *config*) (post-url post)))
:title (post-title post)
:date (post-date post)
:content (render-content (post-content post)
(post-format post))))))
(render-page filename
(funcall (theme-fn 'index)
(list :taglinks (taglinks)
:monthlinks (monthlinks)
:siteroot (domain *config*)
:title title
:posts content
:prev (and prev (format nil "~d.html" prev))
:next (and next (format nil "~d.html" next)))))))
(defun render-by-n (&optional n)
"Render the indices to view posts in reverse chronological order by N."
(flet ((by-n (posts start) (flet ((by-n (posts start)
(let ((index (* n (1- start)))) (let ((index (* n (1- start))))
(subseq posts index (min (length posts) (+ index n)))))) (subseq posts index (min (length posts) (+ index n))))))
(let ((posts (by-date (hash-table-values *posts*))))
(loop for i = 1 then (1+ i) (loop for i = 1 then (1+ i)
do (write-index (by-n posts i) (format nil "~d.html" i) "Recent Posts" do (render-page (make-instance 'index :path (format nil "~d.html" i)
:posts (by-n posts i)
:title "Recent Posts")
nil
:prev (and (plusp (1- i)) (1- i)) :prev (and (plusp (1- i)) (1- i))
:next (and (< (* i n) (length posts)) (1+ i)) :next (and (< (* i n) (length posts)) (1+ i)))
:relative nil) until (> (* i n) (length posts))))
until (> (* i n) (length posts))) (update-symlink "index.html" "1.html"))
(update-symlink "index.html" "1.html"))))
(defun render-by-tag (tags) (defun render-by-tag (posts tags)
"Render the indices to view posts by tag for each tag in TAGS." "Render the indices to view POSTS by tag for each tag in TAGS."
(dolist (tag tags) (dolist (tag tags)
(let ((posts (remove-if-not (lambda (post) (member tag (post-tags post) :test #'string=)) (let ((posts (remove-if-not (lambda (post) (member tag (post-tags post)
(hash-table-values *posts*)))) :test #'string=)) posts)))
(write-index (by-date posts) (render-page (make-instance 'index :path (format nil "tag/~a.html" tag)
(format nil "tag/~a.html" tag) :posts (by-date posts)
(format nil "Posts tagged ~a" tag))))) :title (format nil "Posts tagged ~a" tag))))))
(defun render-by-month (months) (defun render-by-month (posts months)
"Render the indices to view posts by month for each month in MONTHS." "Render the indices to view POSTS by month for each month in MONTHS."
(dolist (month months) (dolist (month months)
(let ((posts (remove-if-not (lambda (post) (search month (post-date post))) (let ((posts (remove-if-not (lambda (post) (search month (post-date post))) posts)))
(hash-table-values *posts*)))) (render-page (make-instance 'index :path (format nil "date/~a.html" month)
(write-index (by-date posts) :posts (by-date posts)
(format nil "date/~a.html" month) :title (format nil "Posts from ~a" month))))))
(format nil "Posts from ~a" month)))))
(defun render-indices () (defun render-indices ()
"Render the indices to view posts in groups of size N, by month, and by tag." "Render the indices to view posts in groups of size N, by month, and by tag."
(render-by-n 10) (let ((posts (hash-table-values *posts*)))
(render-by-tag (all-tags)) (render-by-n (by-date posts) 10)
(render-by-month (all-months))) (render-by-tag posts (all-tags))
(render-by-month posts (all-months))))

View file

@ -1,33 +1,33 @@
{namespace coleslaw.theme.hyde} {namespace coleslaw.theme.hyde}
{template index} {template index}
<h1 class="title">{$title}</h1> <h1 class="title">{$index.title}</h1>
{foreach $post in $posts} {foreach $post in $index.posts}
<div class="article-meta"> <div class="article-meta">
<a class="article-title" href="{$post.url}">{$post.title}</a> <a class="article-title" href="{$config.domain}/posts/{$post.slug}.html">{$post.title}</a>
<div class="date"> posted on {$post.date}</div> <div class="date"> posted on {$post.date}</div>
<div class="article">{$post.content |noAutoescape}</div> <div class="article">{$post.content |noAutoescape}</div>
</div> </div>
{/foreach} {/foreach}
<div id="relative-nav"> <div id="relative-nav">
{if $prev} <a href="{$prev}">Previous</a> {/if} {if $prev} <a href="{$prev}.html">Previous</a> {/if}
{if $next} <a href="{$next}">Next</a> {/if} {if $next} <a href="{$next}.html">Next</a> {/if}
</div> </div>
{if $taglinks} {if $tags}
<div id="tagsoup"> <div id="tagsoup">
<p>This blog covers <p>This blog covers
{foreach $taglink in $taglinks} {foreach $tag in $tags}
<a href="{$siteroot}/{$taglink.url |noAutoescape}">{$taglink.name}</a> <a href="{$config.domain}/tag/{$tag}.html">{$tag}</a>
{if not isLast($taglink)}, {/if} {if not isLast($tag)}, {/if}
{/foreach} {/foreach}
</div> </div>
{/if} {/if}
{if $monthlinks} {if $months}
<div id="monthsoup"> <div id="monthsoup">
<p>View posts from <p>View posts from
{foreach $monthlink in $monthlinks} {foreach $month in $months}
<a href="{$siteroot}/{$monthlink.url |noAutoescape}">{$monthlink.name}</a> <a href="{$config.domain}/date/{$month}.html">{$month}</a>
{if not isLast($monthlink)}, {/if} {if not isLast($month)}, {/if}
{/foreach} {/foreach}
</div> </div>
{/if} {/if}