diff --git a/.gitignore b/.gitignore index d29efbc..237e056 100644 --- a/.gitignore +++ b/.gitignore @@ -18,3 +18,4 @@ reagent.iml outsite/bundle.js outsite/bundle.min.js node_modules +pre-render diff --git a/Makefile b/Makefile index 967d76c..c32a393 100644 --- a/Makefile +++ b/Makefile @@ -70,16 +70,25 @@ push-gh-pages: build-gh-pages git push origin gh-pages:gh-pages # build site and push to reagent-project's doc site -push-project-docs: build-gh-pages - git push --force \ - https://github.com/reagent-project/reagent-project.github.io.git \ - gh-pages:master +push-project-docs: gen-site + # sanity check + test -f $(SITEDIR)/index.html + test ! -e $(OUTPUTDIR) + rm -fr tmp + git clone git@github.com:reagent-project/reagent-project.github.io.git tmp + rm -fr tmp/* + cp -r $(SITEDIR)/* tmp/ + cd tmp && \ + git add . && git commit -m "Updated" && \ + git push + rm -rf tmp # build site into a gh-pages branch build-gh-pages: gen-site gh-pages-add gen-site: clean lein with-profile prod cljsbuild once + lein with-profile prerender cljsbuild once # copy contents of $(SITEDIR) to branch gh-pages gh-pages-add: diff --git a/bin/gen-site.js b/bin/gen-site.js index e9c440d..1726591 100755 --- a/bin/gen-site.js +++ b/bin/gen-site.js @@ -1,8 +1,8 @@ var cljsLoad = require("./cljs-load"); -var srcFile = "outsite/public/js/main.js"; -var outputDirectory = "outsite/public/js/out/"; +var srcFile = "pre-render/main.js"; +var outputDirectory = "pre-render/out/"; var devFile = "reagenttest/runtests.js"; var beep = "\u0007"; @@ -15,7 +15,7 @@ if (typeof location === "undefined") { var gensite = function () { console.log("Loading " + srcFile); var optNone = cljsLoad.load(srcFile, outputDirectory, devFile); - sitetools.core.genpages({"opt-none": optNone}); + sitetools.server.genpages({"opt-none": optNone}); } var compileFail = function () { diff --git a/demo/reagentdemo/server.cljs b/demo/reagentdemo/server.cljs new file mode 100644 index 0000000..2f6b194 --- /dev/null +++ b/demo/reagentdemo/server.cljs @@ -0,0 +1,4 @@ +(ns reagentdemo.server + "Used to pre-render HTML files." + (:require [reagentdemo.core] + [sitetools.server])) diff --git a/demo/sitetools/core.cljs b/demo/sitetools/core.cljs index e81ac1c..aa0e227 100644 --- a/demo/sitetools/core.cljs +++ b/demo/sitetools/core.cljs @@ -2,7 +2,6 @@ (:require [clojure.string :as string] [goog.events :as evt] [reagent.core :as r] - [reagent.dom.server :as server] [reagent.debug :refer-macros [dbg log dev?]] [reagent.interop :as i :refer-macros [$ $!]]) (:import goog.History @@ -103,81 +102,8 @@ (defn main-content [] (get-in @config [:current-page :content])) - -;;; Static site generation - -(defn base [page] - (let [depth (->> page to-relative (re-seq #"/") count)] - (->> "../" (repeat depth) (apply str)))) - -(defn danger [t s] - [t {:dangerouslySetInnerHTML {:__html s}}]) - -(defn html-template [{:keys [title body-html timestamp page-conf - js-file css-file main-div]}] - (let [main (str js-file timestamp)] - (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 (str css-file timestamp) :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 main :type "text/javascript"}]]]))) - -(defn gen-page [page-path conf] - (emit [:set-page page-path]) - (let [conf (merge conf @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 fs [] (js/require "fs")) -(defn path [] (js/require "path")) - -(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] - (mkdirs ($ (path) dirname f)) - ($ (fs) writeFileSync f content)) - -(defn path-join [& paths] - (apply ($ (path) :join) paths)) - -(defn write-resources [dir {:keys [css-file css-infiles]}] - (write-file (path-join dir css-file) - (->> css-infiles - (map #($ (fs) readFileSync %)) - (string/join "\n")))) - - ;;; Main entry points -(defn ^:export genpages [opts] - (log "Generating site") - (let [conf (swap! config merge (js->clj opts :keywordize-keys true)) - conf (assoc conf :timestamp (str "?" (js/Date.now))) - {:keys [site-dir pages]} conf] - (doseq [f (keys pages)] - (write-file (->> f to-relative (path-join site-dir)) - (gen-page f conf))) - (write-resources site-dir conf)) - (log "Wrote site")) - (defn start! [site-config] (swap! config merge site-config) (when r/is-client diff --git a/demo/sitetools/server.cljs b/demo/sitetools/server.cljs new file mode 100644 index 0000000..361ad39 --- /dev/null +++ b/demo/sitetools/server.cljs @@ -0,0 +1,83 @@ +(ns sitetools.server + "Used to pre-render HTML files." + (:require [clojure.string :as string] + [goog.events :as evt] + [reagent.core :as r] + [reagent.dom.server :as server] + [reagent.debug :refer-macros [dbg log dev?]] + [reagent.interop :as i :refer-macros [$ $!]] + [sitetools.core :as tools])) + + +;;; Static site generation + +(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 html-template [{:keys [title body-html timestamp page-conf + js-file css-file main-div]}] + (let [main (str js-file timestamp)] + (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 (str css-file timestamp) :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 main :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 fs [] (js/require "fs")) +(defn path [] (js/require "path")) + +(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] + (mkdirs ($ (path) dirname f)) + ($ (fs) writeFileSync f content)) + +(defn path-join [& paths] + (apply ($ (path) :join) paths)) + +(defn write-resources [dir {:keys [css-file css-infiles]}] + (write-file (path-join dir css-file) + (->> css-infiles + (map #($ (fs) readFileSync %)) + (string/join "\n")))) + +;;; Main entry points + +(defn ^:export genpages [opts] + (log "Generating site") + (let [conf (swap! tools/config merge (js->clj opts :keywordize-keys true)) + conf (assoc conf :timestamp (str "?" (js/Date.now))) + {:keys [site-dir pages]} conf] + (doseq [f (keys pages)] + (write-file (->> f tools/to-relative (path-join site-dir)) + (gen-page f conf))) + (write-resources site-dir conf)) + (log "Wrote site")) diff --git a/project.clj b/project.clj index 2d8769b..05177da 100644 --- a/project.clj +++ b/project.clj @@ -37,10 +37,7 @@ :asset-path "js/out"}}}}}] :site {:resource-paths ^:replace ["outsite"] - :figwheel {:css-dirs ^:replace ["outsite/public/css"]} - :cljsbuild - {:builds {:client - {:notify-command ["node" "bin/gen-site.js"]}}}} + :figwheel {:css-dirs ^:replace ["outsite/public/css"]}} :prod [:site {:cljsbuild @@ -51,6 +48,14 @@ ;; :pseudo-names true :output-dir "target/client"}}}}}] + :prerender [:prod + {:cljsbuild + {:builds {:client + {:compiler {:main "reagentdemo.server" + :output-to "pre-render/main.js" + :output-dir "pre-render/out"} + :notify-command ["node" "bin/gen-site.js"] }}}}] + :webpack {:cljsbuild {:builds {:client {:compiler @@ -74,7 +79,8 @@ "outsite/public/news" "outsite/public/css" "outsite/public/index.html" - "out"] + "out" + "pre-render"] :cljsbuild {:builds {:client {:source-paths ["src"