Copy link to clipboard.
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
47402cb1e2
commit
d72019d6bb
|
@ -0,0 +1,8 @@
|
|||
#+TITLE: About
|
||||
#+DESCRIPTION: Examples mostly oriented around web development
|
||||
|
||||
|
||||
* Introduction
|
||||
This site has various example's guides and snippets showing how to use Clojure and ClojureScript, they are mainly based on my journey learning coming from JavaScript and python having no previous experience with java or the JVM.
|
||||
|
||||
Some of the struggles have been around Terminology & inter-op with the host languages along side re orientating my brain to think more functionally.
|
|
@ -21,6 +21,13 @@
|
|||
<meta property="og:site_name" content="SITE NAME" />
|
||||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png" />
|
||||
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png" />
|
||||
<link
|
||||
rel="stylesheet"
|
||||
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css"
|
||||
integrity="sha512-z3gLpd7yknf1YoNbCzqRKc4qyor8gaKU1qmn+CShxbuBusANI9QpRohGBreCFkKxLhei6S9CQXFEbbKuqLg0DA=="
|
||||
crossorigin="anonymous"
|
||||
referrerpolicy="no-referrer"
|
||||
/>
|
||||
<link
|
||||
rel="stylesheet"
|
||||
type="text/css"
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
(ns clojure-demo.components
|
||||
(:require
|
||||
[clojure-demo.state :refer [site-state]]
|
||||
[clojure-demo.helpers :refer [copy->clipboard slugify]]))
|
||||
|
||||
(defn notification []
|
||||
(if (-> @site-state :notification)
|
||||
[:div.fixed.p-5.top-20.right-0.border-2.border-sky-400.bg-white.opacity-100.transition-opacity.delay-150.duration-200
|
||||
(-> @site-state :notification)]
|
||||
[:<>]))
|
||||
|
||||
(defn header-on-click-copy-link [v]
|
||||
{:on-click (fn [] (copy->clipboard (slugify v)))})
|
||||
|
||||
(defn header-lvl1 [v _]
|
||||
[:h1.text-2xl.fw6.lh-title.mt-0.mb-2 {:id (slugify v)}
|
||||
[:a {:name (slugify v)} [:i.fa-solid.fa-link (header-on-click-copy-link v)] v]])
|
||||
|
||||
(defn header-lvl2 [v _]
|
||||
[:h2.text-xl.fw6.lh-title.mt-0.mb-2 {:id (slugify v)}
|
||||
[:a {:name (slugify v)} [:i.fa-solid.fa-link (header-on-click-copy-link v)] v]])
|
||||
|
||||
(defn header-lvl3 [v _]
|
||||
[:h3.text-base.fw6.lh-title.mt-0.mb-2 {:id (slugify v)}
|
||||
[:a {:name (slugify v)} [:i.fa-solid.fa-link (header-on-click-copy-link v)] v]])
|
|
@ -8,16 +8,17 @@
|
|||
["@nextjournal/lang-clojure" :refer [clojure]]
|
||||
["react-dom/client" :refer [createRoot]]
|
||||
["tarts" :as tarts]
|
||||
[tick.core :as t]
|
||||
[cljs.core.async :as async]
|
||||
[cljs.core.async.interop :as async-in]
|
||||
[shadow.cljs.modern :refer [js-await]]
|
||||
[ajax.core :refer [GET raw-response-format]]
|
||||
[cl-eorg.html :as h :refer [body headers org->replacements]]
|
||||
[cl-eorg.parser :as o :refer [parse]]
|
||||
[cl-eorg.themes.tachyon :refer [tachyon-theme]]
|
||||
[clojure.string :as str]
|
||||
[clojure-demo.components
|
||||
:refer [header-lvl1 header-lvl2 header-lvl3 notification]]
|
||||
[clojure-demo.helpers :refer [slugify]]
|
||||
[clojure-demo.state :refer [site-state]]
|
||||
[clojure-demo.tailwind-theme :refer [tailwind-theme]]
|
||||
[clojure.data.xml :as xml]
|
||||
[clojure.string :as str]
|
||||
[honey.sql :as sql]
|
||||
[honey.sql.helpers :as sqlh]
|
||||
[reagent.core :as reagent]
|
||||
|
@ -25,12 +26,12 @@
|
|||
[reitit.frontend :as rf]
|
||||
[reitit.frontend.easy :as rfe]
|
||||
[reitit.frontend.history :refer [ignore-anchor-click?]]
|
||||
[sci.configs.funcool.promesa :as sci-promesa]
|
||||
[sci.configs.reagent.reagent :as sci-reagent]
|
||||
[sci.configs.tonsky.datascript :as sci-datascript]
|
||||
[sci.configs.funcool.promesa :as sci-promesa]
|
||||
[sci.core :as sci]
|
||||
[clojure-demo.tailwind-theme :refer [tailwind-theme]]
|
||||
[spec-tools.data-spec :as ds]))
|
||||
[spec-tools.data-spec :as ds]
|
||||
[tick.core :as t]))
|
||||
|
||||
(def languages
|
||||
{"clojure" {:mode "clojure"}
|
||||
|
@ -41,7 +42,8 @@
|
|||
|
||||
(def yaml-mode (LanguageSupport. (.define StreamLanguage yaml)))
|
||||
|
||||
(defn ^:sci/macro my-js-await [_ _ [name thenable] & body]
|
||||
(defn ^:sci/macro my-js-await
|
||||
[_ _ [name thenable] & body]
|
||||
(let [last-expr (last body)
|
||||
[body catch]
|
||||
(if (and (seq? last-expr) (= 'catch (first last-expr)))
|
||||
|
@ -54,8 +56,7 @@
|
|||
[`(.then (fn [~name] ~@body))])
|
||||
~@(when catch
|
||||
(let [[name & body] catch]
|
||||
[`(.catch (fn [~name] ~@body))]
|
||||
)))))
|
||||
[`(.catch (fn [~name] ~@body))])))))
|
||||
|
||||
;; https://github.com/babashka/sci.configs
|
||||
(def rf-ns (sci/create-ns 'reitit.frontend nil))
|
||||
|
@ -112,14 +113,6 @@
|
|||
;(def sci-ctx (sci/empty-environment))
|
||||
(sci/alter-var-root sci/print-fn (constantly *print-fn*))
|
||||
|
||||
(defn slugify [s]
|
||||
(when s
|
||||
(str
|
||||
(-> s
|
||||
(str/lower-case)
|
||||
(str/replace #"[^\w]+" "-")
|
||||
(str/replace #"^-\\|-\\-$" "")))))
|
||||
|
||||
(defn fetch-selected-text
|
||||
"Get the users selected text"
|
||||
[updated-view transactions]
|
||||
|
@ -208,9 +201,9 @@
|
|||
(def theme-tachyon
|
||||
(merge tachyon-theme
|
||||
{:SRC code-editor
|
||||
:HEADER1 (fn [v _] [:h1 {:id (slugify v)} [:a {:name (slugify v)} v]])
|
||||
:HEADER2 (fn [v _] [:h2 {:id (slugify v)} [:a {:name (slugify v)} v]])
|
||||
:HEADER3 (fn [v _] [:h2 {:id (slugify v)} [:a {:name (slugify v)} v]])
|
||||
:HEADER1 header-lvl1 #_(fn [v _] [:h1 {:id (slugify v)} [:a {:name (slugify v)} v]])
|
||||
:HEADER2 header-lvl2 #_(fn [v _] [:h2 {:id (slugify v)} [:a {:name (slugify v)} v]])
|
||||
:HEADER3 header-lvl3 #_(fn [v _] [:h2 {:id (slugify v)} [:a {:name (slugify v)} v]])
|
||||
:LINE :p.f5.f5-ns.lh-copy.mt0
|
||||
:BULLETS :ul.mt0
|
||||
:LINK :a #_link-handler}))
|
||||
|
@ -218,42 +211,42 @@
|
|||
(def theme
|
||||
(merge tailwind-theme
|
||||
{:SRC code-editor
|
||||
:HEADER1 (fn [v _] [:h1.text-2xl.fw6.lh-title.mt-0.mb-2 {:id (slugify v)} [:a {:name (slugify v)} v]])
|
||||
:HEADER2 (fn [v _] [:h2.text-xl.fw6.lh-title.mt-0.mb-2 {:id (slugify v)} [:a {:name (slugify v)} v]])
|
||||
:HEADER3 (fn [v _] [:h2.text-base.lh-title.mt-0.mb-2 {:id (slugify v)} [:a {:name (slugify v)} v]])
|
||||
:HEADER1 header-lvl1 #_(fn [v _] [:h1.text-2xl.fw6.lh-title.mt-0.mb-2 {:id (slugify v)} [:a {:name (slugify v)} v]])
|
||||
:HEADER2 header-lvl2 #_(fn [v _] [:h2.text-xl.fw6.lh-title.mt-0.mb-2 {:id (slugify v)} [:a {:name (slugify v)} v]])
|
||||
:HEADER3 header-lvl3 #_(fn [v _] [:h2.text-base.lh-title.mt-0.mb-2 {:id (slugify v)} [:a {:name (slugify v)} v]])
|
||||
:LINE :p.f5.f5-ns.lh-copy.mt0
|
||||
:BULLETS :ul.mt0
|
||||
:LINK :a #_link-handler}))
|
||||
|
||||
#_(def theme-toc-tachyon
|
||||
(merge tachyon-theme
|
||||
{:HEADER1 (fn [v _] [:li [:a {:href (str "#" (slugify v))}
|
||||
[:span.f4.fw6.f3-ns.lh-title.mt0.mb2 v]]])
|
||||
:HEADER2 (fn [v _] [:li.ml2 [:a {:href (str "#" (slugify v))}
|
||||
[:span.f4.fw6.f4-ns.lh-title.mt0.mb2 v]]])
|
||||
:HEADER3 (fn [v _] [:li.ml4 [:a {:href (str "#" (slugify v))}
|
||||
[:span.f5.fw6.f5-ns.lh-title.mt0.mb2 v]]])
|
||||
:HEADER4 (fn [v _] [:li.ml6 [:a {:href (str "#" (slugify v))}
|
||||
[:span.f6.fw6.f5-ns.lh-title.mt0.mb2 v]]])
|
||||
:HEADER5 (fn [v _] [:li.ml8 [:a {:href (str "#" (slugify v))}
|
||||
[:span.f6.fw6.f5-ns.lh-title.mt0.mb2 v]]])
|
||||
:HEADER6 (fn [v _] [:li.ml10 [:a {:href (str "#" (slugify v))}
|
||||
[:span.f6.fw6.f5-ns.lh-title.mt0.mb2 v]]])}))
|
||||
(merge tachyon-theme
|
||||
{:HEADER1 (fn [v _] [:li [:a {:href (str "#" (slugify v))}
|
||||
[:span.f4.fw6.f3-ns.lh-title.mt0.mb2 v]]])
|
||||
:HEADER2 (fn [v _] [:li.ml2 [:a {:href (str "#" (slugify v))}
|
||||
[:span.f4.fw6.f4-ns.lh-title.mt0.mb2 v]]])
|
||||
:HEADER3 (fn [v _] [:li.ml4 [:a {:href (str "#" (slugify v))}
|
||||
[:span.f5.fw6.f5-ns.lh-title.mt0.mb2 v]]])
|
||||
:HEADER4 (fn [v _] [:li.ml6 [:a {:href (str "#" (slugify v))}
|
||||
[:span.f6.fw6.f5-ns.lh-title.mt0.mb2 v]]])
|
||||
:HEADER5 (fn [v _] [:li.ml8 [:a {:href (str "#" (slugify v))}
|
||||
[:span.f6.fw6.f5-ns.lh-title.mt0.mb2 v]]])
|
||||
:HEADER6 (fn [v _] [:li.ml10 [:a {:href (str "#" (slugify v))}
|
||||
[:span.f6.fw6.f5-ns.lh-title.mt0.mb2 v]]])}))
|
||||
|
||||
(def theme-toc
|
||||
(merge tailwind-theme
|
||||
{:HEADER1 (fn [v _] [:li.list-decimal [:a.text-blue-800 {:class "hover:text-blue-500" :href (str "#" (slugify v))}
|
||||
[:span.text-xl.fw6.lh-title.mt0.mb2 v]]])
|
||||
[:span.text-xl.fw6.lh-title.mt0.mb2 v]]])
|
||||
:HEADER2 (fn [v _] [:li.list-decimal.ml-4 [:a.text-blue-800 {:href (str "#" (slugify v))}
|
||||
[:span.text-lg.fw6.lh-title.mt0.mb2 v]]])
|
||||
[:span.text-lg.fw6.lh-title.mt0.mb2 v]]])
|
||||
:HEADER3 (fn [v _] [:li.list-decimal.ml-8 [:a.text-blue-800 {:class "hover:text-blue-500" :href (str "#" (slugify v))}
|
||||
[:span.text-base.fw6.lh-title.mt0.mb2 v]]])
|
||||
[:span.text-base.fw6.lh-title.mt0.mb2 v]]])
|
||||
:HEADER4 (fn [v _] [:li.list-decimal.ml-12 [:a.text-blue-800 {:href (str "#" (slugify v))}
|
||||
[:span.text-sm.fw6.lh-title.mt0.mb2 v]]])
|
||||
[:span.text-sm.fw6.lh-title.mt0.mb2 v]]])
|
||||
:HEADER5 (fn [v _] [:li.list-decimal.ml-26 [:a.text-blue-800 {:href (str "#" (slugify v))}
|
||||
[:span.text-xs.fw6.f5-ns.lh-title.mt0.mb2 v]]])
|
||||
[:span.text-xs.fw6.f5-ns.lh-title.mt0.mb2 v]]])
|
||||
:HEADER6 (fn [v _] [:li.list-decimal.ml-30 [:a.hover:decoration-blue-400 {:href (str "#" (slugify v))}
|
||||
[:span.text-xs.fw6.f5-ns.lh-title.mt0.mb2 v]]])}))
|
||||
[:span.text-xs.fw6.f5-ns.lh-title.mt0.mb2 v]]])}))
|
||||
|
||||
;; put constant data here
|
||||
(def site-data
|
||||
|
@ -318,8 +311,7 @@
|
|||
:icon-image "https://avatars.githubusercontent.com/u/2181346?s=200&v=4"}]}
|
||||
:terminology {:title "Terminology"
|
||||
:intro ""
|
||||
:key ::terminology}
|
||||
}
|
||||
:key ::terminology}}
|
||||
:demos
|
||||
{:hiccup-dsl-demo
|
||||
{:file "documents/hiccup-dsl-demo.org" :git-link "https://github.com/atomjuice/dsl-demo"}
|
||||
|
@ -340,9 +332,6 @@
|
|||
:containers
|
||||
{:file "documents/containers.org" :git-link "https://github.com/atomjuice/containers"}}})
|
||||
|
||||
;; Store site state
|
||||
(defonce site-state (reagent/atom {}))
|
||||
|
||||
;; form one component to render an article
|
||||
(defn article [{:keys [title description tagline]}]
|
||||
[:article.prose {:data-name "article-full-bleed-background"}
|
||||
|
@ -420,7 +409,6 @@
|
|||
:code (filter (fn filter-code [tag] (org-code (first tag))) dsl)
|
||||
:body (filter (fn filter-body [tag] (body (first tag))) dsl)})
|
||||
|
||||
|
||||
(defn home-page []
|
||||
[:<>
|
||||
[articles
|
||||
|
@ -438,19 +426,39 @@
|
|||
|
||||
(defn grouped-page [route]
|
||||
(let [group (keyword (name (:name (:data route))))]
|
||||
[:<>
|
||||
[articles
|
||||
{:title (-> site-data :pages group :title)
|
||||
:body (-> site-data :pages group :intro)
|
||||
:articles
|
||||
(mapv (fn fmt-map [demo]
|
||||
{:title (:title demo)
|
||||
:description (:description demo)
|
||||
:link (rfe/href ::page {:page (:page demo)})
|
||||
:img-src (:icon-image demo)})
|
||||
(-> site-data :pages group :demos))}]]))
|
||||
(swap! site-state dissoc :notification)
|
||||
(fn [route]
|
||||
[:<>
|
||||
[articles
|
||||
{:title (-> site-data :pages group :title)
|
||||
:body (-> site-data :pages group :intro)
|
||||
:articles
|
||||
(mapv (fn fmt-map [demo]
|
||||
{:title (:title demo)
|
||||
:description (:description demo)
|
||||
:link (rfe/href ::page {:page (:page demo)})
|
||||
:img-src (:icon-image demo)})
|
||||
(-> site-data :pages group :demos))}]])))
|
||||
|
||||
(defn default-page [route]
|
||||
(let [demo-key (keyword (-> route :parameters :path :page))
|
||||
content (reagent/atom {})]
|
||||
(GET (str "/" (-> site-data :demos demo-key :file))
|
||||
{:response-format (raw-response-format)
|
||||
:handler (fn [response]
|
||||
(->> response
|
||||
parse
|
||||
org->split2
|
||||
(reset! content)))})
|
||||
(fn [route]
|
||||
(if @content
|
||||
[:main
|
||||
[:h1.mt-8.mb-8.text-4xl (:content (last (first (:header @content))))]
|
||||
[:div
|
||||
(into [:div] (org->replacements theme (:body @content)))]]
|
||||
[:<>]))))
|
||||
|
||||
(defn default-page-header [route]
|
||||
(let [demo-key (keyword (-> route :parameters :path :page))
|
||||
content (reagent/atom {})]
|
||||
(GET (str "/" (-> site-data :demos demo-key :file))
|
||||
|
@ -483,11 +491,10 @@
|
|||
(into [:div] (org->replacements theme (:body @content)))]]
|
||||
[:<>]))))
|
||||
|
||||
|
||||
|
||||
;; form one render about page component
|
||||
(defn about-page []
|
||||
[:div
|
||||
[default-page {:parameters {:path {:page "about"}}}]
|
||||
#_[:div
|
||||
[:section.mw7.center.avenir
|
||||
[:h1 "Clojure library examples to aid learning"]
|
||||
[:p ""]
|
||||
|
@ -504,9 +511,9 @@
|
|||
|
||||
["/page/:page"
|
||||
{:name ::page
|
||||
:view default-page
|
||||
:parameters {:path {:page string?}
|
||||
:query {(ds/opt :foo) keyword?}}}]
|
||||
:view default-page-header
|
||||
:parameters {:path {:page string?}
|
||||
:query {(ds/opt :foo) keyword?}}}]
|
||||
|
||||
["/terminology/"
|
||||
{:name ::terminology
|
||||
|
@ -530,21 +537,15 @@
|
|||
|
||||
["/about/"
|
||||
{:name ::about
|
||||
:view about-page}]
|
||||
|
||||
#_["/demo/:page"
|
||||
{:name ::demo
|
||||
:view demo-page
|
||||
:parameters {:path {:page string?}
|
||||
:query {(ds/opt :foo) keyword?}}}]])
|
||||
:view about-page}]])
|
||||
|
||||
;; top level component contains nav and adds in the select page into a containing element
|
||||
;; we are adding in a style sheet but this will often be done in index.html
|
||||
(defn current-page []
|
||||
[:div
|
||||
[notification]
|
||||
[navbar (concat
|
||||
[{:href (rfe/href ::frontpage) :title "title here" :text "home" :key "homepage"}]
|
||||
|
||||
(mapv (fn build-nav [[key page]] {:href (rfe/href (:key page)) :text (:title page)}) (-> site-data :pages))
|
||||
[;;{:href (rfe/href ::dsl) :text "DSL's" :key "dsl"}
|
||||
{:title "Domain Specific Languages" :href (rfe/href ::about) :text "About" :key "about"}
|
||||
|
|
|
@ -0,0 +1,36 @@
|
|||
(ns clojure-demo.helpers
|
||||
(:require
|
||||
[cljs.core.async :refer [go]]
|
||||
[cljs.core.async.interop :refer [<p!]]
|
||||
[clojure.string :as str]
|
||||
[clojure-demo.state :refer [site-state]]))
|
||||
|
||||
(defn slugify [s]
|
||||
(when s
|
||||
(str
|
||||
(-> s
|
||||
(str/lower-case)
|
||||
(str/replace #"[^\w]+" "-")
|
||||
(str/replace #"^-\\|-\\-$" "")))))
|
||||
|
||||
(defn build-page-path [title]
|
||||
(str "http://127.0.0.1:8080/" #_"https://clojure-demos.digitaloctave.com/" "page/"
|
||||
(when (-> @site-state :current-route :parameters :path :page)
|
||||
(-> @site-state :current-route :parameters :path :page))
|
||||
"#" title)
|
||||
)
|
||||
|
||||
|
||||
(defn copy->clipboard
|
||||
"Simple wrapper which copies text to the clipboard and resolves the promise"
|
||||
[text]
|
||||
(go (<p! (.writeText (.-clipboard js/navigator) (build-page-path text)))
|
||||
(swap! site-state assoc :notification "Copied to clipboard")
|
||||
(prn "copied")))
|
||||
|
||||
|
||||
|
||||
|
||||
(comment
|
||||
(.-writeText (.-clipboard js/navigator) "test")
|
||||
(copy->clipboard "test2"))
|
|
@ -0,0 +1,5 @@
|
|||
(ns clojure-demo.state
|
||||
(:require [reagent.core :as reagent]))
|
||||
|
||||
;; Store site state
|
||||
(defonce site-state (reagent/atom {}))
|
Loading…
Reference in New Issue