瀏覽代碼

added sitemap generation

Do Nhat Minh 12 年之前
父節點
當前提交
273d4ad6a7
共有 6 個文件被更改,包括 50 次插入18 次删除
  1. 11 6
      src/coleslaw.lisp
  2. 3 0
      src/content.lisp
  3. 14 0
      src/feeds.lisp
  4. 8 10
      src/indices.lisp
  5. 2 2
      src/posts.lisp
  6. 12 0
      themes/sitemap.tmpl

+ 11 - 6
src/coleslaw.lisp

@@ -12,14 +12,18 @@
12 12
       (with-output-to-string (str)
13 13
         (3bmd:parse-string-and-print-to-stream text str)))))
14 14
 
15
-(defgeneric page-path (object)
16
-  (:documentation "The path to store OBJECT at once rendered."))
15
+(defgeneric page-url (object)
16
+  (:documentation "The url to the object, without the domain"))
17 17
 
18
-(defmethod page-path :around ((object t))
18
+(defmethod page-url :around ((object t))
19 19
   (let ((result (call-next-method)))
20
-    (if (pathname-type result)
21
-        result
22
-        (make-pathname :type "html" :defaults result))))
20
+    (namestring (if (pathname-type result)
21
+                  result
22
+                  (make-pathname :type "html" :defaults result)))))
23
+
24
+(defun page-path (object)
25
+  "The path to store OBJECT at once rendered."
26
+  (rel-path (staging-dir *config*) (page-url object)))
23 27
 
24 28
 (defun render-page (content &optional theme-fn &rest render-args)
25 29
   "Render the given CONTENT to disk using THEME-FN if supplied.
@@ -51,6 +55,7 @@ Additional args to render CONTENT can be passed via RENDER-ARGS."
51 55
       (when (probe-file dir)
52 56
         (run-program "cp -R ~a ." dir)))
53 57
     (do-ctypes (publish ctype))
58
+    (render-sitemap)
54 59
     (render-indices)
55 60
     (render-feeds (feeds *config*))))
56 61
 

+ 3 - 0
src/content.lisp

@@ -7,6 +7,9 @@
7 7
   ((name :initform nil :initarg :name :accessor tag-name)
8 8
    (slug :initform nil :Initarg :slug :accessor tag-slug)))
9 9
 
10
+(defmethod page-url ((object tag))
11
+  (format nil "tag/~a" (tag-slug object)))
12
+
10 13
 (defun make-tag (str)
11 14
   "Takes a string and returns a TAG instance with a name and slug."
12 15
   (let ((trimmed (string-trim " " str)))

+ 14 - 0
src/feeds.lisp

@@ -4,6 +4,20 @@
4 4
   "Make a RFC1123 pubdate representing the current time."
5 5
   (local-time:format-rfc1123-timestring nil (local-time:now)))
6 6
 
7
+(defun render-sitemap ()
8
+  "Render sitemap.xml under document root"
9
+  (let* ((template (theme-fn :sitemap "feeds"))
10
+         (urls (cons "" ; for root url
11
+                     (append (mapcar #'page-url (find-all 'post))
12
+                             (mapcar #'page-url (all-tags))
13
+                             (mapcar #'(lambda (m)
14
+                                         (format nil "date/~a.html" m))
15
+                                     (all-months)))))
16
+         (index (make-instance 'url-index
17
+                               :id "sitemap.xml"
18
+                               :urls urls)))
19
+    (write-page (page-path index) (render-page index template))))
20
+
7 21
 (defun render-feed (posts &key path template tag)
8 22
   (flet ((first-10 (list) (subseq list 0 (min (length list) 10)))
9 23
          (tag-posts (list) (remove-if-not (lambda (x) (tag-p tag x)) list)))

+ 8 - 10
src/indices.lisp

@@ -16,15 +16,13 @@
16 16
 (defclass tag-index (index) ())
17 17
 (defclass date-index (index) ())
18 18
 (defclass int-index (index) ())
19
+(defclass url-index (index)
20
+  ((urls :initform nil :initarg :urls :accessor urls)))
19 21
 
20
-(defmethod page-path ((object index))
21
-  (rel-path (staging-dir *config*) (index-id object)))
22
-(defmethod page-path ((object tag-index))
23
-  (rel-path (staging-dir *config*) "tag/~a" (index-id object)))
24
-(defmethod page-path ((object date-index))
25
-  (rel-path (staging-dir *config*) "date/~a" (index-id object)))
26
-(defmethod page-path ((object int-index))
27
-  (rel-path (staging-dir *config*) "~d" (index-id object)))
22
+(defmethod page-url ((object index))
23
+  (index-id object))
24
+(defmethod page-url ((object date-index))
25
+  (format nil "date/~a" (index-id object)))
28 26
 
29 27
 (defun all-months ()
30 28
   "Retrieve a list of all months with published content."
@@ -40,7 +38,7 @@
40 38
 
41 39
 (defun index-by-tag (tag content)
42 40
   "Return an index of all CONTENT matching the given TAG."
43
-  (make-instance 'tag-index :id (tag-slug tag)
41
+  (make-instance 'tag-index :id (page-url tag)
44 42
                  :posts (remove-if-not (lambda (x) (tag-p tag x)) content)
45 43
                  :title (format nil "Posts tagged ~a" (tag-name tag))))
46 44
 
@@ -54,7 +52,7 @@
54 52
   "Return the index for the Ith page of CONTENT in reverse chronological order."
55 53
   (let* ((start (* step i))
56 54
          (end (min (length content) (+ start step))))
57
-    (make-instance 'int-index :id (1+ i)
55
+    (make-instance 'int-index :id (format nil "~d" (1+ i))
58 56
                               :posts (subseq content start end)
59 57
                               :title "Recent Posts")))
60 58
 

+ 2 - 2
src/posts.lisp

@@ -10,8 +10,8 @@
10 10
                                   :prev prev
11 11
                                   :next next)))
12 12
 
13
-(defmethod page-path ((object post))
14
-  (rel-path (staging-dir *config*) "posts/~a" (content-slug object)))
13
+(defmethod page-url ((object post))
14
+  (rel-path "posts/~a" (content-slug object)))
15 15
 
16 16
 (defmethod initialize-instance :after ((object post) &key)
17 17
   (with-accessors ((title post-title)

+ 12 - 0
themes/sitemap.tmpl

@@ -0,0 +1,12 @@
1
+{namespace coleslaw.theme.feeds}
2
+
3
+{template sitemap}
4
+<?xml version="1.0"?>{\n}
5
+<urlset xmlns='http://www.sitemaps.org/schemas/sitemap/0.9'>
6
+    {foreach $url in $content.urls}
7
+    <url>
8
+        <loc>{$config.domain}{$url}</loc>
9
+    </url>
10
+    {/foreach}
11
+</urlset>
12
+{/template}