Bladeren bron

adding additional data to the environment, making more build factors configurable

tycho garen 11 jaren geleden
bovenliggende
commit
25891fb7ca
5 gewijzigde bestanden met toevoegingen van 57 en 35 verwijderingen
  1. 16 11
      src/coleslaw.lisp
  2. 24 13
      src/config.lisp
  3. 2 2
      src/content.lisp
  4. 1 0
      src/packages.lisp
  5. 14 9
      src/posts.lisp

+ 16 - 11
src/coleslaw.lisp

@@ -16,10 +16,16 @@
16 16
   (:documentation "The url to the object, without the domain."))
17 17
 
18 18
 (defmethod page-url :around ((object t))
19
-  (let ((result (call-next-method)))
19
+  (let ((result (call-next-method))
20
+        (extension (if (string-equal (pageext *config*) "/")
21
+                       "html"
22
+                       (pageext *config*))))
23
+    (when (string= (char extension 0) ".")
24
+      (setf extension (string-trim "." extension)))
20 25
     (if (pathname-type result)
21 26
         result
22
-        (make-pathname :type "html" :defaults result))))
27
+        (make-pathname :type extension :defaults result)
28
+        )))
23 29
 
24 30
 (defun page-path (object)
25 31
   "The path to store OBJECT at once rendered."
@@ -46,8 +52,6 @@ Additional args to render CONTENT can be passed via RENDER-ARGS."
46 52
 
47 53
 (defun compile-blog (staging)
48 54
   "Compile the blog to a STAGING directory as specified in .coleslawrc."
49
-  (when (probe-file staging)
50
-    (run-program "rm -R ~a" staging))
51 55
   (ensure-directories-exist staging)
52 56
   (with-current-directory staging
53 57
     (dolist (dir (list (app-path "themes/~a/css" (theme *config*))
@@ -55,7 +59,7 @@ Additional args to render CONTENT can be passed via RENDER-ARGS."
55 59
                        (app-path "themes/~a/js" (theme *config*))
56 60
                        (merge-pathnames "static" (repo *config*))))
57 61
       (when (probe-file dir)
58
-        (run-program "cp -R ~a ." dir)))
62
+        (run-program "rsync --delete -raz ~a ." dir)))
59 63
     (do-ctypes (publish (make-keyword ctype)))
60 64
     (render-indices)
61 65
     (update-symlink "index.html" "1.html")
@@ -88,9 +92,10 @@ Additional args to render CONTENT can be passed via RENDER-ARGS."
88 92
 (defun preview (path &optional (content-type 'post))
89 93
   "Render the content at PATH under user's configured repo and save it to
90 94
 ~/tmp.html. Load the user's config and theme if necessary."
91
-  (unless *config*
92
-    (load-config nil)
93
-    (compile-theme (theme *config*)))
94
-  (let* ((file (rel-path (repo *config*) path))
95
-         (content (construct content-type (read-content file))))
96
-    (write-page "~/tmp.html" (render-page content))))
95
+  (let ((current-working-directory (cl-fad:pathname-directory-pathname path)))
96
+    (unless *config*
97
+      (load-config (namestring current-working-directory))
98
+      (compile-theme (theme *config*)))
99
+    (let* ((file (rel-path (repo *config*) path))
100
+           (content (construct content-type (read-content file))))
101
+      (write-page "tmp.html" (render-page content)))))

+ 24 - 13
src/config.lisp

@@ -1,17 +1,20 @@
1 1
 (in-package :coleslaw)
2 2
 
3 3
 (defclass blog ()
4
-  ((author      :initarg :author      :accessor author)
5
-   (deploy-dir  :initarg :deploy-dir  :accessor deploy-dir)
6
-   (domain      :initarg :domain      :accessor domain)
7
-   (feeds       :initarg :feeds       :accessor feeds)
8
-   (license     :initarg :license     :accessor license)
9
-   (plugins     :initarg :plugins     :accessor plugins)
10
-   (repo        :initarg :repo        :accessor repo)
11
-   (sitenav     :initarg :sitenav     :accessor sitenav)
12
-   (staging-dir :initarg :staging-dir :accessor staging-dir)
13
-   (title       :initarg :title       :accessor title)
14
-   (theme       :initarg :theme       :accessor theme)))
4
+  ((author          :initarg :author         :accessor author)
5
+   (deploy-dir      :initarg :deploy-dir     :accessor deploy-dir)
6
+   (domain          :initarg :domain         :accessor domain)
7
+   (feeds           :initarg :feeds          :accessor feeds)
8
+   (license         :initarg :license        :accessor license)
9
+   (plugins         :initarg :plugins        :accessor plugins)
10
+   (repo            :initarg :repo           :accessor repo)
11
+   (sitenav         :initarg :sitenav        :accessor sitenav)
12
+   (staging-dir     :initarg :staging-dir    :accessor staging-dir)
13
+   (postsdir        :initarg :postsdir       :accessor postsdir      :initform "posts") 
14
+   (separator       :initarg :separator      :accessor separator     :initform ";;;;;")
15
+   (pageext         :initarg :pageext        :accessor pageext       :initform ".html")
16
+   (title           :initarg :title          :accessor title)
17
+   (theme           :initarg :theme          :accessor theme)))
15 18
 
16 19
 (define-condition unknown-config-section-error (error)
17 20
   ((text :initarg :text :reader text)))
@@ -37,10 +40,18 @@ are in the plugins folder in coleslaw's source directory."
37 40
       (destructuring-bind (name &rest args) plugin
38 41
         (apply 'enable-plugin (plugin-path name) args)))))
39 42
 
40
-(defun load-config (&optional config-key (dir (user-homedir-pathname)))
43
+(defun discover-config-path (&optional (path ""))
44
+  (let ((default-path (make-pathname :directory (namestring (user-homedir-pathname)) :name ".coleslawrc"))
45
+        (custom-path (make-pathname :directory path :name ".coleslawrc")))
46
+    (cond
47
+      ((file-exists-p custom-path) custom-path)
48
+      ((file-exists-p default-path) default-path))))
49
+
50
+(defun load-config (config-key)
41 51
   "Load the coleslaw configuration from DIR/.coleslawrc, using CONFIG-KEY
42 52
 if necessary. DIR is ~ by default."
43
-  (with-open-file (in (merge-pathnames ".coleslawrc" dir))
53
+
54
+  (with-open-file (in (discover-config-path config-key))
44 55
     (let ((config-form (read in)))
45 56
       (if (symbolp (car config-form))
46 57
           ;; Single site config: ignore CONFIG-KEY.

+ 2 - 2
src/content.lisp

@@ -51,10 +51,10 @@
51 51
          (read-tags (str)
52 52
            (mapcar #'make-tag (cl-ppcre:split "," str))))
53 53
     (with-open-file (in file)
54
-      (unless (string= (read-line in) ";;;;;")
54
+      (unless (string= (read-line in) (separator *config*))
55 55
         (error "The provided file lacks the expected header."))
56 56
       (let ((meta (loop for line = (read-line in nil)
57
-                     until (string= line ";;;;;")
57
+                     until (string= line (separator *config*))
58 58
                      appending (list (field-name line)
59 59
                                      (aref (parse-field line) 0))))
60 60
             (content (slurp-remainder in)))

+ 1 - 0
src/packages.lisp

@@ -5,6 +5,7 @@
5 5
                             #:make-keyword
6 6
                             #:mappend
7 7
                             #:compose)
8
+  (:import-from :cl-fad #:file-exists-p)
8 9
   (:import-from :closure-template #:compile-template)
9 10
   (:export #:main
10 11
            #:preview

+ 14 - 9
src/posts.lisp

@@ -2,8 +2,21 @@
2 2
 
3 3
 (defclass post (content)
4 4
   ((title :initform nil :initarg :title :accessor post-title)
5
+   (author :initform nil :initarg :author :accessor post-author)
5 6
    (format :initform nil :initarg :format :accessor post-format)))
6 7
 
8
+(defmethod initialize-instance :after ((object post) &key)
9
+  (with-accessors ((title post-title)
10
+                   (author post-author)
11
+                   (format post-format)
12
+                   (text content-text)) object
13
+      (setf (content-slug object) (slugify title)
14
+            format (make-keyword (string-upcase format))
15
+            text (render-content text format)
16
+            author (if author
17
+                       author
18
+                       (author *config*)))))
19
+
7 20
 (defmethod render ((object post) &key prev next)
8 21
   (funcall (theme-fn 'post) (list :config *config*
9 22
                                   :post object
@@ -11,15 +24,7 @@
11 24
                                   :next next)))
12 25
 
13 26
 (defmethod page-url ((object post))
14
-  (format nil "posts/~a" (content-slug object)))
15
-
16
-(defmethod initialize-instance :after ((object post) &key)
17
-  (with-accessors ((title post-title)
18
-                   (format post-format)
19
-                   (text content-text)) object
20
-      (setf (content-slug object) (slugify title)
21
-            format (make-keyword (string-upcase format))
22
-            text (render-content text format))))
27
+  (format nil "~a/~a" (postsdir *config*) (content-slug object)))
23 28
 
24 29
 (defmethod publish ((content-type (eql :post)))
25 30
   (loop for (next post prev) on (append '(nil) (by-date (find-all 'post)))