diff --git a/src/lib/metadata.lisp b/src/lib/metadata.lisp new file mode 100644 index 0000000..201bd52 --- /dev/null +++ b/src/lib/metadata.lisp @@ -0,0 +1,29 @@ +(defpackage #:hp/lib/metadata + (:use #:cl) + (:import-from #:hp/lib/env + #:hp-url) + (:export #:complete-metadata)) +(in-package #:hp/lib/metadata) + +(defun path->url (path) + (concatenate 'string + (hp-url) + (and (not (string= path "/")) path))) + +(defparameter *metadata-template* + (list :title (lambda (title) (format nil "~@[~a - ~]~a" title "skyizwhite.dev")) + :description "The personal website of Akira Tempaku (paku) - projects, thoughts, and more." + :canonical #'path->url + :og-url #'path->url + :og-type "website" + :og-image (path->url "/img/og.jpg") + :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))))) diff --git a/src/renderer.lisp b/src/renderer.lisp index 3c7c496..b34f83f 100644 --- a/src/renderer.lisp +++ b/src/renderer.lisp @@ -8,91 +8,24 @@ #:element) (:import-from #:hp/lib/env #:hp-url - #:hp-env)) + #:hp-env) + (:import-from #:hp/lib/metadata + #:complete-metadata) + (:import-from #:hp/ui/layout + #:~layout)) (in-package #:hp/renderer) -(defun path->url (path) - (concatenate 'string - (hp-url) - (and (not (string= path "/")) path))) - -(defparameter *metadata-template* - (list :title (lambda (title) (format nil "~@[~a - ~]~a" title "skyizwhite.dev")) - :description "The personal website of Akira Tempaku (paku) - projects, thoughts, and more." - :canonical #'path->url - :og-url #'path->url - :og-type "website" - :og-image (path->url "/img/og.jpg") - :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))))) - -(defun bust-cache (url) - (format nil "~a?v=~a" url #.(get-universal-time))) - -(defcomp ~document (&key title - description - canonical - og-url - og-type - og-image - og-image-width - og-image-height - children) - (hsx - (html :lang "ja" - (head - (meta :charset "UTF-8") - (meta :name "viewport" :content "width=device-width, initial-scale=1") - (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 "canonical" :href canonical) - (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://api.fonts.coollabs.io") - (link :rel "stylesheet" :href "https://api.fonts.coollabs.io/css2?family=Noto+Sans+JP&display=swap") - (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") - (script :src "https://cdn.jsdelivr.net/npm/htmx-ext-response-targets@2.0.0/response-targets.min.js") - (script :src "https://cdn.jsdelivr.net/npm/alpinejs@3.14.0/dist/cdn.min.js" :defer t)) - (body - :hx-ext "head-support, response-targets" - :hx-boost "true" :hx-target-404 "body" :hx-target-5* "body" - :class "h-[100svh] flex flex-col" - (main :class "flex-1 h-full" - 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= (hp-env) "dev") - "private, no-store, no-cache, must-revalidate" - "public, max-age=60, s-maxage=300, stale-while-revalidate=300, stale-if-error=300")) + "private, no-store" + "public, s-maxage=60, stale-while-revalidate=86400, stale-if-error=86400")) (call-next-method app (hsx:render-to-string (match result ((guard (or (list page metadata) page) (typep page 'element)) - (~document (complete-metadata metadata) + (~layout (complete-metadata metadata) page)) (_ (error "Invalid response form")))))) diff --git a/src/routes/bio.lisp b/src/routes/bio.lisp new file mode 100644 index 0000000..71e5411 --- /dev/null +++ b/src/routes/bio.lisp @@ -0,0 +1,17 @@ +(defpackage #:hp/routes/bio + (:use #:cl + #:hsx) + (:export #:handle-get)) +(in-package :hp/routes/bio) + +(defparameter *metadata* + (list :title "bio")) + +(defcomp ~page () + (hsx + (section + (p "Coming soon...")))) + +(defun handle-get (params) + (declare (ignore params)) + (list (~page) *metadata*)) diff --git a/src/routes/blog.lisp b/src/routes/blog.lisp new file mode 100644 index 0000000..7c13289 --- /dev/null +++ b/src/routes/blog.lisp @@ -0,0 +1,17 @@ +(defpackage #:hp/routes/blog + (:use #:cl + #:hsx) + (:export #:handle-get)) +(in-package :hp/routes/blog) + +(defparameter *metadata* + (list :title "blog")) + +(defcomp ~page () + (hsx + (section + (p "Coming soon...")))) + +(defun handle-get (params) + (declare (ignore params)) + (list (~page) *metadata*)) diff --git a/src/routes/index.lisp b/src/routes/index.lisp index 8cf6c73..11fd0dc 100644 --- a/src/routes/index.lisp +++ b/src/routes/index.lisp @@ -14,16 +14,16 @@ (defcomp ~page () (hsx (section :class "flex flex-col items-center justify-center h-full" - (img :src "/img/me.webp" :alt "Profile Picture" :class "size-40 rounded rounded-full border shadow-lg") + (img :src "/img/avatar.jpg" :alt "avatar" :class "size-40 rounded-xl shadow-sm") (div :class "flex flex-col items-center gap-2 py-6" - (h1 :class "font-bold text-2xl" + (h1 :class "font-bold text-2xl text-center" "Akira Tempaku") (p :class "text-xl" "Web developer")) - (div :class "flex flex-col items-center text-pink-500" + (div :class "flex flex-col items-center" (loop :for (name url) :in *links* - :collect (hsx (a :href url :target "_blank" :class "text-lg hover:underline" + :collect (hsx (a :href url :target "_blank" :class "text-lg underline hover:text-pink-500" name))))))) (defun handle-get (params) diff --git a/src/routes/work.lisp b/src/routes/work.lisp new file mode 100644 index 0000000..fa96819 --- /dev/null +++ b/src/routes/work.lisp @@ -0,0 +1,17 @@ +(defpackage #:hp/routes/work + (:use #:cl + #:hsx) + (:export #:handle-get)) +(in-package :hp/routes/work) + +(defparameter *metadata* + (list :title "work")) + +(defcomp ~page () + (hsx + (section + (p "Coming soon...")))) + +(defun handle-get (params) + (declare (ignore params)) + (list (~page) *metadata*)) diff --git a/src/ui/layout.lisp b/src/ui/layout.lisp new file mode 100644 index 0000000..23785b5 --- /dev/null +++ b/src/ui/layout.lisp @@ -0,0 +1,70 @@ +(defpackage #:hp/ui/layout + (:use #:cl + #:hsx) + (:export #:~layout)) +(in-package #:hp/ui/layout) + +(defun bust-cache (url) + (format nil "~a?v=~a" url #.(get-universal-time))) + +(defcomp ~layout (&key title + description + canonical + og-url + og-type + og-image + og-image-width + og-image-height + children) + (hsx + (html :lang "ja" + (head + (meta :charset "UTF-8") + (meta :name "viewport" :content "width=device-width, initial-scale=1") + (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 "canonical" :href canonical) + (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+Kurenaido&display=swap") + (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-preload@2.0.0/preload.min.js") + (script :src "https://cdn.jsdelivr.net/npm/htmx-ext-head-support@2.0.0/head-support.min.js") + (script :src "https://cdn.jsdelivr.net/npm/htmx-ext-response-targets@2.0.0/response-targets.min.js") + (script :src "https://cdn.jsdelivr.net/npm/alpinejs@3.14.0/dist/cdn.min.js" :defer t)) + (body + :hx-ext "head-support, response-targets, preload" + :hx-boost "true" :hx-target-404 "body" :hx-target-5* "body" + :class (<> + "h-[100svh] flex flex-col bg-[url(/img/bg.jpg)] bg-cover bg-center " + "p-2 md:p-8") + (div :class (<> + "bg-amber-50/90 flex flex-col flex-1 w-full max-w-[700px] overflow-hidden shadow-sm " + "px-2 pt-2 mx-auto md:px-8 md:pt-8") + (header :class "flex justify-between pb-2 md:pb-4 border-b-1" + (h1 :class "text-2xl md:text-4xl font-bold" + (a :href "/" + "skyizwhite")) + (nav :class "flex items-end" + (ul + :class "flex gap-4 text-lg [&_a]:underline [&_a]:hover:text-pink-500" + :preload t + (li (a :href "/bio" "bio")) + (li (a :href "/work" "work")) + (li (a :href "/blog" "blog"))))) + (main :class "flex-1 pt-2 pb-4 md:pt-4 md:pb-8 overflow-y-scroll " + children)))))) diff --git a/static/img/avatar.jpg b/static/img/avatar.jpg new file mode 100644 index 0000000..38cf5fc Binary files /dev/null and b/static/img/avatar.jpg differ diff --git a/static/img/bg.jpg b/static/img/bg.jpg new file mode 100644 index 0000000..f1c176e Binary files /dev/null and b/static/img/bg.jpg differ diff --git a/static/img/me.webp b/static/img/me.webp deleted file mode 100644 index 892723a..0000000 Binary files a/static/img/me.webp and /dev/null differ diff --git a/static/style/global.css b/static/style/global.css index 671406c..dc52305 100644 --- a/static/style/global.css +++ b/static/style/global.css @@ -1,11 +1,11 @@ @import "tailwindcss"; :root { - font-family: 'Noto Sans JP Variable', sans-serif; + font-family: "Zen Kurenaido", sans-serif; } @supports (font-variation-settings: normal) { :root { - font-family: 'Noto Sans JP Variable', sans-serif; + font-family: "Zen Kurenaido", sans-serif; } }