From 9d48364cee205a4860fd45c91656a66042085483 Mon Sep 17 00:00:00 2001 From: Oly Date: Thu, 10 Aug 2023 16:58:58 +0100 Subject: [PATCH] Sitemap support --- deps.edn | 15 +++++++------- src/clojure_demo/core.cljs | 37 +++++++++++++++++++++++++++++++---- src/clojure_demo/helpers.cljs | 20 ++++++++++++++----- src/clojure_demo/sitemap.cljc | 29 +++++++++++++++++++++++++++ 4 files changed, 85 insertions(+), 16 deletions(-) create mode 100644 src/clojure_demo/sitemap.cljc diff --git a/deps.edn b/deps.edn index 0a6ef88..858ebca 100644 --- a/deps.edn +++ b/deps.edn @@ -19,22 +19,23 @@ metosin/reitit-spec {:mvn/version "0.5.10"} metosin/reitit-frontend {:mvn/version "0.5.10"} + thheller/shadow-cljs {:mvn/version "2.23.3"} + ;; interactive code snippets ;;viebel/klipse {:mvn/version "7.10.4"} com.github.seancorfield/honeysql {:mvn/version "2.4.1026"} - + ;binaryage/devtools {:mvn/version "1.0.7"} hiccup/hiccup {:mvn/version "1.0.5"} viebel/klipse {:mvn/version "7.11.4"} org.babashka/sci {:mvn/version "0.7.39"} org.babashka/sci.configs {:git/url "https://github.com/babashka/sci.configs" :sha "33bd51e53700b224b4cb5bda59eb21b62f962745"} - datascript/datascript {:mvn/version "1.5.1"} - - - com.bhauman/figwheel-main {:mvn/version "0.2.18"}} + datascript/datascript {:mvn/version "1.5.1"}} :paths ["src" "resources"] :aliases {:prod {:main-opts ["-m" "figwheel.main" "-bo" "dev"]} - :build-dev {:extra-deps {thheller/shadow-cljs {:mvn/version "2.23.3"}} + :build-dev {:extra-deps {thheller/shadow-cljs {:mvn/version "2.23.3"} + #_#_binaryage/devtools {:mvn/version "1.0.7"}}} :main-opts ["-m" "shadow.cljs.devtools.cli"]} :dev {:extra-deps {thheller/shadow-cljs {:mvn/version "2.23.3"} - no.cjohansen/portfolio {:mvn/version "2023.07.15"}}}}} + ;binaryage/devtools {:mvn/version "1.0.7"} + no.cjohansen/portfolio {:mvn/version "2023.07.15"}}}} diff --git a/src/clojure_demo/core.cljs b/src/clojure_demo/core.cljs index 2dfde1d..8229118 100644 --- a/src/clojure_demo/core.cljs +++ b/src/clojure_demo/core.cljs @@ -31,7 +31,8 @@ [sci.configs.tonsky.datascript :as sci-datascript] [sci.core :as sci] [spec-tools.data-spec :as ds] - [tick.core :as t])) + [tick.core :as t]) + (:require-macros [clojure-demo.sitemap :refer [spit-pwa-sitemap]])) (def languages {"clojure" {:mode "clojure"} @@ -330,7 +331,21 @@ :example-xml-sitemap {:file "documents/examples-xml-sitemap.org" :git-link "https://github.com/atomjuice/dsl-demo"} :containers - {:file "documents/containers.org" :git-link "https://github.com/atomjuice/containers"}}}) + {:file "documents/containers.org" :git-link "https://github.com/atomjuice/containers"} + :about + {:file "documents/about.org" :git-link "https://github.com/atomjuice/containers"}}}) + + +(defn get-pages + "Get pages from site-data map" + [] + (->> site-data + :pages + (map second) + (map :demos) + (map (fn cat [c] (map (fn build-url [page] (str "page/" (:page page))) c))) + flatten)) + ;; form one component to render an article (defn article [{:keys [title description tagline]}] @@ -506,11 +521,11 @@ (def routes [["/" {:name ::frontpage - :my-data "hi" :view home-page}] - ["/page/:page" + ["/page/{page}" {:name ::page + :sitemap {:vec get-pages} :view default-page-header :parameters {:path {:page string?} :query {(ds/opt :foo) keyword?}}}] @@ -590,6 +605,20 @@ ;; we defonce the startup so that hot reloading does not reinitialize the state of the site (def launch (do (startup!) true)) +(defn build-sitemap-urls [] + (->> routes + (reduce (fn handle-sitemap [result [route route-map]] + (if (-> route-map :sitemap :vec) + (conj result ((-> route-map :sitemap :vec))) + (conj result route) + )) []) + flatten)) + +(spit-pwa-sitemap + "resources/public/sitemap.xml" + "https://clojure-demos.digitaloctave.com/" + (build-sitemap-urls)) + (comment @site-state (org->replacements tachyon-theme [[:SRC {:LANGUAGE "shell"} "hi"]]) diff --git a/src/clojure_demo/helpers.cljs b/src/clojure_demo/helpers.cljs index e239f2d..d603939 100644 --- a/src/clojure_demo/helpers.cljs +++ b/src/clojure_demo/helpers.cljs @@ -2,8 +2,8 @@ (:require [cljs.core.async :refer [go]] [cljs.core.async.interop :refer [ @site-state :current-route :parameters :path :page) (-> @site-state :current-route :parameters :path :page)) - "#" title) - ) + "#" title)) (defn copy->clipboard @@ -28,9 +27,20 @@ (swap! site-state assoc :notification "Copied to clipboard") (prn "copied"))) - +(defn map-replace + "Given a string with {:key} strings substitute the matching key in a hash map" + [text m] + (reduce + (fn [acc [k v]] (str/replace acc (str "{" k "}") (str v))) + text m)) (comment + (map-replace "/page/{page}" "page") + (re-seq #"\{(.*?)\}" "/page/{page}/{id}" ) + (->> (re-seq #"\{(.*?)\}" "/page/{page}/{id}" ) + (map second)) + ;(re-seq #"{(.*?)}" "/page/{page}" ) + (re-seq #"\[(.*?)\]" "/page/[page]" ) (.-writeText (.-clipboard js/navigator) "test") (copy->clipboard "test2")) diff --git a/src/clojure_demo/sitemap.cljc b/src/clojure_demo/sitemap.cljc new file mode 100644 index 0000000..c8a8b0d --- /dev/null +++ b/src/clojure_demo/sitemap.cljc @@ -0,0 +1,29 @@ +(ns clojure-demo.sitemap + (:require [clojure.data.xml :as xml])) + +(defn pwa-sitemap [domain routes] + #?(:cljs (xml/emit-str + {:tag :urlset + :attrs {#_#_:xmlns "http://www.sitemaps.org/schemas/sitemap/0.9"} + :content + (mapv (fn [r] + {:tag :url + :attrs {} + :content [{:tag :loc :attrs {} :content [(str domain r)]}]} + ) routes)}) + :clj (xml/indent-str + {:tag :urlset + :attrs {:xmlns "http://www.sitemaps.org/schemas/sitemap/0.9"} + :content + (mapv (fn [r] + {:tag :url + :attrs {} + :content [{:tag :loc :attrs {} :content [(str domain r)]}]} + ) routes)}))) + +(defmacro spit-pwa-sitemap + "Generate the sitemap and outut to the provided path" + {:arglists '([body] [options & body]), :style/indent 0} + [path domain urls] + #?(:clj (spit path (pwa-sitemap domain urls)) + :cljs nil))