diff --git a/.gitignore b/.gitignore index e63012d..2dfe775 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,3 @@ .qlot -public/dist.css bin/tailwindcss +public/style/dist.css diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..90353a2 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,25 @@ +FROM fukamachi/qlot + +# 作業ディレクトリ +WORKDIR /app + +# ソース全体をコピー +COPY . /app + +# Tailwind CLI をダウンロード&インストール +RUN mkdir -p ./bin \ + && curl -sLO https://github.com/tailwindlabs/tailwindcss/releases/latest/download/tailwindcss-linux-x64 \ + && chmod +x tailwindcss-linux-x64 \ + && mv tailwindcss-linux-x64 ./bin/tailwindcss + +# Tailwind CSS をビルド(global.css -> dist.css) +RUN ./bin/tailwindcss -i ./public/style/global.css -o ./public/style/dist.css --minify + +# Qlot依存関係のインストール +RUN qlot install + +# ポート開放 +EXPOSE 3000 + +# アプリ起動 +CMD [".qlot/bin/clackup", "--system", "hp", "--server", "woo", "--port", "3000", "src/app.lisp"] diff --git a/Makefile b/Makefile index 9e820ae..b5ba028 100644 --- a/Makefile +++ b/Makefile @@ -2,8 +2,8 @@ TAILWIND_URL=https://github.com/tailwindlabs/tailwindcss/releases/latest/downloa TAILWIND_TARGET=tailwindcss-macos-arm64 BIN_DIR=./bin TAILWIND_BIN=$(BIN_DIR)/tailwindcss -STYLE_SRC=./public/style.css -STYLE_DIST=./public/dist.css +STYLE_SRC=./public/style/global.css +STYLE_DIST=./public/style/dist.css all: install @@ -40,4 +40,10 @@ lem: ## Open Lem with TailwindCSS server WATCH_PID=$$!; \ trap "kill $$WATCH_PID" SIGINT SIGTERM EXIT; \ lem; \ - kill $$WATCH_PID \ No newline at end of file + kill $$WATCH_PID + +docker-build: + docker build -t hp . + +docker-run: + docker run -p 3000:3000 hp \ No newline at end of file diff --git a/README.md b/README.md index 66efaf1..e245afd 100644 --- a/README.md +++ b/README.md @@ -1 +1 @@ -# homepage (WIP) +# hp diff --git a/public/favicon.ico b/public/favicon.ico deleted file mode 100644 index 60cabc0..0000000 Binary files a/public/favicon.ico and /dev/null differ diff --git a/public/fv.jpg b/public/fv.jpg deleted file mode 100644 index ca68e44..0000000 Binary files a/public/fv.jpg and /dev/null differ diff --git a/public/img/favicon.ico b/public/img/favicon.ico new file mode 100644 index 0000000..4dc7866 Binary files /dev/null and b/public/img/favicon.ico differ diff --git a/public/img/me.jpg b/public/img/me.jpg new file mode 100644 index 0000000..e78e422 Binary files /dev/null and b/public/img/me.jpg differ diff --git a/public/logo.png b/public/logo.png deleted file mode 100644 index 75a0ef9..0000000 Binary files a/public/logo.png and /dev/null differ diff --git a/public/style.css b/public/style/global.css similarity index 100% rename from public/style.css rename to public/style/global.css diff --git a/qlfile b/qlfile index 70b08f9..5baf28a 100644 --- a/qlfile +++ b/qlfile @@ -2,8 +2,10 @@ ql fiveam ql cl-jingle git hsx https://github.com/skyizwhite/hsx.git git ningle-fbr https://github.com/skyizwhite/ningle-fbr.git +git lack-mw https://github.com/skyizwhite/lack-mw.git ql cl-ppcre ql trivial-backtrace ql trivia ql cl-str ql quri +ql clack diff --git a/qlfile.lock b/qlfile.lock index 4625fbc..4b4d73b 100644 --- a/qlfile.lock +++ b/qlfile.lock @@ -1,11 +1,11 @@ ("quicklisp" . (:class qlot/source/dist:source-dist :initargs (:distribution "https://beta.quicklisp.org/dist/quicklisp.txt" :%version :latest) - :version "2023-10-21")) + :version "2024-10-12")) ("fiveam" . (:class qlot/source/ql:source-ql :initargs (:%version :latest) - :version "ql-2023-10-21")) + :version "ql-2024-10-12")) ("cl-jingle" . (:class qlot/source/ql:source-ql :initargs (:%version :latest) @@ -13,19 +13,23 @@ ("hsx" . (:class qlot/source/git:source-git :initargs (:remote-url "https://github.com/skyizwhite/hsx.git") - :version "git-f60259ec4a101de87c5364c3f1b571706448d3a0")) + :version "git-4ff1c97e3ff727aa332995f5be4dcfb138a45d5f")) ("ningle-fbr" . (:class qlot/source/git:source-git :initargs (:remote-url "https://github.com/skyizwhite/ningle-fbr.git") - :version "git-d20dbe264911b7dfd6e6fade899db9b09bd2dd32")) + :version "git-bc87e5de01959cd99364bc14ad3eaf88e52e4478")) +("lack-mw" . + (:class qlot/source/git:source-git + :initargs (:remote-url "https://github.com/skyizwhite/lack-mw.git") + :version "git-77a0f436635e5beadaba3765492832704a015a3c")) ("cl-ppcre" . (:class qlot/source/ql:source-ql :initargs (:%version :latest) - :version "ql-2023-10-21")) + :version "ql-2024-10-12")) ("trivial-backtrace" . (:class qlot/source/ql:source-ql :initargs (:%version :latest) - :version "ql-2023-10-21")) + :version "ql-2023-02-14")) ("trivia" . (:class qlot/source/ql:source-ql :initargs (:%version :latest) @@ -38,3 +42,7 @@ (:class qlot/source/ql:source-ql :initargs (:%version :latest) :version "ql-2024-10-12")) +("clack" . + (:class qlot/source/ql:source-ql + :initargs (:%version :latest) + :version "ql-2024-10-12")) diff --git a/src/app.lisp b/src/app.lisp index 6465f44..07bebf9 100644 --- a/src/app.lisp +++ b/src/app.lisp @@ -20,3 +20,5 @@ (jg:install-middleware *app* *recoverer*) (jg:install-middleware *app* *trim-trailing-slash*) (jg:install-middleware *app* *public-server*) + +(jg:configure *app*) diff --git a/src/components/footer.lisp b/src/components/footer.lisp deleted file mode 100644 index bac89ba..0000000 --- a/src/components/footer.lisp +++ /dev/null @@ -1,11 +0,0 @@ -(defpackage #:hp/components/footer - (:use #:cl - #:hsx) - (:export #:~footer)) -(in-package #:hp/components/footer) - -(defcomp ~footer () - (hsx - (footer :class "fixed bottom-0 w-full" - (div :class "container py-6 flex justify-end" - (p "© 2025 skyizwhite"))))) \ No newline at end of file diff --git a/src/components/header.lisp b/src/components/header.lisp deleted file mode 100644 index 7af6768..0000000 --- a/src/components/header.lisp +++ /dev/null @@ -1,27 +0,0 @@ -(defpackage #:hp/components/header - (:use #:cl - #:hsx) - (:export #:~header)) -(in-package #:hp/components/header) - -(defcomp ~header () - (let ((links '(("Home" "/") - ("About" "/about") - ("Work" "/work") - ("Article" "/article") - ("Contact" "/contact")))) - (hsx - (header :class "fixed top-0 w-full" - (div :class "container flex justify-between py-6" - (h1 - (a :href "/" - (img - :src "/logo.png" :alt "Amongtellers" - :class "w-52 h-auto"))) - (ul :class "flex flex-col gap-4" - (loop - :for (title href) :in links :collect - (hsx - (li :class "flex items-center" - (a :href href :class "text-lg hover:text-orange-600" - title)))))))))) diff --git a/src/main.lisp b/src/main.lisp index c83f1f6..17327df 100644 --- a/src/main.lisp +++ b/src/main.lisp @@ -11,10 +11,7 @@ (in-package #:hp) (defun start () - (jg:start *app*) - (when (env:dev-mode-p) - (uiop:run-program (format nil "open http://~a:~a" - env:*address* env:*port*)))) + (jg:start *app*)) (defun stop () (jg:stop *app*)) diff --git a/src/renderer.lisp b/src/renderer.lisp index 05f127d..4f5623d 100644 --- a/src/renderer.lisp +++ b/src/renderer.lisp @@ -2,54 +2,73 @@ (:use #:cl #:hsx #:trivia) - (:import-from #:str) (:local-nicknames (#:jg #:jingle)) (:import-from #:hsx/element #:element) - (:local-nicknames (#:env #:hp/env)) - (:import-from #:hp/components/header - #:~header) - (:import-from #:hp/components/footer - #:~footer)) + (:local-nicknames (#:env #:hp/env))) (in-package #:hp/renderer) (defun bust-cache (url) - (format nil "~a?~a" url #.(get-universal-time))) + (format nil "~a?v=~a" url (get-universal-time))) -(defcomp ~document (&key title description children) +(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" + :og-image (lambda (path) + (format nil "https://skyizwhite.dev~@[~a~]" path)) + :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) (hsx (html :lang "ja" (head (meta :charset "UTF-8") (meta :name "viewport" :content "width=device-width, initial-scale=1") - (link :rel "icon" :href (bust-cache "/favicon.ico")) - (link :rel "apple-touch-icon" :href (bust-cache "/favicon.ico")) - (link :rel "stylesheet" :href (bust-cache "/dist.css")) + (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")) (link :rel "preconnect" :href "https://fonts.googleapis.com") (link :rel "preconnect" :href "https://fonts.gstatic.com" :crossorigin t) (link :rel "stylesheet" :href "https://fonts.googleapis.com/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) - (title (format nil "~@[~a - ~]Amongtellers" title)) - (meta - :name "description" - :content - (or description - (hsx - (<> - "Welcome to the official website of 'Amongtellers (Amaterasu)', " - "a personal project by paku (skyizwhite). " - "Discover project details, the latest updates, and related activities."))))) + (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" - (~header) (main :class "flex-1 h-full" - children) - (~footer))))) + children))))) (defmethod jg:process-response ((app jg:app) result) (jg:set-response-header :content-type "text/html; charset=utf-8") @@ -63,5 +82,6 @@ ((guard (or (list element metadata) element) (typep element 'element)) - (~document metadata element)) + (~document (complete-metadata metadata) + element)) (_ (error "Invalid response form")))))) diff --git a/src/routes/index.lisp b/src/routes/index.lisp index 95f7371..0ef2dd5 100644 --- a/src/routes/index.lisp +++ b/src/routes/index.lisp @@ -4,18 +4,28 @@ (:export #:handle-get)) (in-package #:hp/routes/index) +(defparameter *links* + '(("Keyoxide" "https://keyoxide.org/f39d5b2c951d16732a5cd3528f0c1a22f26d7e62") + ("GitHub" "https://github.com/skyizwhite") + ("Forgejo" "https://code.skyizwhite.dev/paku") + ("X" "https://x.com/skyizwhite") + ("Fediverse" "https://himagine.club/@skyizwhite") + ("Service Status" "https://status.skyizwhite.dev"))) + (defcomp ~page () (hsx - (section - ; first view - (div :class "h-[100svh] bg-[url('/fv.jpg')] bg-cover bg-center flex" - (div :class "container flex items-end justify-between" - (h1 :class "flex flex-col text-6xl font-bold italic leading-normal pb-10" - (span :class "block" - "Beyond Differences,") - (span :class "block" - "Shaping Tomorrow"))))))) - + (section :class "flex flex-col items-center justify-center h-full" + (img :src "/img/me.jpg" :alt "Profile Picture" :class "size-40 rounded rounded-full border shadow-lg") + (div :class "flex flex-col items-center gap-2 py-6" + (h1 :class "font-bold text-2xl" + "Akira Tempaku") + (p :class "text-xl" + "Web developer")) + (div :class "flex flex-col items-center text-pink-500" + (loop + :for (name url) :in *links* + :collect (hsx (a :href url :target "_blank" :class "text-lg hover:underline" + name))))))) (defun handle-get (params) (declare (ignore params)) (~page)) diff --git a/src/routes/not-found.lisp b/src/routes/not-found.lisp index 97b0750..f1301af 100644 --- a/src/routes/not-found.lisp +++ b/src/routes/not-found.lisp @@ -11,12 +11,8 @@ (defcomp ~page () (hsx - (section :class "container flex flex-col justify-center items-center h-full gap-10" - (h1 :class "text-2xl text-red-600" - (getf *metadata* :title)) - (p (getf *metadata* :description)) - (a :href "/" :class "text-orange-600" - "Return to the homepage")))) + (section + (h1 "404 Not Found")))) (defun handle-not-found () (jg:set-response-status :not-found)