website/src/renderer.lisp

89 lines
3.8 KiB
Common Lisp
Raw Normal View History

2024-10-03 14:48:42 +09:00
(defpackage #:hp/renderer
2024-06-15 21:59:15 +09:00
(:use #:cl
2024-11-16 01:52:01 +09:00
#:hsx
#:trivia)
2025-03-29 01:07:45 +09:00
(:import-from :jingle)
2024-11-16 01:52:01 +09:00
(:import-from #:hsx/element
2025-03-29 12:01:07 +09:00
#:element)
(:import-from #:hp/env
#:hp-env))
2024-10-03 14:48:42 +09:00
(in-package #:hp/renderer)
2024-06-01 22:21:15 +09:00
2024-11-16 14:02:31 +09:00
(defun bust-cache (url)
2025-03-29 12:01:07 +09:00
(format nil "~a?v=~a" url (if (string= (hp-env) "dev")
(get-universal-time)
#.(get-universal-time))))
2024-11-16 14:02:31 +09:00
2025-03-28 23:12:07 +09:00
(defparameter *metadata-template*
(list :title (lambda (title)
(format nil "~@[~a - ~]~a" title "skyizwhite.dev"))
:description "The personal homepage of Akira Tempaku (paku) - projects, thoughts, and more."
:og-url "https://skyizwhite.dev"
:og-type "website"
2025-03-29 03:10:50 +09:00
:og-image "https://skyizwhite.dev/img/og.jpg"
2025-03-28 23:12:07 +09:00
:og-image-width 1024
:og-image-height 1024))
(defun complete-metadata (metadata)
(loop
:for (key template) :on *metadata-template* by #'cddr
:for value := (getf metadata key)
:append (list key (if (functionp template)
(funcall template value)
(or value template)))))
(defcomp ~document (&key title
description
og-url
og-type
og-image
og-image-width
og-image-height
children)
2024-06-15 21:59:15 +09:00
(hsx
(html :lang "ja"
(head
(meta :charset "UTF-8")
(meta :name "viewport" :content "width=device-width, initial-scale=1")
2025-03-28 23:12:07 +09:00
(title title)
(meta :name "description" :content description)
(meta :property "og:title" :content title)
(meta :property "og:description" :content description)
(meta :property "og:url" :content og-url)
(meta :property "og:type" :content og-type)
(meta :property "og:site_name" :content "skyizwhite.dev")
(meta :property "og:image" :content og-image)
(meta :property "og:image:width" :content og-image-width)
(meta :property "og:image:height" :content og-image-height)
(link :rel "icon" :type "image/x-icon" :href "/img/favicon.ico")
(link :rel "apple-touch-icon" :href "/img/favicon.ico")
(link :rel "stylesheet" :href (bust-cache "/style/dist.css"))
2025-03-29 14:07:33 +09:00
(link :rel "preconnect" :href "https://api.fonts.coollabs.io")
(link :rel "stylesheet" :href "https://api.fonts.coollabs.io/css2?family=Noto+Sans+JP&display=swap")
2024-06-18 10:14:51 +09:00
(script :src "https://cdn.jsdelivr.net/npm/htmx.org@2.0.0/dist/htmx.min.js")
(script :src "https://cdn.jsdelivr.net/npm/htmx-ext-head-support@2.0.0/head-support.min.js")
2024-11-16 14:02:31 +09:00
(script :src "https://cdn.jsdelivr.net/npm/htmx-ext-response-targets@2.0.0/response-targets.min.js")
2025-03-28 23:12:07 +09:00
(script :src "https://cdn.jsdelivr.net/npm/alpinejs@3.14.0/dist/cdn.min.js" :defer t))
2024-11-16 14:45:06 +09:00
(body
:hx-ext "head-support, response-targets"
:hx-boost "true" :hx-target-404 "body" :hx-target-5* "body"
:class "h-[100svh] flex flex-col"
2024-11-17 00:59:06 +09:00
(main :class "flex-1 h-full"
2025-03-28 23:12:07 +09:00
children)))))
2024-06-15 21:59:15 +09:00
2025-03-29 01:07:45 +09:00
(defmethod jingle:process-response ((app jingle:app) result)
(jingle:set-response-header :content-type "text/html; charset=utf-8")
2025-03-29 12:01:07 +09:00
(when (string= (hp-env) "dev")
2025-03-29 01:07:45 +09:00
(jingle:set-response-header :cache-control "no-store, no-cache, must-revalidate")
(jingle:set-response-header :pragma "no-cache")
(jingle:set-response-header :expires "0"))
2024-10-02 23:36:30 +09:00
(call-next-method app
(hsx:render-to-string
2024-11-16 01:52:01 +09:00
(match result
((guard (or (list element metadata)
element)
(typep element 'element))
2025-03-28 23:12:07 +09:00
(~document (complete-metadata metadata)
element))
2024-11-16 01:52:01 +09:00
(_ (error "Invalid response form"))))))