Refactor components

This commit is contained in:
Akira Tempaku 2025-05-03 23:36:01 +09:00
parent 1b217da311
commit 7b31bd1f18
Signed by: paku
GPG key ID: 5B4E8402BCC50607
7 changed files with 83 additions and 103 deletions

View file

@ -1,8 +1,6 @@
(defpackage #:website/components/layout
(:use #:cl
#:hsx)
(:import-from #:website/components/metadata
#:~metadata)
(:import-from #:website/components/header
#:~header)
(:export #:~layout))
@ -10,12 +8,7 @@
(defcomp ~layout (&key children)
(hsx
(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")
(div :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"

View file

@ -1,75 +1,66 @@
(defpackage #:website/components/metadata
(:use #:cl
#:hsx)
(:import-from #:jingle
#:request-uri)
(:import-from #:website/lib/env
#:website-url)
(:export #:~metadata))
(in-package #:website/components/metadata)
(defun create-metadata (&key title
description
path
canonical
type
image
error)
(list :title title
:description description
:canonical (or canonical path)
:og-title title
:og-description description
:og-url path
:og-type type
:og-image (getf image :url)
:og-image-width (getf image :width)
:og-image-height (getf image :height)
:error error))
(defun path->url (path)
(concatenate 'string
(website-url)
(and (not (string= path "/")) path)))
(defparameter *metadata-template*
(let ((%title (lambda (title) (format nil "~@[~a - ~]~a" title "skyizwhite.dev")))
(%description "The personal website of Akira Tempaku (paku)"))
(list :title %title
:description %description
:canonical #'path->url
:og-title %title
:og-description %description
:og-url #'path->url
:og-type "website"
:og-site-name "skyizwhite.dev"
:og-image (path->url "/img/og.jpg")
:og-image-width 1024
:og-image-height 1024
:error nil)))
(defparameter *default-metadata*
(list :title (lambda (title) (format nil "~@[~a - ~]skyizwhite" title))
:description "The personal website of Akira Tempaku (paku)"
:canonical nil
:type "website"
:image (list :url (path->url "/img/og.jpg")
:height 1024
:width 1024)
:error nil))
(defun create-metadata (&key title
description
canonical
type
image
error)
(let ((path (request-uri jingle:*request*)))
(hsx
(<>
(meta :charset "UTF-8")
(meta :name "viewport" :content "width=device-width, initial-scale=1")
(title title)
(meta :name "description" :content description)
(and (not error)
(hsx (<>
(meta :property "og:title" :content title)
(meta :property "og:description" :content description)
(meta :property "og:url" :content (path->url path))
(meta :property "og:type" :content type)
(meta :property "og:site_name" :content "skyizwhite")
(meta :property "og:image" :content (getf image :url))
(meta :property "og:image:width" :content (getf image :width))
(meta :property "og:image:height" :content (getf image :height))
(link :rel "canonical" :href (path->url (or canonical path))))))
(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")))))
(defun complete-metadata (metadata)
(loop
:for (key template) :on *metadata-template* :by #'cddr
:for (key template) :on *default-metadata* :by #'cddr
:for value := (getf metadata key)
:append (list key (if (functionp template)
(funcall template value)
(or value template)))))
(defcomp ~metadata (&key metadata)
(let ((%metadata (complete-metadata (apply #'create-metadata metadata))))
(hsx
(<>
(title (getf %metadata :title))
(meta :name "description" :content (getf %metadata :description))
(and
(not (getf %metadata :error))
(hsx
(<>
(meta :property "og:title" :content (getf %metadata :og-title))
(meta :property "og:description" :content (getf %metadata :og-description))
(meta :property "og:url" :content (getf %metadata :og-url))
(meta :property "og:type" :content (getf %metadata :og-type))
(meta :property "og:site_name" :content (getf %metadata :og-site-name))
(meta :property "og:image" :content (getf %metadata :og-image))
(meta :property "og:image:width" :content (getf %metadata :og-image-width))
(meta :property "og:image:height" :content (getf %metadata :og-image-height))
(link :rel "canonical" :href (getf %metadata :canonical)))))))))
(apply #'create-metadata (complete-metadata metadata)))

View file

@ -0,0 +1,22 @@
(defpackage #:website/components/scripts
(:use #:cl
#:hsx)
(:export #:~scripts))
(in-package #:website/components/scripts)
(defun bust-cache (url)
(format nil "~a?v=~a" url #.(get-universal-time)))
(defcomp ~scripts ()
(hsx
(<>
(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))))

View file

@ -3,47 +3,19 @@
#:hsx
#:trivia)
(:import-from #:jingle
#:get-request-header
#:set-response-header)
(:import-from #:hsx/element
#:element)
(:import-from #:website/lib/env
#:website-url
#:website-env)
(:import-from #:website/components/layout
#:~layout)
(:import-from #:website/components/metadata
#:~metadata))
#:~metadata)
(:import-from #:website/components/scripts
#:~scripts)
(:import-from #:website/components/layout
#:~layout))
(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)))
(defmethod jingle:process-response ((app jingle:app) result)
(set-response-header :content-type "text/html; charset=utf-8")
(set-response-header :cache-control (if (string= (website-env) "dev")
@ -55,7 +27,12 @@
(typep body 'element))
(call-next-method app
(hsx:render-to-string
(~document :metadata metadata
(~layout
body)))))
(hsx (html :lang "ja"
(head
(~metadata :metadata metadata)
(~scripts))
(body
:hx-ext "head-support, response-targets, preload, alpine-morph"
:hx-boost "true" :hx-target-404 "body" :hx-target-5* "body"
(~layout body)))))))
(_ (error "Invalid response form"))))

View file

@ -10,8 +10,7 @@
(in-package :website/routes/about)
(defparameter *metadata*
(list :title "about"
:path "/about"))
(list :title "about"))
(defcomp ~page ()
(hsx

View file

@ -5,8 +5,7 @@
(in-package :website/routes/blog)
(defparameter *metadata*
(list :title "blog"
:path "/blog"))
(list :title "blog"))
(defcomp ~page ()
(hsx

View file

@ -10,8 +10,7 @@
(in-package :website/routes/work)
(defparameter *metadata*
(list :title "work"
:path "/work"))
(list :title "work"))
(defcomp ~page ()
(hsx