Add example of rendering google maps.
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
This commit is contained in:
parent
da51aadd6a
commit
608ea2f9e8
|
@ -1,4 +1,4 @@
|
|||
((clojurescript-mode .
|
||||
((clojurescript-mode .
|
||||
(cider-clojure-cli-aliases . "-M:dev")
|
||||
(cider-preferred-build-tool . clojure-cli)
|
||||
(cider-default-cljs-repl . custom)
|
||||
|
|
2
deps.edn
2
deps.edn
|
@ -1,5 +1,7 @@
|
|||
{:deps {org.clojure/clojure {:mvn/version "1.10.0"}
|
||||
org.clojure/clojurescript {:mvn/version "1.11.60"}
|
||||
org.clojure/core.async {:mvn/version "1.6.673"}
|
||||
funcool/promesa {:mvn/version "9.0.494"}
|
||||
|
||||
;;ajax requests
|
||||
cljs-ajax/cljs-ajax {:mvn/version "0.8.1"}
|
||||
|
|
|
@ -19,20 +19,10 @@ The code below can be evaluated live inside the page you can select parts of the
|
|||
#+END_SRC
|
||||
|
||||
|
||||
#+BEGIN_SRC text :export none :results silent :tangle readme.org
|
||||
#+BEGIN_SRC text :export none :results silent :tangle readme.org
|
||||
#+TITLE: Getting started
|
||||
#+END_SRC
|
||||
|
||||
|
||||
* Install the npm requirements.
|
||||
|
||||
npx install
|
||||
|
||||
* Launch shadow-cljs watch for source code changes
|
||||
npx shadow-cljs watch app
|
||||
#+END_SRC
|
||||
|
||||
|
||||
** Clojure comments
|
||||
|
||||
There a few ways to comment code in this language.
|
||||
|
|
|
@ -0,0 +1,211 @@
|
|||
#+TITLE: Embedding maps in your apps
|
||||
#+DESCRIPTION: Example's of embeding maps into your frontend application.
|
||||
|
||||
* Introduction
|
||||
|
||||
Install npm dependencies
|
||||
|
||||
npm install
|
||||
|
||||
Run the project
|
||||
npx shadow-cljs server app
|
||||
|
||||
|
||||
* Google Maps
|
||||
|
||||
Below is an example of using google maps, it pulls in the library directly you could alternatively use an npm dependency.
|
||||
|
||||
You will need to provide your own api key, the examples are blank and render a warning so paste in your google api key to make this work.
|
||||
|
||||
|
||||
#+BEGIN_SRC html :results silent :exports none :tangle resources/public/index.html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>Clojure demos</title>
|
||||
<script src="https://cdn.tailwindcss.com"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div id="app">
|
||||
App loading here
|
||||
</div>
|
||||
<script src="/cljs-out/main_bundle.js" type="application/javascript"></script>
|
||||
</body>
|
||||
</html>
|
||||
#+END_SRC
|
||||
|
||||
#+BEGIN_SRC edn :results silent :exports none :tangle deps.edn
|
||||
{:paths ["src" "resources"]
|
||||
:deps
|
||||
{org.clojure/clojure {:mvn/version "1.10.0"}
|
||||
org.clojure/clojurescript {:mvn/version "1.11.60"}
|
||||
funcool/promesa {:mvn/version "11.0.671"}
|
||||
reagent/reagent {:mvn/version "1.2.0"}
|
||||
thheller/shadow-cljs {:mvn/version "2.24.0"}}}
|
||||
#+END_SRC
|
||||
|
||||
#+BEGIN_SRC edn :results silent :exports none :tangle shadow-cljs.edn
|
||||
{:deps {:aliases [:dev]}
|
||||
:dev-http {8080 ["resources/public/" "classpath:public"]}
|
||||
:source ["src" "../../components"]
|
||||
:builds {:app {:output-dir "resources/public/cljs-out/"
|
||||
:asset-path "/cljs-out"
|
||||
:target :browser
|
||||
:compiler-options {:infer-externs :auto
|
||||
:externs ["datascript/externs.js"]
|
||||
:output-feature-set :es6}
|
||||
:modules {:main_bundle {:init-fn clojure-demo.core/startup!}}
|
||||
:devtools {:after-load app.main/reload!}}}}
|
||||
#+END_SRC
|
||||
|
||||
#+BEGIN_SRC json :results silent :exports none :tangle package.json
|
||||
{
|
||||
"dependencies": {
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"shadow-cljs": "^2.23.3",
|
||||
"webpack": "^5.74.0",
|
||||
"webpack-cli": "^4.10.0"
|
||||
}
|
||||
}
|
||||
#+END_SRC
|
||||
|
||||
#+BEGIN_SRC clojurescript :exports none :tangle src/clojure_demo/core.cljs
|
||||
(ns clojure-demo.core
|
||||
(:require
|
||||
["react-dom/client" :refer [createRoot]]
|
||||
[cljs.core.async :as async]
|
||||
[cljs.core.async.interop :as async-in]
|
||||
[promesa.core :as promesa]
|
||||
[shadow.cljs.modern :refer [js-await] :as shadow]
|
||||
[reagent.core :as reagent]))
|
||||
#+END_SRC
|
||||
|
||||
|
||||
** Load in the google maps script by adding it to the dom
|
||||
#+BEGIN_SRC clojurescript :results output :tangle src/clojure_demo/core.cljs
|
||||
(defn load-google-maps-script [api-key]
|
||||
(let [script (.createElement js/document "script")]
|
||||
;; copied from googles recommended way of loading google maps
|
||||
(set! (.-innerHTML script) (str "(g=>{var h,a,k,p=\"The Google Maps JavaScript API\",c=\"google\",l=\"importLibrary\",q=\"__ib__\",m=document,b=window;b=b[c]||(b[c]={});var d=b.maps||(b.maps={}),r=new Set,e=new URLSearchParams,u=()=>h||(h=new Promise(async(f,n)=>{await (a=m.createElement(\"script\"));e.set(\"libraries\",[...r]+\"\");for(k in g)e.set(k.replace(/[A-Z]/g,t=>\"_\"+t[0].toLowerCase()),g[k]);e.set(\"callback\",c+\".maps.\"+q);a.src=`https://maps.${c}apis.com/maps/api/js?`+e;d[q]=f;a.onerror=()=>h=n(Error(p+\" could not load.\"));a.nonce=m.querySelector(\"script[nonce]\")?.nonce||\"\";m.head.append(a)}));d[l]?console.warn(p+\" only loads once. Ignoring:\",g):d[l]=(f,...n)=>r.add(f)&&u().then(()=>d[l](f,...n))})({
|
||||
key: \"" api-key "\", v: \"weekly\"});"))
|
||||
(.appendChild (.-head js/document) script)))
|
||||
#+END_SRC
|
||||
|
||||
** Create a map using google and core async
|
||||
|
||||
In this example we render google maps using core async, async go blocks drop type hints so we need to pull out any hinting to functions, this is a shame as this version reduces the amount of nesting.
|
||||
|
||||
#+BEGIN_SRC clojurescript :results output :tangle src/clojure_demo/core.cljs
|
||||
(defn google-map-core-async []
|
||||
(let [map-element (reagent/atom nil)
|
||||
;; pulled out of the go block to satisfy the infer warnings, the go block removes hints
|
||||
get-map-obj (fn [obj] (.-Map ^js/google.maps.Map obj))
|
||||
get-marker-obj (fn [obj] (.-Marker ^js/google.maps.Map obj))]
|
||||
(load-google-maps-script "")
|
||||
|
||||
;; go blocks loose hints so may cause infer warnings
|
||||
(async/go (let [gMap (get-map-obj (async-in/<p! (js/google.maps.importLibrary "maps")))
|
||||
gMarker (get-marker-obj (async-in/<p! (js/google.maps.importLibrary "marker")))
|
||||
map (gMap. @map-element
|
||||
(clj->js {:center {:lng 131.031 :lat -25.344} :zoom 4}))]
|
||||
(gMarker. (clj->js {:map map
|
||||
:title "test marker 1"
|
||||
:position {:lng 131.031 :lat -24.344}}) "marker 1")
|
||||
(gMarker. (clj->js {:map map
|
||||
:title "test marker 2"
|
||||
:position {:lng 131.031 :lat -25.344}}) "marker 2")))
|
||||
(fn []
|
||||
[:div#google-map-async.m-4
|
||||
{:style {:width "400px" :height "400px"} :ref #(reset! map-element %)}
|
||||
"core async map here"])))
|
||||
#+END_SRC
|
||||
|
||||
|
||||
|
||||
** Create a map using google and shadow js-await
|
||||
|
||||
#+BEGIN_SRC clojurescript :results output :tangle src/clojure_demo/core.cljs
|
||||
(defn google-map-js-await []
|
||||
(let [map-element (reagent/atom nil)]
|
||||
(load-google-maps-script "")
|
||||
(shadow/js-await
|
||||
[js-map (js/google.maps.importLibrary "maps")]
|
||||
(shadow/js-await
|
||||
[js-marker (js/google.maps.importLibrary "marker")]
|
||||
(when @map-element
|
||||
(let [gMap (.-Map ^js/google.maps.Map js-map)
|
||||
gMarker (.-Marker ^js/google.maps.Marker js-marker)
|
||||
map (gMap. @map-element
|
||||
(clj->js {:center {:lng 131.031 :lat -25.344} :zoom 4}))]
|
||||
(gMarker. (clj->js {:map map
|
||||
:title "test marker 1"
|
||||
:position {:lng 131.031 :lat -24.344}}) "marker 1")
|
||||
(gMarker. (clj->js {:map map
|
||||
:title "test marker 2"
|
||||
:position {:lng 131.031 :lat -25.344}}) "marker 2")
|
||||
nil))))
|
||||
|
||||
(fn []
|
||||
[:div#google-map-js-await.m-4
|
||||
{:style {:width "400px" :height "400px"} :ref #(reset! map-element %)}
|
||||
"shadow js-await map here"])))
|
||||
|
||||
[google-map-js-await]
|
||||
#+END_SRC
|
||||
|
||||
** Create a map using google and promesa
|
||||
|
||||
An example using promesa to render a google map.
|
||||
|
||||
#+BEGIN_SRC clojurescript :results output :tangle src/clojure_demo/core.cljs
|
||||
(defn google-map-promesa []
|
||||
(let [map-element (reagent/atom nil)]
|
||||
(load-google-maps-script "")
|
||||
|
||||
(promesa/let
|
||||
[js-map (js/google.maps.importLibrary "maps")
|
||||
js-marker (js/google.maps.importLibrary "marker")]
|
||||
|
||||
(let
|
||||
[gMap (.-Map ^js/google.maps.Map js-map)
|
||||
gMarker (.-Marker ^js/google.maps.Marker js-marker)
|
||||
map (gMap. @map-element
|
||||
(clj->js {:center {:lng 131.031 :lat -25.344} :zoom 4}))]
|
||||
(gMarker. (clj->js {:map map
|
||||
:title "test"
|
||||
:position {:lng 131.031 :lat -24.344}}) "marker 1")
|
||||
|
||||
(gMarker. (clj->js {:map map
|
||||
:title "test"
|
||||
:position {:lng 131.031 :lat -25.344}}) "marker 1")))
|
||||
|
||||
|
||||
(fn []
|
||||
[:div#google-map-promesa.m-4
|
||||
{:style {:width "400px" :height "400px"} :ref #(reset! map-element %)}
|
||||
"promesa map here"])))
|
||||
|
||||
[google-map-promesa]
|
||||
#+END_SRC
|
||||
|
||||
|
||||
#+BEGIN_SRC clojure :exports none :tangle src/clojure_demo/core.cljs
|
||||
(defn current-page []
|
||||
[:div
|
||||
[google-map-core-async]
|
||||
[google-map-promesa]
|
||||
[google-map-js-await]])
|
||||
|
||||
(defn mount-root-page []
|
||||
;; this select the main node from the html file and injects your page content
|
||||
(.render
|
||||
(createRoot (.getElementById js/document "app"))
|
||||
(reagent/as-element [current-page])))
|
||||
|
||||
(def startup! (mount-root-page))
|
||||
|
||||
#+END_SRC
|
|
@ -12,6 +12,13 @@
|
|||
name="description"
|
||||
content="Examples & Guides on using various libraries and technologies with in the clojure eco system's"
|
||||
/>
|
||||
<link rel="canonical" href="https://clojure-demos.digitaloctave.com/" />
|
||||
<meta property="og:type" content="article" />
|
||||
<meta property="og:title" content="TITLE OF YOUR POST OR PAGE" />
|
||||
<meta property="og:description" content="DESCRIPTION OF PAGE CONTENT" />
|
||||
<meta property="og:image" content="LINK TO THE IMAGE FILE" />
|
||||
<meta property="og:url" content="PERMALINK" />
|
||||
<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
|
||||
|
|
|
@ -8,6 +8,9 @@
|
|||
["@nextjournal/lang-clojure" :refer [clojure]]
|
||||
["react-dom/client" :refer [createRoot]]
|
||||
["tarts" :as tarts]
|
||||
[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]]
|
||||
|
@ -22,6 +25,7 @@
|
|||
[reitit.frontend.history :refer [ignore-anchor-click?]]
|
||||
[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]))
|
||||
|
@ -35,18 +39,45 @@
|
|||
|
||||
(def yaml-mode (LanguageSupport. (.define StreamLanguage yaml)))
|
||||
|
||||
(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)))
|
||||
[(butlast body) last-expr]
|
||||
[body nil])]
|
||||
|
||||
;; FIXME: -> here will always return a promise so shouldn't be necessary to add js hint?
|
||||
`(-> ~thenable
|
||||
~@(when (seq body)
|
||||
[`(.then (fn [~name] ~@body))])
|
||||
~@(when catch
|
||||
(let [[name & body] catch]
|
||||
[`(.catch (fn [~name] ~@body))]
|
||||
)))))
|
||||
|
||||
;; https://github.com/babashka/sci.configs
|
||||
(def rf-ns (sci/create-ns 'reitit.frontend nil))
|
||||
(def rfe-ns (sci/create-ns 'reitit.frontend.easy nil))
|
||||
(def rss-ns (sci/create-ns 'reitit.coercion.spec nil))
|
||||
(def sql-ns (sci/create-ns 'honey.sql.core nil))
|
||||
(def sqlh-ns (sci/create-ns 'honey.sql.helpers nil))
|
||||
(def shadow-ns (sci/create-ns 'shadow.cljs.modern nil))
|
||||
|
||||
;; core async does not work with sci
|
||||
(def async-ns (sci/create-ns 'cljs.core.async nil))
|
||||
(def async-in-ns (sci/create-ns 'cljs.core.async.interop nil))
|
||||
|
||||
(def sci-ctx
|
||||
(sci/init
|
||||
{:classes {'js js/globalThis :allow :all}
|
||||
:namespaces
|
||||
{'reagent sci-reagent/reagent-namespace
|
||||
'promesa sci-promesa/promesa-namespace
|
||||
;'h {'html (sci/copy-var h/html hc-ns)}
|
||||
;'async {'go (sci/copy-var async/go async-ns)}
|
||||
;'shadow {'js-await (sci/copy-var js-await shadow-ns)}
|
||||
'shadow {'js-await (sci/copy-var my-js-await shadow-ns)}
|
||||
;'async-in {'<p! (sci/copy-var async-in/<p! async-in-ns)}
|
||||
'd sci-datascript/core-namespace
|
||||
'sql {'format (sci/copy-var sql/format sql-ns)
|
||||
#_#_'raw (sci/copy-var sql/raw sql-ns)}
|
||||
|
@ -108,7 +139,7 @@
|
|||
;(into [:<>] children)
|
||||
))})))
|
||||
(defn code-editor
|
||||
[{:keys [exports class results]} content]
|
||||
[{:keys [export class results]} content]
|
||||
(let [language class
|
||||
editor (atom nil)
|
||||
evaled-result (reagent/atom nil)
|
||||
|
@ -146,13 +177,13 @@
|
|||
:parent @editor})))))
|
||||
:component-will-unmount (fn [_] (.destroy @view))
|
||||
:reagent-render (fn []
|
||||
(if exports
|
||||
(if export
|
||||
nil
|
||||
[:div.mb2
|
||||
[:div.ba.ma0.f5.b--black-05.pa2.overflow-auto.editor {:ref #(reset! editor %)}]
|
||||
[:div.mb-8
|
||||
[:div.ba.ma-0.f5.b--black-05.pa2.overflow-auto.editor {:ref #(reset! editor %)}]
|
||||
(when @evaled-result
|
||||
[err-boundary
|
||||
[:pre.ba.ma0.f6.code.b--black-05.pa2.pl4.overflow-auto
|
||||
[:pre.border-2.pa-4.pl-6.text-xl
|
||||
{:style {:white-space "pre-line"}}
|
||||
;; See org mode :results key
|
||||
(case results
|
||||
|
@ -165,9 +196,9 @@
|
|||
(def theme-tachyon
|
||||
(merge tachyon-theme
|
||||
{:SRC code-editor
|
||||
:HEADER1 (fn [v _] [:h1.f2.fw6.f3-ns.lh-title.mt0.mb2 {:id (slugify v)} [:a {:name (slugify v)} v]])
|
||||
:HEADER2 (fn [v _] [:h2.f3.fw6.f3-ns.lh-title.mt0.mb2 {:id (slugify v)} [:a {:name (slugify v)} v]])
|
||||
:HEADER3 (fn [v _] [:h2.f4.fw6.f3-ns.lh-title.mt0.mb2 {:id (slugify v)} [:a {:name (slugify v)} v]])
|
||||
: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]])
|
||||
:LINE :p.f5.f5-ns.lh-copy.mt0
|
||||
:BULLETS :ul.mt0
|
||||
:LINK :a #_link-handler}))
|
||||
|
@ -175,14 +206,14 @@
|
|||
(def theme
|
||||
(merge tailwind-theme
|
||||
{:SRC code-editor
|
||||
:HEADER1 (fn [v _] [:h1.text-2xl.fw6.lh-title.mt0.mb2 {:id (slugify v)} [:a {:name (slugify v)} v]])
|
||||
:HEADER2 (fn [v _] [:h2.text-xl.fw6.lh-title.mt0.mb2 {:id (slugify v)} [:a {:name (slugify v)} v]])
|
||||
:HEADER3 (fn [v _] [:h2.text-base.lh-title.mt0.mb2 {:id (slugify v)} [:a {:name (slugify v)} v]])
|
||||
: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]])
|
||||
:LINE :p.f5.f5-ns.lh-copy.mt0
|
||||
:BULLETS :ul.mt0
|
||||
:LINK :a #_link-handler}))
|
||||
|
||||
(def theme-toc-tachyon
|
||||
#_(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]]])
|
||||
|
@ -199,17 +230,17 @@
|
|||
|
||||
(def theme-toc
|
||||
(merge tailwind-theme
|
||||
{:HEADER1 (fn [v _] [:li [:a {:href (str "#" (slugify v))}
|
||||
{: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]]])
|
||||
:HEADER2 (fn [v _] [:li.ml-4 [:a {:href (str "#" (slugify 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]]])
|
||||
:HEADER3 (fn [v _] [:li.ml-8 [:a {:href (str "#" (slugify 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]]])
|
||||
:HEADER4 (fn [v _] [:li.ml-12 [:a {:href (str "#" (slugify 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]]])
|
||||
:HEADER5 (fn [v _] [:li.ml-26 [:a {:href (str "#" (slugify 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]]])
|
||||
:HEADER6 (fn [v _] [:li.ml-30 [:a {:href (str "#" (slugify 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]]])}))
|
||||
|
||||
;; put constant data here
|
||||
|
@ -264,7 +295,11 @@
|
|||
:icon-image "https://avatars.githubusercontent.com/u/2181346?s=200&v=4"}]}
|
||||
:examples {:title "Examples"
|
||||
:intro "Some example applications"
|
||||
:key ::examples}
|
||||
:key ::examples
|
||||
:demos [{:title "Maps"
|
||||
:description ""
|
||||
:page "example-maps"
|
||||
:icon-image "https://avatars.githubusercontent.com/u/2181346?s=200&v=4"}]}
|
||||
:terminology {:title "Terminology"
|
||||
:intro ""
|
||||
:key ::terminology}
|
||||
|
@ -282,6 +317,8 @@
|
|||
{:file "documents/clojure-basics.org" :git-link "https://github.com/atomjuice/dsl-demo"}
|
||||
:ci-demo
|
||||
{:file "documents/ci-demo.org" :git-link "https://github.com/atomjuice/dsl-demo"}
|
||||
:example-maps
|
||||
{:file "documents/examples-maps.org" :git-link "https://github.com/atomjuice/dsl-demo"}
|
||||
:containers
|
||||
{:file "documents/containers.org" :git-link "https://github.com/atomjuice/containers"}}})
|
||||
|
||||
|
@ -290,7 +327,7 @@
|
|||
|
||||
;; form one component to render an article
|
||||
(defn article [{:keys [title description tagline]}]
|
||||
[:article {:data-name "article-full-bleed-background"}
|
||||
[:article.prose {:data-name "article-full-bleed-background"}
|
||||
[:div.cf {:style {:background "url(http://placekitten.com/g/600/300)"
|
||||
:no-repeat "center center fixed" :background-size "cover"}}
|
||||
[:div.fl.pa3.pa4-ns.bg-white.black-70.measure-narrow.f3.times
|
||||
|
@ -303,15 +340,13 @@
|
|||
(defn articles [{:keys [title body articles]}]
|
||||
[:section.mw7.center.avenir
|
||||
[:h2.text-4xl.mt-4.mb-4 title]
|
||||
(when body [:p.mb-8 body])
|
||||
(map (fn [{:keys [title author link description img-src img-alt]}]
|
||||
[:article.bt.bb.b--black-10 {:key title}
|
||||
(map (fn [{:keys [title author link description img-src img-alt] :as article}]
|
||||
[:article.bt.bb.b--black-10.border-b-2 {:key title}
|
||||
[:a {:href link}
|
||||
[:div.flex.flex-column.flex-row-ns.p-4
|
||||
(when img-src
|
||||
[:div.flex-none #_{:class "w-1/3"}
|
||||
[:img.w-48 #_h-24.block {:src img-src :alt img-alt}]])
|
||||
|
||||
[:div.flex-none.w-32
|
||||
(when img-src
|
||||
[:img.w-32 #_h-24.block {:src img-src :alt img-alt}])]
|
||||
[:div.ml-4.flex-grow #_{:class "w-2/3"}
|
||||
[:h1.text-2xl title]
|
||||
[:p description]
|
||||
|
@ -341,39 +376,6 @@
|
|||
{:target "_blank" :href "https://matrix.to/#/@oly:matrix.org"}
|
||||
"Contact me"]]])
|
||||
|
||||
(defn home-page []
|
||||
[:<>
|
||||
[articles
|
||||
{:title "Clojure Demos"
|
||||
:body (-> site-data :homepage :intro)
|
||||
:articles
|
||||
[{:title "Clojure Basics"
|
||||
:description "Getting started with clojure syntax datatype's sequences conditions"
|
||||
:link (rfe/href ::demo {:page "clojure-basics"})
|
||||
:img-src "https://clojure.org/images/clojure-logo-120b.png"}
|
||||
{:title "Reagent Demo"
|
||||
:description "React application using reagent"
|
||||
:link (rfe/href ::demo {:page "reagent-demo"})
|
||||
:img-src "https://raw.githubusercontent.com/reagent-project/reagent/master/logo/logo-text.png"}]}]])
|
||||
|
||||
(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 ::demo {:page (:page demo)})
|
||||
:img-src (:icon-image demo)})
|
||||
(-> site-data :pages group :demos))}]]))
|
||||
|
||||
(defn dialects-page [route]
|
||||
[:<>
|
||||
[grouped-page route #_(keyword (name (:name (:data route))))]])
|
||||
|
||||
(def toc (partial contains? (into #{} (map keyword [:HEADER1 :HEADER2 :HEADER3 :HEADER4 :HEADER5 :HEADER6]))))
|
||||
(def org-code (partial contains? (into #{} (map keyword [:SRC]))))
|
||||
|
||||
|
@ -400,6 +402,71 @@
|
|||
: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
|
||||
{:title "Clojure Demos"
|
||||
:body (-> site-data :homepage :intro)
|
||||
:articles
|
||||
[{:title "Clojure Basics"
|
||||
:description "Getting started with clojure syntax datatype's sequences conditions"
|
||||
:link (rfe/href ::page {:page "clojure-basics"})
|
||||
:img-src "https://clojure.org/images/clojure-logo-120b.png"}
|
||||
{:title "Reagent Demo"
|
||||
:description "React application using reagent"
|
||||
:link (rfe/href ::page {:page "reagent-demo"})
|
||||
:img-src "https://raw.githubusercontent.com/reagent-project/reagent/master/logo/logo-text.png"}]}]])
|
||||
|
||||
(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))}]]))
|
||||
|
||||
(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]
|
||||
;;(prn (org->replacements theme (parse response) ))
|
||||
;;[:LINE "" [:LINK {:href "https://github.com/weavejester/hiccup"} "https://github.com/weavejester/hiccup"]]
|
||||
(->> response
|
||||
parse
|
||||
org->split2
|
||||
(reset! content)))})
|
||||
(fn [route]
|
||||
(if @content
|
||||
[:main
|
||||
[:h1.mt-8.mb-8.text-4xl (:content (last (first (:header @content))))]
|
||||
[:div.mw7.center.avenir
|
||||
(into [:ol.list-inside.m-6.font-semibold] (org->replacements theme-toc (:toc @content)))]
|
||||
[:p "The code in these examples is evaluated when modified, you can highlight a partial expression to evalute the selection, You can also download the code as a tar if you like and use it in your favourite editor."]
|
||||
[:a.bg-sky-500.text-white.m-2.p-2.pl-4.pr-4.inline-block
|
||||
{:download (str (slugify (:content (last (first (:header @content))))) ".tar")
|
||||
:title (:content (last (first (:header @content))))
|
||||
:href (.createObjectURL
|
||||
js/URL
|
||||
(js/Blob. #js [(build-file-tar-hm
|
||||
(build-tarts-map
|
||||
(:code @content)))]
|
||||
{:type "application/tar"}))}
|
||||
"Download Code"]
|
||||
[:div
|
||||
(into [:div] (org->replacements theme (:body @content)))]]
|
||||
[:<>]))))
|
||||
|
||||
|
||||
|
||||
;; form one render about page component
|
||||
(defn about-page []
|
||||
[:div
|
||||
|
@ -417,6 +484,12 @@
|
|||
:my-data "hi"
|
||||
:view home-page}]
|
||||
|
||||
["/page/:page"
|
||||
{:name ::page
|
||||
:view default-page
|
||||
:parameters {:path {:page string?}
|
||||
:query {(ds/opt :foo) keyword?}}}]
|
||||
|
||||
["/terminology/"
|
||||
{:name ::terminology
|
||||
:view grouped-page}]
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
:LANGUAGE :class
|
||||
:SRC :pre.bg-near-black.silver.pa2.hljs.roboto.overflow-auto.klipse
|
||||
:RESULTS :pre.bg-near-black.silver.pa2.hljs.roboto.overflow-auto
|
||||
:EXAMPLE :pre.bg-near-black.silver.pa2.hljs.roboto.overflow-auto
|
||||
:EXAMPLE :pre.text-slate-700.bg-white.rounded-xl
|
||||
:COMMENT nil
|
||||
:CAPTION :span
|
||||
:I :i
|
||||
|
@ -42,8 +42,8 @@
|
|||
;;:LINK link-handler
|
||||
:IMG :img
|
||||
;; probably remove these 2
|
||||
:A :a
|
||||
:P :p
|
||||
:A :a.text-blue-800
|
||||
:P :p.mb-2
|
||||
:BR :br
|
||||
:LINE :p.f5.f4-ns.lh-copy.mt0
|
||||
:BULLETS-ORDERED :ol
|
||||
|
|
Loading…
Reference in New Issue