Explorar o código

Flesh out the sketch a bit more and add some constraints.

Brit Butler %!s(int64=11) %!d(string=hai) anos
pai
achega
7d9b0aa011
Modificáronse 1 ficheiros con 38 adicións e 7 borrados
  1. 38 7
      plugins/incremental.lisp

+ 38 - 7
plugins/incremental.lisp

@@ -15,26 +15,33 @@
15 15
 
16 16
 (in-package :coleslaw-incremental)
17 17
 
18
-;; FIXME: We currently never update the site for config changes.
18
+;; KLUDGE: We currently never update the site for config changes.
19 19
 ;; Examples to consider include changing the theme or domain of the site.
20 20
 ;; Both would require full site recompiles. Consequently, it seems reasonable
21 21
 ;; to expect that incremental plugin users:
22 22
 ;;   A) have done a full build of their site
23 23
 ;;   B) have a cl-store dump of the database at ~/.coleslaw.db
24 24
 ;;      ^ we should provide a script or plugin just for this
25
+;;   C) move the original deployment to a location of their choice and
26
+;;      set it as staging-dir in coleslaw's config prior to enabling incremental builds
27
+;;   D) to further simplify *my* life, we assume the date of a piece of content will
28
+;;      never be changed retroactively, only its tags
25 29
 
26 30
 ;; NOTE: We're gonna be a bit dirty here and monkey patch. The compilation model
27 31
 ;; still isn't an "exposed" part of Coleslaw. After some experimentation maybe
28 32
 ;; we'll settle on an interface.
29 33
 
30
-(defvar *changed-content* nil
31
-  "A list of changed content instances to iterate over and write out to disk.")
34
+(defvar *transients* '(coleslaw::numeric-index coleslaw::feed coleslaw::tag-feed)
35
+  "A list of document types that should be regenerated on *any* change to the blog.")
32 36
 
33 37
 (defun coleslaw::load-content ()
34 38
   (let ((db-file (rel-path (user-homedir-pathname) ".coleslaw.db")))
35 39
     (setf coleslaw::*site* (cl-store:restore db-file))
36 40
     (loop for (status path) in (get-updated-files)
37 41
        do (update-content status path))
42
+    (coleslaw::update-content-metadata)
43
+    (dolist (doc-type *transients*)
44
+      (discover (find-class doc-type)))
38 45
     (cl-store:store coleslaw::*site* db-file)))
39 46
 
40 47
 (defun update-content (status path)
@@ -50,23 +57,47 @@
50 57
       ;; This feels way too clever. I wish I could think of a better option.
51 58
       (flet ((class-name-p (x class)
52 59
                (string-equal x (symbol-name (class-name class)))))
60
+        ;; If the updated file's extension doesn't match one of our content types,
61
+        ;; we don't need to mess with it at all. Otherwise, since the class is
62
+        ;; annoyingly tricky to determine, pass it along.
53 63
         (when-let (ctype (find extension ctypes :test #'class-name-p))
54 64
           (call-next-method status path :ctype ctype))))))
55 65
 
66
+;; TODO: We should check to see if a *new* tag or month exists
67
+;; and create an index appropriately. If the last content from a
68
+;; given month or with a given tag is deleted, just drop the index.
69
+;; (And also remove it from *all-months* / *all-tags*. Should we store those?)
70
+;; Additionally, the tag/month lists won't be updated on tag/month index pages.
71
+
56 72
 (defmethod process-change ((status (eql :deleted)) path &key)
57
-  (let ((obj (find-content-by-path path)))
58
-    ))
73
+  (let ((old (find-content-by-path path)))
74
+    ;; TODO: Remove from any tag and month indexes.
75
+    (delete-document old)))
59 76
 
60 77
 (defmethod process-change ((status (eql :modified)) path &key)
61
-  (let ((obj (find-content-by-path path)))
78
+  (let ((old (find-content-by-path path))
79
+        (new (construct ctype (read-content path))))
80
+    (setf (gethash (page-url old) coleslaw::*site*) new)
81
+    ;; TODO:
82
+    ;; Iterate over tags in new, setting old to new in each tag index's content.
83
+    ;; If there are new tags/date, add it to relevant indices.
84
+    ;; If tags/date are removed, remove from relevant indices.
62 85
     ))
63 86
 
64 87
 (defmethod process-change ((status (eql :added)) path &key ctype)
65
-  (let ((obj (construct ctype (read-content path))))
88
+  (let ((new (construct ctype (read-content path))))
66 89
     ))
67 90
 
91
+(defun delete-document (document)
92
+  "Given a DOCUMENT, delete it from the staging directory and in-memory DB."
93
+  (let ((url (page-url document)))
94
+    (delete-file (rel-path (staging-dir *config*) (namestring url)))
95
+    (remhash (page-url document) coleslaw::*site*)))
96
+
68 97
 (defun coleslaw::compile-blog (staging)
69 98
   "lulz. Do it live. DO IT ALL LIVE."
99
+  (dolist (doc-type *transients*)
100
+    (publish (find-class doc-type)))
70 101
   ;; FIXME: This doesn't cover prev/next links for posts, theme-fn for feeds.
71 102
   (mapcar #'write-document *changed-content*))
72 103