Add blog project to static files
continuous-integration/drone/push Build is failing
Details
continuous-integration/drone/push Build is failing
Details
This commit is contained in:
parent
c584866355
commit
7088e865a1
27
.drone.yml
27
.drone.yml
|
@ -43,6 +43,33 @@ steps:
|
|||
source: /drone/src/development/resources/public/*
|
||||
strip_components: 5
|
||||
|
||||
- name: build-static-blog
|
||||
pull: always
|
||||
image: clojure:tools-deps
|
||||
volumes:
|
||||
- name: cache
|
||||
path: /drone/cache/
|
||||
commands:
|
||||
- ls -la /drone/cache/.m2
|
||||
- clj -M:blog:shadow-cljs-run release blog
|
||||
#- clj -Sdeps '{:mvn/local-repo "/drone/cache/.m2/repository"}' -Mshadow-cljs-run release app --debug
|
||||
|
||||
- name: deploy-static-blog
|
||||
pull: True
|
||||
image: appleboy/drone-scp
|
||||
depends_on:
|
||||
- build-static-blog
|
||||
settings:
|
||||
host: blog.digitaloctave.com
|
||||
port: 22
|
||||
username:
|
||||
from_secret: ssh_user
|
||||
key:
|
||||
from_secret: ssh_key
|
||||
target: /var/www/new-blog/
|
||||
source: /drone/src/resources/public/*
|
||||
strip_components: 4
|
||||
|
||||
- name: promote-deployed-site
|
||||
pull: True
|
||||
image: appleboy/drone-ssh
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
{:paths ["src" "resources"]
|
||||
:deps {
|
||||
org.clojure/core.async {:mvn/version "1.6.673"}
|
||||
org.clojure/clojurescript {:mvn/version "1.11.60"}
|
||||
|
||||
reagent/reagent {:mvn/version "1.1.1"}
|
||||
tick/tick {:mvn/version "0.5.0"}
|
||||
metosin/reitit {:mvn/version "0.5.18"}
|
||||
|
||||
cljs-ajax/cljs-ajax {:mvn/version "0.8.4"}
|
||||
|
||||
datascript/datascript {:mvn/version "1.4.0"}
|
||||
olymk2/tachyon-reagent {:git/url "https://gitlab.com/olymk2/tachyon-reagent.git"
|
||||
:sha "e422af7b41266f7bc90ab78a24fb93f32be61385"}
|
||||
olymk2/cl-eorg {:git/url "https://gitlab.com/olymk2/cl-org.git"
|
||||
:sha "528e8125afcac5d7664aac80f7fbba12dd0f5d98"}
|
||||
|
||||
}
|
||||
:aliases {:dev {:extra-deps {thheller/shadow-cljs {:mvn/version "2.25.2"}
|
||||
cider/cider-nrepl {:mvn/version "0.50.2"}
|
||||
refactor-nrepl/refactor-nrepl {:mvn/version "3.10.0"}
|
||||
cider/piggieback {:mvn/version "0.5.3"}}}
|
||||
|
||||
:test {:extra-paths ["test"]
|
||||
:extra-deps {}}}}
|
|
@ -0,0 +1,340 @@
|
|||
(ns com.oly.static-sites.do-blog.core
|
||||
(:require [ajax.core :refer [GET text-response-format]]
|
||||
[com.oly.static-sites.do-blog.theme :refer [tachyon-theme]]
|
||||
[cl-eorg.html :refer [org->to-hiccup]]
|
||||
[cl-eorg.parser :as parser]
|
||||
[cljs.reader :as reader]
|
||||
[datascript.core :as d]
|
||||
[clojure.string :as str]
|
||||
[reagent.core :as r]
|
||||
[reagent.dom :as dom]
|
||||
[reitit.frontend :as rf]
|
||||
[reitit.frontend.easy :as rfe]
|
||||
[tachyons.cards :refer [profile-card]]
|
||||
[clojure.core.async :refer [<! >! chan go]]
|
||||
[tick.core :as t]
|
||||
[tick.timezone]
|
||||
[tick.locale-en-us]
|
||||
;; [cljsjs.js-joda-timezone]
|
||||
;; [henryw374.js-joda-locale_en-us]
|
||||
[com.oly.static-sites.do-blog.pages.helpers.database
|
||||
:refer [state document conn schema latest-article search-articles]]
|
||||
[com.oly.static-sites.do-blog.pages.home :refer [home-page]]
|
||||
[com.oly.static-sites.do-blog.pages.article :refer [article-page]]
|
||||
[com.oly.static-sites.do-blog.pages.archive :refer [archive-page]]
|
||||
[com.oly.static-sites.do-blog.pages.about :refer [about-page]])
|
||||
(:require-macros [cl-eorg.macros :refer [org-doc->move-process inline-filelist-map]]))
|
||||
|
||||
|
||||
;(set! js/JSJoda (.use js/JSJoda js/JSJodaLocale))
|
||||
|
||||
(inline-filelist-map "bases/do-blog/resources/documents/")
|
||||
|
||||
(org-doc->move-process
|
||||
"bases/do-blog/resources/documents/"
|
||||
"bases/do-blog/resources/public/documents/")
|
||||
|
||||
(d/listen!
|
||||
conn
|
||||
(fn [tx-report]
|
||||
;; Only update if data was modified
|
||||
(when (:tx-data tx-report)
|
||||
(swap! state update :new-data inc))))
|
||||
|
||||
(defn convert-date [text]
|
||||
(when text
|
||||
(let [parts (-> text
|
||||
clojure.string/trim
|
||||
(clojure.string/split #" "))]
|
||||
(-> (t/date (first parts))))))
|
||||
|
||||
|
||||
(defn href
|
||||
"Build up path to document"
|
||||
[doc]
|
||||
(str (rfe/href :posts {:path ""}) (:relative-path doc)))
|
||||
|
||||
(defn fetch-document-cb [doc callback]
|
||||
(GET (str "/documents/" doc)
|
||||
{:response-format (text-response-format)
|
||||
:handler callback}))
|
||||
|
||||
(defn org-dsl-render
|
||||
"Render and store parsed documents"
|
||||
[doc]
|
||||
(swap! state assoc-in [:document :body] (parser/parse doc))
|
||||
(swap! state assoc-in [:document :hiccup] (into [:div] (vec (rest (org->to-hiccup tachyon-theme (-> @state :document :body))))))
|
||||
(swap! state assoc-in [:document :details] (parser/filter-root-nodes [] (-> @state :document :body))))
|
||||
|
||||
(defn render-doc-from-path [path]
|
||||
(if path
|
||||
(let [comm (r/atom (chan))]
|
||||
(fetch-document-cb path #(go (>! @comm %)))
|
||||
(go (reset! document (<! @comm))
|
||||
(swap! state assoc :search {:terms nil :results []})
|
||||
(org-dsl-render @document)))
|
||||
(prn (str "render from path nothing found ") path)))
|
||||
|
||||
|
||||
(def router
|
||||
(rf/router
|
||||
[["/"
|
||||
{:name :homepage
|
||||
:init 'switch-to-latest
|
||||
:view #'home-page}]
|
||||
["/archive/{*tag}"
|
||||
{:name :archive
|
||||
:view #'archive-page}]
|
||||
["/tags/{*path}"
|
||||
{:name :tags
|
||||
:view 'post
|
||||
:parameters {:path string?}}]
|
||||
["/about"
|
||||
{:name :about
|
||||
:view #'about-page}]
|
||||
["/book/{*path}"
|
||||
{:name :book
|
||||
:view 'book
|
||||
:parameters {:path string?}}]
|
||||
["/posts/{*path}"
|
||||
{:name :posts
|
||||
:view #'article-page
|
||||
:state render-doc-from-path
|
||||
:parameters {:path string?}}]]))
|
||||
|
||||
(defn switch-to-latest
|
||||
[path-params]
|
||||
(-> (latest-article)
|
||||
(render-doc-from-path)))
|
||||
|
||||
(defn select-initial-page
|
||||
[path-params]
|
||||
(if path-params
|
||||
(render-doc-from-path path-params)
|
||||
(-> (latest-article)
|
||||
(render-doc-from-path))))
|
||||
|
||||
(defn ui-search [search]
|
||||
[:div
|
||||
[:input.w-100.center.input-reset.ba.b--black-20.pa2.mb2
|
||||
{:type "text"
|
||||
:placeholder "Search"
|
||||
:on-change (fn [evt]
|
||||
(swap! state assoc :search {:terms (-> evt .-target .-value)}))}]])
|
||||
|
||||
(defn ui-sidebar [{:keys [sidebar body]}]
|
||||
(let [search (r/atom "")]
|
||||
(fn [{:keys [sidebar body]}]
|
||||
[:div.h-100.flex.items-stretch
|
||||
[:div.dn.db-l.pa3.bg-blue {:style {:flex-basis "20rem" :flex-grow "1"}} sidebar]
|
||||
[:div.ma3.pa3 {:style {:flex-basis "0" :flex-grow "999"}}
|
||||
[ui-search search]
|
||||
body]])))
|
||||
|
||||
#_(defn ui-tags [meta]
|
||||
[:div (map-indexed
|
||||
(fn [idx tag]
|
||||
[:span.mr2 {:key idx}
|
||||
[pill-grow
|
||||
{:href (rfe/href :archive {:tag tag})
|
||||
:text tag}]])
|
||||
(-> meta :filetags extract-tags))])
|
||||
|
||||
#_(defn title-text-image [{:keys [title content] :as optional} tags]
|
||||
[:article.lh-copy.f4.mt-0
|
||||
[:h1.f2 title]
|
||||
(when tags
|
||||
[ui-tags tags])
|
||||
(when (:img-src optional)
|
||||
[:img.w-100.f5.measure {:src (:img-src optional) :alt (:img-alt optional)}])
|
||||
content])
|
||||
|
||||
(defn layout [content]
|
||||
(let [org-index (r/cursor state [:index])]
|
||||
(fn [content]
|
||||
[:<>
|
||||
[:link {:rel "stylesheet" :href "https://unpkg.com/tachyons@4.12.0/css/tachyons.min.css"}]
|
||||
[:link {:rel "stylesheet" :href "https://cdn.jsdelivr.net/npm/@fortawesome/fontawesome-free@5.15.3/css/fontawesome.min.css"}]
|
||||
[:style
|
||||
".font{font-family: \"Roboto Slab\",serif !important;}"
|
||||
".r90{transition: all 3s; transform-style: preserve-3d; transform-origin: top left; transform: rotate3d(0,1,0,180deg); backface-visibility: visible;}
|
||||
|
||||
|
||||
.r180-back{transition: all 3s; transform-style: preserve-3d; transform-origin: top left; transform: rotate3d(0,1,0,180deg); backface-visibility: visible;}
|
||||
.r180-front{transition: all 3s; transform-style: preserve-3d; transform-origin: top left; transform: rotate3d(0,1,0,180deg); backface-visibility: hidden;}
|
||||
.r0{transition: all 3s; transform-style: preserve-3d; transform-origin: top left; transform: rotate3d(0,1,0,0deg); backface-visibility: visible;}"]
|
||||
[:div.font.h-100
|
||||
[ui-sidebar
|
||||
{:body content
|
||||
:sidebar [:div
|
||||
[profile-card {:name "Oly" :tagline "Earthling, Software Engineer" :img-src "/images/default/me.png"}]
|
||||
[:ul.list.pl0.measure.center
|
||||
[:li.lh-copy.pv3.b--black-30.ba.bt-0.bl-0.br-0
|
||||
[:a.black.f3.link.hover-green
|
||||
{:href (rfe/href :homepage)} "Home"]]
|
||||
[:li.lh-copy.pv3.b--black-30.ba.bt-0.bl-0.br-0
|
||||
[:a.black.f3.link.hover-green
|
||||
{:href (rfe/href :archive {:tag ""})} "Past articles"]]
|
||||
[:li.lh-copy.pv3.b--black-30.ba.bt-0.bl-0.br-0
|
||||
[:a.black.f3.link.hover-green
|
||||
{:href (rfe/href :about)} "About"]]
|
||||
#_[:li.lh-copy.pv3.b--black-30.ba.bt-0.bl-0.br-0
|
||||
[:a.black.f3.link.hover-green
|
||||
{:href (rfe/href :book {:path ""})} "Book test"]]]]}]]])))
|
||||
|
||||
(defn book-page [front back current-page page degrees callback]
|
||||
[:div.outline.w-50.v-mid.absolute.center.bg-blue.r0
|
||||
{:onMouseUp #(when (<= current-page page) (callback inc))
|
||||
:style {:left "50%" :height "105px"
|
||||
:backface-visibility "hidden"
|
||||
:transform (str "rotate3D(0,1,0,"
|
||||
degrees
|
||||
#_(if (<= (+ 1 current-page) page)
|
||||
0
|
||||
180)
|
||||
"deg")}}
|
||||
|
||||
[:div.w-100.h-100.absolute.bg-green
|
||||
{:onMouseUp #(when (> current-page page) (callback dec))
|
||||
:style {:backface-visibility "hidden"
|
||||
:transform
|
||||
(str "rotate3D(0,1,0,"
|
||||
180
|
||||
"deg")}}
|
||||
(+ 1 page)
|
||||
"-" degrees "-"
|
||||
back]
|
||||
page "-" degrees "-" front])
|
||||
|
||||
(defn rotate-test
|
||||
[]
|
||||
(let [current-page (r/atom 1)
|
||||
flick (fn [dir] (prn dir)
|
||||
(swap! current-page dir))
|
||||
pages (vec (search-articles {}))
|
||||
p (r/track! (fn []
|
||||
(prn @current-page)
|
||||
(prn (- @current-page 1))
|
||||
(prn (+ 4 @current-page))
|
||||
(subvec pages 0 4 #_#_(- @current-page 1) (+ 4 @current-page))))]
|
||||
(fn []
|
||||
[:div
|
||||
(str (count pages))
|
||||
(str (nth @p 1))
|
||||
(str @current-page)
|
||||
[:div.flex.relative.center
|
||||
[:<>
|
||||
[book-page
|
||||
(:title (nth @p 2))
|
||||
(:title (nth @p 3))
|
||||
@current-page 3
|
||||
(if (<= (* 180 (- @current-page 2)) 0) 0 (* 180 (- @current-page 2)))
|
||||
flick]
|
||||
[book-page
|
||||
(:title (first @p))
|
||||
(:title (second @p))
|
||||
@current-page 1
|
||||
(* 180 (- 1 @current-page))
|
||||
flick]]]
|
||||
|
||||
@current-page])))
|
||||
|
||||
;(partition 4 [1 2 3 4 5 6 7 8 9 10])
|
||||
;(mod 360 180)
|
||||
(defn book-pages
|
||||
[& pages]
|
||||
(let [current-page (r/atom 0)
|
||||
flick (fn [idx dir] (swap! current-page dir))]
|
||||
(fn [pages]
|
||||
[:div.flex.relative.center @current-page
|
||||
(doall
|
||||
(->> pages
|
||||
(map-indexed (fn [idx page] [(+ 1 idx) page]))
|
||||
(reverse)
|
||||
;(partition 4)
|
||||
;(first)
|
||||
(map (fn [[idx page]]
|
||||
[:<> {:key idx}
|
||||
[:div.outline.w-50.v-mid.absolute.center.bg-blue
|
||||
{:onMouseUp #(flick idx inc)
|
||||
:class (when (>= @current-page idx) "r0")
|
||||
:style {:left "50%" :height "1050px"
|
||||
:transform (if (< idx @current-page)
|
||||
;(str "rotate3D(0,1,0,360deg)")
|
||||
(str "rotate3D(0,1,0," (* @current-page 180) "deg)")
|
||||
(str "rotate3D(0,1,0," (* @current-page 180) "deg)")
|
||||
;(str "rotate3D(0,1,0," (* (- 1 idx) 180) "deg)")
|
||||
)
|
||||
:z-index (if (> idx @current-page) "1" "0")}}
|
||||
[:div (when (= idx (+ 1 @current-page)) {:style {:transform "rotateY(180deg)"}}) "back page"
|
||||
idx
|
||||
page]]]))))])))
|
||||
|
||||
(defn book [{:keys [path-params] :as route}]
|
||||
(let [document (r/cursor state [:document :hiccup])]
|
||||
(fn [{:keys [path-params] :as route}]
|
||||
[:<>
|
||||
[rotate-test]
|
||||
#_[book-pages
|
||||
|
||||
(mapv (fn [article] [:div.p1 (str article)
|
||||
|
||||
[title-text-image {:title article
|
||||
:content (into [:div]
|
||||
(vec
|
||||
(rest
|
||||
@doc)))}
|
||||
(:details @document)]]) (search-articles {}))]])))
|
||||
|
||||
(defn ^:dev/after-load reagent-render [hiccup]
|
||||
(dom/render hiccup (js/document.getElementById "app")))
|
||||
|
||||
|
||||
(defn render-page []
|
||||
(let [current-page (r/cursor state [:current-route])]
|
||||
;; load in the latest document
|
||||
(fn []
|
||||
(when (-> @current-page :data :init)
|
||||
((-> @current-page :data :init) nil)
|
||||
((-> @current-page :data :init) (-> @current-page :parameters :path :path)))
|
||||
(when (-> @current-page :data :state)
|
||||
((-> @current-page :data :state) (-> @current-page :parameters :path :path)))
|
||||
[layout [(-> @current-page :data :view) (-> @current-page)]]
|
||||
#_(case (-> @current-page :data :name)
|
||||
:homepage [layout [page-homepage @current-page]]
|
||||
:archive [layout [archive @current-page]]
|
||||
:posts [layout [post @current-page]]
|
||||
:book [layout [book @current-page]]
|
||||
:about [layout [about-page @current-page]]
|
||||
[layout [:div "default"]]))))
|
||||
|
||||
(defn ^:after-load init []
|
||||
(rfe/start!
|
||||
router
|
||||
(fn [m]
|
||||
(swap! state assoc :current-route m)
|
||||
;;(switch-to-latest (-> @state :current-route :parameters :path :path))
|
||||
)
|
||||
{:use-fragment false})
|
||||
|
||||
(GET "/documents/org-meta-index.edn"
|
||||
{:handler (fn [response]
|
||||
(->> (reader/read-string response)
|
||||
;; filter out missing dates
|
||||
(filter (fn [doc] (some? (:date doc))))
|
||||
(mapv #(assoc % :tags (into [] (:filetags %))))
|
||||
(mapv #(assoc % :date (convert-date (:date %))))
|
||||
(swap! state assoc :index))
|
||||
(d/reset-conn! conn (d/empty-db schema))
|
||||
(d/transact! conn (:index @state))
|
||||
(select-initial-page (-> @state :current-route :parameters :path :path)))})
|
||||
(reagent-render [render-page]))
|
||||
|
||||
;;(defonce start (init))
|
||||
|
||||
;;(comment )
|
||||
;; (-> @state :document)
|
||||
;; (latest-article)
|
||||
|
||||
; (switch-to-latest)
|
||||
;; (org->to-hiccup tachyon-theme (-> @state :document :body))
|
|
@ -0,0 +1,5 @@
|
|||
(ns com.oly.static-sites.do-blog.pages.about)
|
||||
|
||||
(defn about-page [{:keys [path-params] :as route}]
|
||||
(fn [{:keys [path-params] :as route}]
|
||||
[:div "hi2"]))
|
|
@ -0,0 +1,21 @@
|
|||
(ns com.oly.static-sites.do-blog.pages.archive
|
||||
(:require [reagent.core :as r]
|
||||
[reitit.frontend.easy :as rfe]
|
||||
[tachyons.definition-lists :refer [simple]]
|
||||
[com.oly.static-sites.do-blog.pages.helpers.utils :refer [format-date]]
|
||||
[com.oly.static-sites.do-blog.pages.helpers.database :refer [search-articles state]]))
|
||||
|
||||
(defn archive-page [{:keys [path-params] :as route}]
|
||||
(let [search (r/cursor state [:search :terms])
|
||||
org-index (r/reaction (search-articles (merge {:search @search} path-params)))]
|
||||
(fn [{:keys [path-params] :as route}]
|
||||
[:div {:key "search"}
|
||||
[:h1 "Past articles"]
|
||||
[simple
|
||||
{:list
|
||||
(map-indexed (fn [idx doc]
|
||||
{:text [:div [:a.f4.lh-copy {:href (str (rfe/href :posts {:path ""}) (:relative-path doc))
|
||||
:key idx}
|
||||
(str (format-date (:date doc))
|
||||
#_(convert-date (:date doc)) " " (:title doc))]]})
|
||||
@org-index)}]])))
|
|
@ -0,0 +1,16 @@
|
|||
(ns com.oly.static-sites.do-blog.pages.article
|
||||
(:require [reagent.core :as r]
|
||||
[reitit.frontend.easy :as rfe]
|
||||
[com.oly.static-sites.do-blog.pages.helpers.utils :refer [format-date]]
|
||||
[com.oly.static-sites.do-blog.pages.helpers.database :refer [search-articles state]]
|
||||
[com.oly.static-sites.do-blog.pages.components.core :refer [ui-tags title-text-image article-list-author-media-flipped]]))
|
||||
|
||||
|
||||
(defn article-page [{:keys [path-params] :as route}]
|
||||
(let [document (r/cursor state [:document])]
|
||||
(fn [{:keys [path-params] :as route}]
|
||||
[:<>
|
||||
[title-text-image
|
||||
{:title (-> @document :details :title)
|
||||
:content (-> @document :hiccup)}
|
||||
(-> @document :details)]])))
|
|
@ -0,0 +1,41 @@
|
|||
(ns com.oly.static-sites.do-blog.pages.components.core
|
||||
(:require [reitit.frontend.easy :as rfe]
|
||||
[tachyons.buttons :refer [pill-grow]]
|
||||
[com.oly.static-sites.do-blog.pages.helpers.utils :refer [extract-tags format-date]]
|
||||
))
|
||||
|
||||
(defn ui-tags [meta]
|
||||
[:div (map-indexed
|
||||
(fn [idx tag]
|
||||
[:span.mr2 {:key idx}
|
||||
[pill-grow
|
||||
{:href (rfe/href :archive {:tag tag})
|
||||
:text tag}]])
|
||||
(-> meta :filetags extract-tags))])
|
||||
|
||||
(defn article-list-author-media-flipped [title articles]
|
||||
[:section.mw7.center
|
||||
(when title [:h2.athelas.ph3.ph0-l title])
|
||||
(map-indexed (fn [idx {:keys [title relative-path description date author src alt thumbnail] :as article}]
|
||||
[:article.pv4.bb.b--black-10.ph3.ph0-l
|
||||
{:keys idx}
|
||||
[:div.flex.flex-column.flex-row-ns
|
||||
[:div.w-100.w-60-ns.pr3-ns.order-2.order-1-ns
|
||||
[:a {:href (str (rfe/href :posts {:path ""}) relative-path)}
|
||||
[:h1.f3.athelas.mt0.lh-title title]]
|
||||
[:p.f5.f4-l.lh-copy.athelas description]]
|
||||
(when thumbnail [:div.pl3-ns.order-1.order-2-ns.mb4.mb0-ns.w-100.w-40-ns
|
||||
[:img.db {:src thumbnail
|
||||
:alt alt}]])]
|
||||
[:p.f6.lh-copy.gray.mv0 (when author (str "By " author))
|
||||
(when date [:time.f6.db.gray (format-date date)])]])
|
||||
articles)])
|
||||
|
||||
(defn title-text-image [{:keys [title content] :as optional} tags]
|
||||
[:article.lh-copy.f4.mt-0
|
||||
[:h1.f2 title]
|
||||
(when tags
|
||||
[ui-tags tags])
|
||||
(when (:img-src optional)
|
||||
[:img.w-100.f5.measure {:src (:img-src optional) :alt (:img-alt optional)}])
|
||||
content])
|
|
@ -0,0 +1,60 @@
|
|||
(ns com.oly.static-sites.do-blog.pages.helpers.database
|
||||
(:require [clojure.string :as str]
|
||||
[reagent.core :as r]
|
||||
[datascript.core :as d]
|
||||
[com.oly.static-sites.do-blog.pages.helpers.utils :refer [ltrim-slash]]))
|
||||
|
||||
(defonce schema {:tags {:db/cardinality :db.cardinality/many}})
|
||||
(defonce conn (d/create-conn schema))
|
||||
(defonce document (r/atom {}))
|
||||
(defonce state
|
||||
(r/atom {:index []
|
||||
:search {:terms ""
|
||||
:results []}
|
||||
:document {:details nil :body nil}
|
||||
:latest nil
|
||||
:current-doc ""
|
||||
:new-data 0
|
||||
:current-key :org-01}))
|
||||
|
||||
;(def not-empty? (complement empty?))
|
||||
|
||||
(def db-search
|
||||
'{:find [(pull ?e [*])]
|
||||
:in [$]
|
||||
:where
|
||||
[[?e :title ?title]
|
||||
[(get-else $ ?e :description :nil) ?description]
|
||||
[?e :date ?date]
|
||||
[(get-else $ ?e :thumbnail :nil) ?thumbnail]
|
||||
[?e :relative-path ?path]]})
|
||||
|
||||
(defn db-search-filter
|
||||
"Add where clauses to the datalog query when supplied"
|
||||
[{:keys [search tag]}]
|
||||
(let [re-search (if (not (str/blank? search)) #_(js/RegEx (str "(?i)" search))
|
||||
(re-pattern (str "(?i)" search)) nil)]
|
||||
(prn re-search)
|
||||
(cond-> db-search
|
||||
(not (str/blank? tag))
|
||||
(update-in [:where] #(conj % ['?e :tags tag]))
|
||||
re-search
|
||||
(update-in [:where] #(conj % [`(~'re-find ~re-search ~'?title)])))))
|
||||
|
||||
(defn search-articles [search]
|
||||
(prn (db-search-filter search))
|
||||
(->>
|
||||
(d/q (db-search-filter search) @conn)
|
||||
(flatten)
|
||||
(sort-by :date)
|
||||
reverse
|
||||
(map #(assoc %1 :relative-path (ltrim-slash (:relative-path %1))))))
|
||||
|
||||
(defn latest-article
|
||||
"Just return the first item from search articles."
|
||||
[]
|
||||
(->> (search-articles {:search ""})
|
||||
first
|
||||
:relative-path))
|
||||
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
(ns com.oly.static-sites.do-blog.pages.helpers.utils
|
||||
(:require
|
||||
[clojure.string :as str]
|
||||
[tick.core :as t]
|
||||
[tick.locale-en-us]
|
||||
[tick.timezone]))
|
||||
|
||||
(defonce date-format (t/formatter "yyyy-MMM-dd"))
|
||||
|
||||
(defn format-date [text]
|
||||
(when text
|
||||
(t/format date-format text)))
|
||||
|
||||
(defn ltrim-slash "Right trim a leading slash" [text] (str/replace text #"^/" ""))
|
||||
|
||||
(defn extract-tags [text]
|
||||
(->> (clojure.string/split text #_(:filetags %) #":")
|
||||
(reduce (fn [m a] (conj m a)) [])
|
||||
vec))
|
|
@ -0,0 +1,21 @@
|
|||
(ns com.oly.static-sites.do-blog.pages.home
|
||||
(:require [reagent.core :as r]
|
||||
[reitit.frontend.easy :as rfe]
|
||||
[com.oly.static-sites.do-blog.pages.helpers.utils :refer [format-date]]
|
||||
[com.oly.static-sites.do-blog.pages.helpers.database :refer [search-articles state]]
|
||||
[com.oly.static-sites.do-blog.pages.components.core :refer [ui-tags title-text-image article-list-author-media-flipped]]))
|
||||
|
||||
(defn home-page [{:keys [path] :as route}]
|
||||
(let [search (r/cursor state [:search :terms])
|
||||
latest (r/cursor state [:document])]
|
||||
(fn []
|
||||
[:<>
|
||||
[:div
|
||||
(if (empty? @search)
|
||||
[title-text-image
|
||||
{:title (-> @latest :details :title)
|
||||
:content (-> @latest :hiccup)}
|
||||
(-> @latest :details)]
|
||||
[article-list-author-media-flipped
|
||||
"Articles"
|
||||
(search-articles {:search @search})])]])))
|
|
@ -0,0 +1,61 @@
|
|||
(ns com.oly.static-sites.do-blog.theme)
|
||||
|
||||
(defn link-handler [v d]
|
||||
(if (-> v second :img)
|
||||
(conj [:img] (-> (dissoc (clojure.set/rename-keys (second v) {:href :src}) :img)
|
||||
(update :src #(clojure.string/replace % #"\.\./" "")) )
|
||||
)
|
||||
(conj [:a] (second v))))
|
||||
|
||||
|
||||
(def tachyon-theme
|
||||
{:TITLE :header.f2.fw6.f2-ns.lh-title.mt0.mb2
|
||||
;:DESCRIPTION :p
|
||||
:HEADER1 :h1.f3.fw6.f3-ns.lh-title.mt0.mb2
|
||||
:HEADER2 :h2.f3.fw6.f3-ns.lh-title.mt0.mb2
|
||||
:HEADER3 :h3
|
||||
:HEADER4 :h4
|
||||
:HEADER5 :h5
|
||||
:TODO :span
|
||||
:VERBATIM :code
|
||||
:CODE :code
|
||||
|
||||
:MAIN :main
|
||||
|
||||
:THUMBNAIL nil
|
||||
:DESCRIPTION :meta ;(fn [v] [:span {:name (str v)} ])
|
||||
:CATEGORY :meta ;(fn [v] [:span {:name (str v)} ])
|
||||
:SLUG :meta ;(fn [v] [:span {:name (str v)} ])
|
||||
:DATE :meta ;(fn [v] [:span {:name (str v)} ])
|
||||
:FILETAGS (fn [v] [:meta {:name "keywords" :content (str v)}])
|
||||
:NAME :meta ;(fn [v] [:span {:name (str v)} ])
|
||||
:HTML_DOCTYPE :meta
|
||||
|
||||
:TABLE :table.collapse.ba.br2.b--black-10.pv2.ph3
|
||||
:TBODY :tbody
|
||||
:THEAD :thead
|
||||
:TR :tr.striped--light-gray
|
||||
:TD :td.pv2.ph3
|
||||
|
||||
;;TODO this is a src attrib probably worth handling this differently
|
||||
;;perhaps allow custom functions instead of a simple replace
|
||||
:LANGUAGE :class
|
||||
:SRC :pre.bg-near-black.silver.pa2.hljs.roboto.overflow-auto.klipse.f6
|
||||
:RESULTS :pre.bg-near-black.silver.pa2.hljs.roboto.overflow-auto
|
||||
:EXAMPLE :pre.bg-near-black.silver.pa2.hljs.roboto.overflow-auto
|
||||
:COMMENT nil
|
||||
:CAPTION :span
|
||||
:I :i
|
||||
:U :u
|
||||
:B :b
|
||||
:LINK link-handler
|
||||
:IMG :img
|
||||
;; probably remove these 2
|
||||
:A :a
|
||||
:P :p
|
||||
:BR :br
|
||||
:LINE :p.f5.f4-ns.lh-copy.mt0
|
||||
:BULLETS-ORDERED :ol
|
||||
:BULLETS :ul
|
||||
:BULLET :li
|
||||
})
|
38
deps.edn
38
deps.edn
|
@ -1,24 +1,50 @@
|
|||
{:paths ["development/src" "bases/portfolio/src"]
|
||||
{:paths ["development/src" "bases/portfolio/src" "bases/do-blog/src"]
|
||||
:deps {cjohansen/dumdom {:mvn/version "2023.11.06"}
|
||||
org.clojure/clojurescript {:mvn/version "1.11.60"}
|
||||
|
||||
no.cjohansen/portfolio {:mvn/version "2023.07.15"}}
|
||||
:aliases {:dev {:extra-paths ["development/src" "bases/portfolio/src" ]
|
||||
:aliases {
|
||||
:dev {:extra-paths ["development/src" "bases/portfolio/src" "bases/do-blog/src"]
|
||||
:extra-deps {org.clojure/clojure {:mvn/version "1.10.3"}
|
||||
org.clojure/clojurescript {:mvn/version "1.11.60"}
|
||||
|
||||
org.clojure/tools.deps.alpha {:mvn/version "0.12.1003"}
|
||||
|
||||
cljs-ajax/cljs-ajax {:mvn/version "0.8.1"}
|
||||
|
||||
;; dev libraries
|
||||
thheller/shadow-cljs {:mvn/version "2.25.2"}
|
||||
refactor-nrepl/refactor-nrepl {:mvn/version "3.9.0"}
|
||||
cider/cider-nrepl {:mvn/version "0.43.1"}
|
||||
;;refactor-nrepl/refactor-nrepl {:mvn/version "3.9.0"}
|
||||
;;cider/cider-nrepl {:mvn/version "0.43.1"}
|
||||
no.cjohansen/portfolio {:mvn/version "2023.07.15"}
|
||||
djblue/portal {:mvn/version "0.48.0"}}}
|
||||
|
||||
:blog {:extra-paths ["development/src" "bases/do-blog/src"]
|
||||
:extra-deps {
|
||||
org.clojure/core.async {:mvn/version "1.6.673"}
|
||||
org.clojure/clojurescript {:mvn/version "1.11.60"}
|
||||
|
||||
reagent/reagent {:mvn/version "1.1.1"}
|
||||
tick/tick {:mvn/version "0.5.0"}
|
||||
metosin/reitit {:mvn/version "0.5.18"}
|
||||
|
||||
cljs-ajax/cljs-ajax {:mvn/version "0.8.4"}
|
||||
|
||||
datascript/datascript {:mvn/version "1.4.0"}
|
||||
olymk2/tachyon-reagent {:git/url "https://gitlab.com/olymk2/tachyon-reagent.git"
|
||||
:sha "e422af7b41266f7bc90ab78a24fb93f32be61385"}
|
||||
olymk2/cl-eorg {:git/url "https://gitlab.com/olymk2/cl-org.git"
|
||||
:sha "528e8125afcac5d7664aac80f7fbba12dd0f5d98"}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
:shadow-cljs-run
|
||||
{:extra-deps {thheller/shadow-cljs {:mvn/version "2.25.2"}
|
||||
refactor-nrepl/refactor-nrepl {:mvn/version "3.9.0"}
|
||||
cider/cider-nrepl {:mvn/version "0.50.2"}
|
||||
refactor-nrepl/refactor-nrepl {:mvn/version "3.10.0"}
|
||||
cider/piggieback {:mvn/version "0.5.3"}}
|
||||
:extra-paths ["dev"]
|
||||
:extra-paths ["dev" "bases/do-blog/src"]
|
||||
:main-opts ["-m" "shadow.cljs.devtools.cli"]}
|
||||
|
||||
:test {:extra-paths []}
|
||||
|
|
|
@ -4,3 +4,6 @@ npx shadow-cljs server
|
|||
|
||||
npx tailwindcss -i ./development/resources/public/css/tailwind-styles.css -o ./development/resources/public/css/styles.css --watch
|
||||
|
||||
|
||||
|
||||
clj -M:blog::shadow-cljs-run watch blog
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
{:deps {:aliases [:dev]}
|
||||
:dev-http {8080 ["development/resources/public/" "classpath:public"]}
|
||||
{:deps {:aliases [:blog]}
|
||||
:dev-http {8080 ["bases/do-blog/resources/public" "classpath:public"]
|
||||
8081 ["development/resources/public/" "classpath:public"]}
|
||||
;:nrepl {:middleware [refactor-nrepl.middleware/wrap-refactor]}
|
||||
:nrepl {:middleware [refactor-nrepl.middleware/wrap-refactor]}
|
||||
:source ["devlopment/src" "bases/portfolio/src"] ;;"src"
|
||||
;; :source ["devlopment/src" "bases/portfolio/src"] ;;"src"
|
||||
;; "../../components/web-ui/src"
|
||||
;; "../../components/web-api/src"
|
||||
;; "../../components/polyculture/src"
|
||||
;; "../../components/svg-generation/src"
|
||||
;; "../../components/local-store/src"]
|
||||
:builds {:app {:output-dir "development/resources/public/cljs-out"
|
||||
:builds {:app {:output-dir "bases/portfolio/resources/public/js"
|
||||
;:asset-path "."
|
||||
:target :browser
|
||||
:compiler-options {:infer-externs :auto :output-feature-set :es6}
|
||||
|
@ -18,6 +19,15 @@
|
|||
:portfolio {:init-fn design/launch
|
||||
:depends-on #{:base}}
|
||||
}
|
||||
:devtools {:after-load app.main/reload!}}
|
||||
:blog {:output-dir "bases/do-blog/resources/public/js"
|
||||
;:asset-path "."
|
||||
:target :browser
|
||||
:compiler-options {:infer-externs :auto :output-feature-set :es6}
|
||||
:modules {:base {:entries []}
|
||||
:app {:init-fn com.oly.static-sites.do-blog.core/init
|
||||
:depends-on #{:base}}
|
||||
}
|
||||
:devtools {:after-load app.main/reload!}
|
||||
}
|
||||
}}
|
||||
|
|
Loading…
Reference in New Issue