diff --git a/src/components/layout.lisp b/src/components/layout.lisp index 3beb8fd..4204c40 100644 --- a/src/components/layout.lisp +++ b/src/components/layout.lisp @@ -8,41 +8,17 @@ (:export #:~layout)) (in-package #:website/components/layout) -(defun bust-cache (url) - (format nil "~a?v=~a" url #.(get-universal-time))) - -(defcomp ~layout (&key metadata children) +(defcomp ~layout (&key children) (hsx - (html :lang "ja" - (head - (meta :charset "UTF-8") - (meta :name "viewport" :content "width=device-width, initial-scale=1") - (~metadata :metadata metadata) - (link :rel "icon" :type "image/png" :href "/img/favicon-96x96.png" :sizes "96x96") - (link :rel "icon" :type "image/svg+xml" :href "/img/favicon.svg") - (link :rel "shortcut icon" :href "/img/favicon.ico") - (link :rel "apple-touch-icon" :sizes "180x180" :href "/img/apple-touch-icon.png") - (meta :name "apple-mobile-web-app-title" :content "skyizwhite") - (link :rel "manifest" :href "/img/site.webmanifest") - (link :rel "stylesheet" :href (bust-cache "/style/dist.css")) - (link :rel "preconnect" :href "https://fonts.googleapis.com") - (link :rel "stylesheet" :href "https://fonts.googleapis.com/css2?family=Zen+Maru+Gothic:wght@400;500;700&display=swap") - (script :src "https://cdn.jsdelivr.net/npm/htmx.org@2.0.4/dist/htmx.min.js") - (script :src "https://cdn.jsdelivr.net/npm/htmx-ext-preload@2.1.1/dist/preload.min.js") - (script :src "https://cdn.jsdelivr.net/npm/htmx-ext-head-support@2.0.4/dist/head-support.min.js") - (script :src "https://cdn.jsdelivr.net/npm/htmx-ext-response-targets@2.0.3/dist/response-targets.min.js") - (script :src "https://cdn.jsdelivr.net/npm/htmx-ext-alpine-morph@2.0.1/alpine-morph.min.js") - (script :src "https://cdn.jsdelivr.net/npm/@alpinejs/morph@3.14.9/dist/cdn.min.js" :defer t) - (script :src "https://cdn.jsdelivr.net/npm/alpinejs@3.14.9/dist/cdn.min.js" :defer t)) - (body - :hx-ext "head-support, response-targets, preload, alpine-morph" - :hx-boost "true" :hx-target-404 "body" :hx-target-5* "body" - :class (<> - "flex flex-col h-[100svh] w-full max-w-[700px] " - "px-2 mx-auto") - (~header) - (div :class "flex flex-col flex-1 overflow-y-scroll" - (main :class "flex-1 px-2 py-6 md:px-4 md:py-8" - children) - (footer :class "flex p-2 justify-center text-sm border-t-1" - (p "© 2025 Akira Tempaku"))))))) + (body + :hx-ext "head-support, response-targets, preload, alpine-morph" + :hx-boost "true" :hx-target-404 "body" :hx-target-5* "body" + :class (<> + "flex flex-col h-[100svh] w-full max-w-[700px] " + "px-2 mx-auto") + (~header) + (div :class "flex flex-col flex-1 overflow-y-scroll" + (main :class "flex-1 px-2 py-6 md:px-4 md:py-8" + children) + (footer :class "flex p-2 justify-center text-sm border-t-1" + (p "© 2025 Akira Tempaku")))))) diff --git a/src/renderer.lisp b/src/renderer.lisp index 5de6845..13429c8 100644 --- a/src/renderer.lisp +++ b/src/renderer.lisp @@ -3,6 +3,7 @@ #:hsx #:trivia) (:import-from #:jingle + #:get-request-header #:set-response-header) (:import-from #:hsx/element #:element) @@ -10,15 +11,46 @@ #:website-url #:website-env) (:import-from #:website/components/layout - #:~layout)) + #:~layout) + (:import-from #:website/components/metadata + #:~metadata)) (in-package #:website/renderer) +(defun bust-cache (url) + (format nil "~a?v=~a" url #.(get-universal-time))) + +(defcomp ~document (&key metadata children) + (hsx + (html :lang "ja" + (head + (meta :charset "UTF-8") + (meta :name "viewport" :content "width=device-width, initial-scale=1") + (~metadata :metadata metadata) + (link :rel "icon" :type "image/png" :href "/img/favicon-96x96.png" :sizes "96x96") + (link :rel "icon" :type "image/svg+xml" :href "/img/favicon.svg") + (link :rel "shortcut icon" :href "/img/favicon.ico") + (link :rel "apple-touch-icon" :sizes "180x180" :href "/img/apple-touch-icon.png") + (meta :name "apple-mobile-web-app-title" :content "skyizwhite") + (link :rel "manifest" :href "/img/site.webmanifest") + (link :rel "stylesheet" :href (bust-cache "/style/dist.css")) + (link :rel "preconnect" :href "https://fonts.googleapis.com") + (link :rel "stylesheet" :href "https://fonts.googleapis.com/css2?family=Zen+Maru+Gothic:wght@400;500;700&display=swap") + (script :src "https://cdn.jsdelivr.net/npm/htmx.org@2.0.4/dist/htmx.min.js") + (script :src "https://cdn.jsdelivr.net/npm/htmx-ext-preload@2.1.1/dist/preload.min.js") + (script :src "https://cdn.jsdelivr.net/npm/htmx-ext-head-support@2.0.4/dist/head-support.min.js") + (script :src "https://cdn.jsdelivr.net/npm/htmx-ext-response-targets@2.0.3/dist/response-targets.min.js") + (script :src "https://cdn.jsdelivr.net/npm/htmx-ext-alpine-morph@2.0.1/alpine-morph.min.js") + (script :src "https://cdn.jsdelivr.net/npm/@alpinejs/morph@3.14.9/dist/cdn.min.js" :defer t) + (script :src "https://cdn.jsdelivr.net/npm/alpinejs@3.14.9/dist/cdn.min.js" :defer t)) + children))) + + (defun set-cache-control (strategy) (set-response-header :cache-control (if (string= (website-env) "dev") "private, no-store" (cond - ((eq strategy :static) "public, max-age=60, s-maxage=31536000") + ((eq strategy :static) "public, max-age=60, s-maxage=604800, immutable") ((eq strategy :dynamic) "public, max-age=60") (t "private, no-store"))))) @@ -30,10 +62,11 @@ :cache cache :partial partial) (set-cache-control cache) - (call-next-method app + (call-next-method app (hsx:render-to-string (if partial body - (~layout :metadata metadata - body))))) + (~document :metadata metadata + (~layout + body)))))) (_ (error "Invalid response form"))))