(ns sitetools.prerender (:require [reagentdemo.core :as demo] [clojure.string :as string] [goog.events :as evt] [reagent.core :as r] [reagent.dom.server :as server] [reagent.debug :refer-macros [dbg log dev?]] [sitetools.core :as tools] ;; Node libs [path :as path] [md5-file :as md5-file] [path :as path] [fs :as fs])) (defn base [page] (let [depth (->> page tools/to-relative (re-seq #"/") count)] (->> "../" (repeat depth) (apply str)))) (defn danger [t s] [t {:dangerouslySetInnerHTML {:__html s}}]) (defn add-cache-buster [resource-path path] (let [h (md5-file/sync (path/join resource-path path))] (str path "?" (subs h 0 6)))) (defn html-template [{:keys [title body-html page-conf js-file css-file main-div js-resource-path site-dir]}] (server/render-to-static-markup [:html [:head [:meta {:charset 'utf-8}] [:meta {:name 'viewport :content "width=device-width, initial-scale=1.0"}] [:base {:href (-> page-conf :page-path base)}] [:link {:href (add-cache-buster site-dir css-file) :rel "stylesheet"}] [:title title]] [:body [:div {:id main-div} (danger :div body-html)] (danger :script (str "var pageConfig = " (-> page-conf clj->js js/JSON.stringify))) [:script {:src (add-cache-buster js-resource-path js-file) :type "text/javascript"}]]])) (defn gen-page [page-path conf] (tools/emit [:set-page page-path]) (let [conf (merge conf @tools/config) b (:body conf) bhtml (server/render-to-string b)] (str "\n" (html-template (assoc conf :page-conf {:page-path page-path} :body-html bhtml))))) (defn mkdirs [f] (doseq [d (reductions #(str %1 "/" %2) (-> (path/normalize f) (string/split #"/")))] (when-not (fs/existsSync d) (fs/mkdirSync d)))) (defn write-file [f content] (log "Write" f) (mkdirs (path/dirname f)) (fs/writeFileSync f content)) (defn write-resources [dir {:keys [css-file css-infiles]}] (write-file (path/join dir css-file) (->> css-infiles (map #(fs/readFileSync %)) (string/join "\n")))) (defn -main [& args] (log "Generating site") (demo/init!) (let [[js-resource-path] args {:keys [site-dir pages] :as conf} (assoc @tools/config :js-resource-path js-resource-path)] (write-resources site-dir conf) (doseq [f (keys pages)] (write-file (->> f tools/to-relative (path/join site-dir)) (gen-page f conf)))) (log "Wrote site") (js/process.exit 0)) (set! *main-cli-fn* -main)