Created
June 13, 2024 01:59
-
-
Save ccjoel/6be6aa6a757785bbad874b01a7e9beb6 to your computer and use it in GitHub Desktop.
clojure htmx + hiccup + picoCSS
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
;; deps.edn | |
{:paths ["src"] | |
:deps {org.clojure/clojure {:mvn/version "1.11.2"} | |
ring/ring-core {:mvn/version "1.12.1"} | |
ring/ring-devel {:mvn/version "1.12.1"} | |
http-kit/http-kit {:mvn/version "2.8.0"} | |
compojure/compojure {:mvn/version "1.7.1"} | |
rum/rum {:mvn/version "0.12.11" | |
:exclusions [cljsjs/react cljsjs/react-dom]}} | |
:aliases {:run {:ns-default clj32.server | |
:exec-fn run}}} | |
;; src/clj32/server ns file: | |
(ns clj32.server | |
(:require [org.httpkit.server :as hk-server] | |
[ring.middleware.reload :as reload] | |
[compojure.handler :refer [site]] | |
[compojure.core :refer [defroutes GET POST ANY PUT]] | |
[compojure.route :as route] | |
[rum.core :as rum])) | |
(defonce my-server (atom nil)) | |
;; server state, usually a cache/DB in practice | |
;; but we can also have in-memory aspects of server | |
(defonce app-counter (atom 0)) | |
(defn stop-server [] | |
(when-not (nil? @my-server) | |
(@my-server :timeout 100) | |
(reset! my-server nil))) | |
(defn hello-handler [req] | |
{:status 200 | |
:headers {"Content-Type" "text/html"} | |
:body "hello HTTP (KIT)!"}) | |
;; counter "component", reusable widget | |
(rum/defc counter [] | |
[:<> | |
[:p#counter [:span (str "Count is " @app-counter)]] | |
[:form | |
[:input {:name "test-value" :placeholder "Enter here"}] | |
[:button | |
{:hx-post "/count" | |
:hx-trigger "click" | |
:hx-target "#counter" | |
:hx-swap "innerHTML"} | |
"Click Me"]]]) | |
(rum/defc body-contents [] | |
[:<> | |
[:header.container | |
[:nav | |
[:ul | |
[:li [:a {:href "/"} "HOME"]] | |
[:details.dropdown | |
[:summary.secondary {:role "button"} "Theme"] | |
[:ul | |
[:li [:a {:href "#" :data-theme-switcher "light"} "Light"]] | |
[:li [:a {:href "#" :data-theme-switcher "dark"} "dark"]]]]]]] | |
[:main.container | |
[:hgroup | |
[:h1 "Hello, World."] | |
[:p "Trying this out."]] | |
[:article [:h2 "Article"] | |
[:p "Nullam dui arcu, malesuada et sodales eu, efficitur vitae dolor. Sed ultricies dolor non | |
ante vulputate hendrerit. Vivamus sit amet suscipit sapien. Nulla iaculis eros a elit | |
pharetra egestas. Nunc placerat facilisis cursus. Sed vestibulum metus eget dolor pharetra | |
rutrum."] | |
[:footer | |
[:small "Duis nec elit placerat, suscipit nibh quis, finibus neque."]]] | |
(counter)] | |
[:footer.container | |
[:button {:aria-busy "true"} | |
"Please wait…"]]]) | |
(defn index-handler [req] | |
{:status 200 | |
:headers {"Content-Type" "text/html"} | |
:body | |
;; TODO move hardcoded fixed html tags to a different file | |
(rum/render-static-markup | |
[:html {:lang "en"} | |
[:head | |
[:meta {:charset "utf-8"}] | |
[:meta {:name "viewport" :content "width=device-width, initial-scale=1"}] | |
[:meta {:name "color-scheme" :content "light dark"}] | |
[:script {:src "https://unpkg.com/[email protected]" :crossorigin "anonymous"}] | |
[:link | |
{:rel "stylesheet" | |
:href "https://cdn.jsdelivr.net/npm/@picocss/pico@2/css/pico.min.css"}] | |
[:title "hcljx"]] | |
[:body | |
(body-contents) | |
[:script {:src "https://4mrnhq.csb.app/js/minimal-theme-switcher.js"}]]])}) | |
(defroutes app-routes | |
(GET "/" [] index-handler) | |
(POST "/count" [] | |
(fn [req] | |
(swap! app-counter inc) | |
{:status 200 | |
:headers {} | |
;; TODO this span code is duplicated here from counter above | |
;; should just use the same "template" | |
:body (rum/render-static-markup [:span (str "Count is " @app-counter)])})) | |
(GET "/hello" [] hello-handler) | |
(route/not-found "You Must Be New Here")) | |
;; start server in code reload mode | |
(defn run [opts] | |
(reset! my-server | |
(hk-server/run-server | |
(reload/wrap-reload (site #'app-routes)) | |
{:port 8083})) | |
(println "Server started on port 8083")) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment