Flexible Lisp Blogware. Fork for personal use. Mirrored from https://github.com/kingcons/coleslaw originally.

coleslaw.lisp 2.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172
  1. (in-package :coleslaw)
  2. (defvar *last-revision* nil
  3. "The git revision prior to the last push. For use with GET-UPDATED-FILES.")
  4. (defun main (repo-dir &optional oldrev)
  5. "Load the user's config file, then compile and deploy the blog stored
  6. in REPO-DIR. Optionally, OLDREV is the revision prior to the last push."
  7. (load-config repo-dir)
  8. (setf *last-revision* oldrev)
  9. (load-content)
  10. (compile-theme (theme *config*))
  11. (let ((dir (staging-dir *config*)))
  12. (compile-blog dir)
  13. (deploy dir)))
  14. (defun load-content ()
  15. "Load all content stored in the blog's repo."
  16. (do-subclasses (ctype content)
  17. (discover ctype))
  18. (update-content-metadata)
  19. (do-subclasses (itype index)
  20. (discover itype)))
  21. (defun compile-blog (staging)
  22. "Compile the blog to a STAGING directory as specified in .coleslawrc."
  23. (ensure-directories-exist staging)
  24. (with-current-directory staging
  25. (let ((theme-dir (find-theme (theme *config*))))
  26. (dolist (dir (list (merge-pathnames "css" theme-dir)
  27. (merge-pathnames "img" theme-dir)
  28. (merge-pathnames "js" theme-dir)
  29. (repo-path "static")))
  30. (when (probe-file dir)
  31. (run-program "rsync --delete -raz ~a ." dir))))
  32. (do-subclasses (ctype content)
  33. (publish ctype))
  34. (do-subclasses (itype index)
  35. (publish itype))
  36. (update-symlink (format nil "index.~A" (page-ext *config*))
  37. (format nil "1.~A" (page-ext *config*)))))
  38. (defgeneric deploy (staging)
  39. (:documentation "Deploy the STAGING build to the directory specified in the config.")
  40. (:method (staging)
  41. (run-program "rsync --delete -avz ~a ~a" staging (deploy-dir *config*))))
  42. (defun update-symlink (path target)
  43. "Update the symlink at PATH to point to TARGET."
  44. (run-program "ln -sfn ~a ~a" target path))
  45. (defun preview (path &optional (content-type 'post))
  46. "Render the content at PATH under user's configured repo and save it to
  47. ~/tmp.html. Load the user's config and theme if necessary."
  48. (let ((current-working-directory (cl-fad:pathname-directory-pathname path)))
  49. (unless *config*
  50. (load-config (namestring current-working-directory))
  51. (compile-theme (theme *config*)))
  52. (let* ((file (rel-path (repo-dir *config*) path))
  53. (content (construct content-type (read-content file))))
  54. (write-file "tmp.html" (render-page content)))))
  55. (defun render-page (content &optional theme-fn &rest render-args)
  56. "Render the given CONTENT to HTML using THEME-FN if supplied.
  57. Additional args to render CONTENT can be passed via RENDER-ARGS."
  58. (funcall (or theme-fn (theme-fn 'base))
  59. (list :config *config*
  60. :content content
  61. :raw (apply 'render content render-args)
  62. :pubdate (format-rfc1123-timestring nil (local-time:now))
  63. :injections (find-injections content))))