|
@@ -2,28 +2,34 @@
|
2
|
2
|
|
3
|
3
|
(defun all-months ()
|
4
|
4
|
"Retrieve a list of all months with published posts."
|
5
|
|
- (sort (remove-duplicates (mapcar (lambda (x) (subseq (post-date x) 0 7))
|
6
|
|
- (hash-table-values *posts*)) :test #'string=)
|
7
|
|
- #'string<))
|
|
5
|
+ (remove-duplicates (mapcar (lambda (x) (get-month (post-date x)))
|
|
6
|
+ (hash-table-values *posts*)) :test #'string=))
|
8
|
7
|
|
9
|
8
|
(defun all-tags ()
|
10
|
9
|
"Retrieve a list of all tags used in posts."
|
11
|
|
- (sort (reduce (lambda (x y) (union x y :test #'string=))
|
12
|
|
- (mapcar #'post-tags (hash-table-values *posts*)))
|
13
|
|
- #'string<))
|
|
10
|
+ (reduce (lambda (x y) (union x y :test #'string=))
|
|
11
|
+ (mapcar #'post-tags (hash-table-values *posts*))))
|
14
|
12
|
|
15
|
13
|
(defun taglinks ()
|
16
|
14
|
"Generate links to all the tag indices."
|
17
|
|
- (loop for tag in (all-tags)
|
|
15
|
+ (loop for tag in (sort (all-tags) #'string<)
|
18
|
16
|
collect (list :url (format nil "~a/tag/~a.html" (domain *config*) tag)
|
19
|
17
|
:name tag)))
|
20
|
18
|
|
21
|
19
|
(defun monthlinks ()
|
22
|
20
|
"Generate links to all the month indices."
|
23
|
|
- (loop for month in (all-months)
|
|
21
|
+ (loop for month in (sort (all-months) #'string<)
|
24
|
22
|
collect (list :url (format nil "~a/date/~a.html" (domain *config*) month)
|
25
|
23
|
:name month)))
|
26
|
24
|
|
|
25
|
+(defun get-month (timestamp)
|
|
26
|
+ "Extract the YYYY-MM portion of TIMESTAMP."
|
|
27
|
+ (subseq timestamp 0 7))
|
|
28
|
+
|
|
29
|
+(defun by-date (posts)
|
|
30
|
+ "Sort POSTS in reverse chronological order."
|
|
31
|
+ (sort posts #'string> :key #'post-date))
|
|
32
|
+
|
27
|
33
|
(defun write-index (posts filename title)
|
28
|
34
|
"Write out the HTML for POSTS to FILENAME.html."
|
29
|
35
|
(let ((content (loop for post in posts
|
|
@@ -48,7 +54,7 @@
|
48
|
54
|
(flet ((by-20 (posts start)
|
49
|
55
|
(let ((index (* 20 (1- start))))
|
50
|
56
|
(subseq posts index (min (length posts) (+ index 20))))))
|
51
|
|
- (let ((posts (sort (hash-table-values *posts*) #'string> :key #'post-date)))
|
|
57
|
+ (let ((posts (by-date (hash-table-value *posts*))))
|
52
|
58
|
(loop for i = 1 then (1+ i)
|
53
|
59
|
do (write-index (by-20 posts i) (format nil "~d.html" i) "Recent Posts")
|
54
|
60
|
until (> (* i 20) (length posts))))))
|
|
@@ -59,19 +65,19 @@
|
59
|
65
|
do (flet ((match-tag (post)
|
60
|
66
|
(member tag (post-tags post) :test #'string=)))
|
61
|
67
|
(let ((posts (remove-if-not #'match-tag (hash-table-values *posts*))))
|
62
|
|
- (write-index posts (format nil "tag/~a.html" tag)
|
|
68
|
+ (write-index (by-date posts)
|
|
69
|
+ (format nil "tag/~a.html" tag)
|
63
|
70
|
(format nil "Posts tagged ~a" tag))))))
|
64
|
71
|
|
65
|
72
|
(defun render-by-month ()
|
66
|
73
|
"Render the indices to view posts by month."
|
67
|
|
- (let ((months (remove-duplicates (mapcar (lambda (x) (subseq (post-date x) 0 7))
|
68
|
|
- (hash-table-values *posts*))
|
69
|
|
- :test #'string=)))
|
70
|
|
- (loop for month in months
|
71
|
|
- do (let ((posts (remove-if-not (lambda (x) (search month (post-date x)))
|
72
|
|
- (hash-table-values *posts*))))
|
73
|
|
- (write-index posts (format nil "date/~a.html" (subseq month 0 7))
|
74
|
|
- (format nil "Posts from ~a" (subseq month 0 7)))))))
|
|
74
|
+ (loop for month in (all-months)
|
|
75
|
+ do (flet ((match-month (post)
|
|
76
|
+ (search month (post-date post))))
|
|
77
|
+ (let ((posts (remove-if-not #'match-month (hash-table-values *posts*))))
|
|
78
|
+ (write-index (by-date posts)
|
|
79
|
+ (format nil "date/~a.html" month)
|
|
80
|
+ (format nil "Posts from ~a" month))))))
|
75
|
81
|
|
76
|
82
|
(defun render-indices ()
|
77
|
83
|
"Render the indices to view posts in groups of 20, by month, and by tag."
|