Public archive for the Return to Ritherdon project.
https://www.nicolaellisandritherdon.com
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
126 lines
4.9 KiB
126 lines
4.9 KiB
(in-package #:cl-user) |
|
(defpackage #:ritherdon-archive.view |
|
(:use #:cl) |
|
(:import-from #:ritherdon-archive.config |
|
#:*template-directory*) |
|
(:import-from #:caveman2 |
|
#:*response* |
|
#:response-headers) |
|
(:import-from #:djula |
|
#:add-template-directory |
|
#:compile-template* |
|
#:render-template* |
|
#:*djula-execute-package*) |
|
(:import-from #:datafly |
|
:encode-json) |
|
(:export #:render |
|
#:render-json)) |
|
(in-package #:ritherdon-archive.view) |
|
|
|
(djula:add-template-directory *template-directory*) |
|
|
|
(defparameter *template-registry* (make-hash-table :test 'equal)) |
|
|
|
(defun render (template-path &optional env) |
|
(let ((template (gethash template-path *template-registry*))) |
|
(unless template |
|
(setf template (djula:compile-template* (princ-to-string template-path))) |
|
(setf (gethash template-path *template-registry*) template)) |
|
(apply #'djula:render-template* |
|
template nil |
|
env))) |
|
|
|
(defun render-json (object) |
|
(setf (getf (response-headers *response*) :content-type) "application/json") |
|
(encode-json object)) |
|
|
|
|
|
;; |
|
;; Execute package definition |
|
|
|
(defpackage ritherdon-archive.djula |
|
(:use #:cl |
|
#:storage) |
|
(:import-from #:files |
|
#:storage-file) |
|
(:import-from #:ritherdon-archive.config |
|
#:config |
|
#:appenv |
|
#:developmentp |
|
#:productionp) |
|
(:import-from #:caveman2 |
|
#:url-for)) |
|
|
|
;; Added 'in-package' line after default Caveman2 set-up. Needed for custom |
|
;; functions. Not part of Caveman2 set-up. |
|
(in-package #:ritherdon-archive.djula) |
|
|
|
(setf djula:*djula-execute-package* (find-package :ritherdon-archive.djula)) |
|
|
|
;; Custom filters and template code added below... |
|
;; ============================================================================= |
|
|
|
;; This filter is for converting Integers used to store Boolean values |
|
;; in a SQLite database. The intended place you will use this filter |
|
;; is in the /software section. The most notable parts being the /add |
|
;; and /edit sections. In the SQLite database, I have set: |
|
;; - 0 => false |
|
;; - 1 => true. |
|
;; In this case, if the `VALUE' is not 1, it is always false (I.E. 0). |
|
(djula:def-filter :integer-to-checkbox (value) |
|
(format nil "~S" (if (= 1 value) "on" "off"))) |
|
|
|
(djula:def-filter :build-thumbnail-path (file) |
|
(cond ((str:contains? "image" (files::file-type-of file) :ignore-case t) |
|
(format nil "/storage/thumb/media/~a" (files::slug-of file))) |
|
((str:contains? "pdf" (files::file-type-of file) :ignore-case t) |
|
(format nil "/images/icons/pdf.png")) |
|
((str:contains? "html" (files::file-type-of file) :ignore-case t) |
|
(format nil "/images/icons/code.png")) |
|
((str:contains? "text" (files::file-type-of file) :ignore-case t) |
|
(format nil "/images/icons/txt.png")) |
|
((str:contains? "css" (files::file-type-of file) :ignore-case t) |
|
(format nil "/images/icons/code2.png")) |
|
((str:contains? "video" (files::file-type-of file) :ignore-case t) |
|
(format nil "/images/icons/video.png")) |
|
((str:contains? "audio" (files::file-type-of file) :ignore-case t) |
|
(format nil "/images/icons/audio.png")) |
|
((str:contains? "zip" (files::file-type-of file) :ignore-case t) |
|
(format nil "/images/icons/archive.png")) |
|
(t (format nil "/images/icons/file.png")))) |
|
|
|
(defun insert-snippet (snippet-name) |
|
(if (storage:file-exists-p "" "snippets" snippet-name) |
|
(format nil "~a" (storage:open-text-file "" "snippets" snippet-name)) |
|
(format nil "<!-- ~a not found -->" snippet-name))) |
|
|
|
(defun insert-dashboard-cat () |
|
(let ((timestamp (local-time:now))) |
|
(cond ((and (>= (local-time:timestamp-hour timestamp) 6) |
|
(< (local-time:timestamp-hour timestamp) 10)) |
|
(format nil "/images/icons/morning-cat.png")) |
|
((and (>= (local-time:timestamp-hour timestamp) 10) |
|
(< (local-time:timestamp-hour timestamp) 12)) |
|
(format nil "/images/icons/coffee-cat.png")) |
|
((and (>= (local-time:timestamp-hour timestamp) 12) |
|
(< (local-time:timestamp-hour timestamp) 14)) |
|
(format nil "/images/icons/dinner-cat.png")) |
|
((and (>= (local-time:timestamp-hour timestamp) 14) |
|
(< (local-time:timestamp-hour timestamp) 18)) |
|
(format nil "/images/icons/study-cat.png")) |
|
((and (>= (local-time:timestamp-hour timestamp) 18) |
|
(< (local-time:timestamp-hour timestamp) 20)) |
|
(cond ((<= (local-time:timestamp-day-of-week timestamp) 5) |
|
(format nil "/images/icons/workout-cat.png")) |
|
((= (local-time:timestamp-day-of-week timestamp) 6) |
|
(format nil "/images/icons/rock-star-cat.png")) |
|
((= (local-time:timestamp-day-of-week timestamp) 7) |
|
(format nil "/images/icons/love-cat.png")))) |
|
((and (>= (local-time:timestamp-hour timestamp) 20) |
|
(< (local-time:timestamp-hour timestamp) 22)) |
|
(format nil "/images/icons/dinner-cat.png")) |
|
((and (>= (local-time:timestamp-hour timestamp) 22) |
|
(< (local-time:timestamp-hour timestamp) 24)) |
|
(format nil "/images/icons/bed-time-cat.png")) |
|
(t (format nil "/images/icons/default-cat.png"))))) |
|
|
|
|