diff --git a/examples/class-registry/project.clj b/examples/class-registry/project.clj index d9f2394..1f6e5eb 100644 --- a/examples/class-registry/project.clj +++ b/examples/class-registry/project.clj @@ -16,7 +16,7 @@ [reagent-data-views "0.2.0-SNAPSHOT"] [reagent-data-views-browserchannel "0.1.0-SNAPSHOT"] - [clj-pebble "0.2.0"] + [hiccup "1.0.5"] [reagent "0.6.0-alpha2"] [cljsjs/bootstrap "3.3.6-1"] [cljs-ajax "0.5.4"] @@ -33,8 +33,10 @@ [:cljsbuild :builds :main :compiler :output-to]] :cljsbuild {:builds {:main {:source-paths ["src"] - :compiler {:output-to "resources/public/cljs/app.js" + :compiler {:main class-registry.client + :output-to "resources/public/cljs/app.js" :output-dir "resources/public/cljs/target" + :asset-path "cljs/target" :source-map true :optimizations :none :pretty-print true}}}} diff --git a/examples/class-registry/resources/html/app.html b/examples/class-registry/resources/html/app.html deleted file mode 100644 index 0f154fe..0000000 --- a/examples/class-registry/resources/html/app.html +++ /dev/null @@ -1,25 +0,0 @@ - - - - - - Class Registry - - - - - - - - -
- {% if dev %}{% endif %} - - {% if dev %}{% endif %} - - - diff --git a/examples/class-registry/src/class_registry/client.cljs b/examples/class-registry/src/class_registry/client.cljs index 0d54225..4e6e3df 100644 --- a/examples/class-registry/src/class_registry/client.cljs +++ b/examples/class-registry/src/class_registry/client.cljs @@ -5,7 +5,7 @@ [ajax.core :refer [POST default-interceptors to-interceptor]] [net.thegeez.browserchannel.client :as browserchannel] [reagent-data-views.client.component :refer [view-cursor] :refer-macros [defvc]] - [reagent-data-views.browserchannel.client :as rdv-browserchannel])) + [reagent-data-views.browserchannel.client :as rdv])) ;; Class Registry - Reagent Data Views example app ;; @@ -361,8 +361,8 @@ (defn get-anti-forgery-token [] - (if-let [tag (aget (.querySelectorAll js/document "meta[name='anti-forgery-token']") 0)] - (.-content tag))) + (if-let [hidden-field (.getElementById js/document "__anti-forgery-token")] + (.-value hidden-field))) (def csrf-interceptor (to-interceptor {:name "CSRF Interceptor" @@ -376,8 +376,7 @@ (defn ^:export run [] - (enable-console-print!) - (rdv-browserchannel/configure!) - (browserchannel/connect! {} {:middleware [rdv-browserchannel/middleware]}) + (rdv/configure!) + (browserchannel/connect! {} {:middleware [rdv/middleware]}) (r/render-component [class-registry-app] (.getElementById js/document "app"))) diff --git a/examples/class-registry/src/class_registry/server.clj b/examples/class-registry/src/class_registry/server.clj index e5e5718..006bc24 100644 --- a/examples/class-registry/src/class_registry/server.clj +++ b/examples/class-registry/src/class_registry/server.clj @@ -4,18 +4,19 @@ [compojure.core :refer [routes GET POST]] [compojure.route :as route] [ring.middleware.defaults :refer [wrap-defaults site-defaults]] - [ring.middleware.anti-forgery :refer [*anti-forgery-token*]] [ring.middleware.format :refer [wrap-restful-format]] + [ring.util.anti-forgery :refer [anti-forgery-field]] [ring.util.response :refer [response]] [net.thegeez.browserchannel.server :refer [wrap-browserchannel]] [net.thegeez.browserchannel.immutant-async-adapter :refer [wrap-immutant-async-adapter]] [immutant.web :as immutant] - [clj-pebble.core :as pebble] + [hiccup.page :refer [html5 include-css include-js]] + [hiccup.element :refer [javascript-tag]] [environ.core :refer [env]] [clojure.java.jdbc :as jdbc] [views.sql.core :refer [vexec! with-view-transaction]] [views.sql.view :refer [view]] - [reagent-data-views.browserchannel.server :as rdv-browserchannel])) + [reagent-data-views.browserchannel.server :as rdv])) (def dev? (boolean (env :dev))) @@ -134,6 +135,25 @@ +;; main page html + +(defn render-page + [] + (html5 + [:head + [:title "Class Registry"] + [:meta {:name "viewport" :content "width=device-width, initial-scale=1"}] + (include-css + "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css" + "app.css") + (include-js "cljs/app.js")] + [:body + (anti-forgery-field) + [:div#app [:h1 "This will be replaced by the Class Registry app when the ClojureScript is compiled."]] + (javascript-tag "class_registry.client.run();")])) + + + ;; Compojure routes and Ring handler (def app-routes @@ -151,10 +171,7 @@ (POST "/registry/remove" [id] (remove-registration! id)) ; main page - (GET "/" [] (pebble/render-resource - "html/app.html" - {:dev dev? - :csrfToken *anti-forgery-token*})) + (GET "/" [] (render-page)) (route/resources "/") (route/not-found "not found"))) @@ -163,19 +180,18 @@ (-> app-routes (wrap-restful-format :formats [:transit-json]) (wrap-defaults (assoc-in site-defaults [:security :anti-forgery] (not dev?))) - (wrap-browserchannel {} {:middleware [(rdv-browserchannel/->middleware view-system)]}) + (wrap-browserchannel {} {:middleware [(rdv/->middleware view-system)]}) (wrap-immutant-async-adapter))) ;; Web server startup & main -(defn run-server [] - (pebble/set-options! :cache (not dev?)) - - (rdv-browserchannel/init-views! view-system {:views views}) - +(defn run-server + [] + (rdv/init-views! view-system {:views views}) (immutant/run handler {:port 8080})) -(defn -main [& args] +(defn -main + [& args] (run-server)) diff --git a/examples/todomvc/project.clj b/examples/todomvc/project.clj index 5705734..67a94c4 100644 --- a/examples/todomvc/project.clj +++ b/examples/todomvc/project.clj @@ -8,18 +8,16 @@ [org.clojure/java.jdbc "0.6.1"] [org.postgresql/postgresql "9.4.1208.jre7"] - [gered/clj-browserchannel "0.3.1"] + [gered/clj-browserchannel "0.3.2"] [gered/clj-browserchannel-immutant-adapter "0.0.3"] [gered/views "1.5-SNAPSHOT"] [gered/views-sql "0.1.0-SNAPSHOT"] [reagent-data-views "0.2.0-SNAPSHOT"] [reagent-data-views-browserchannel "0.1.0-SNAPSHOT"] - [clj-pebble "0.2.0"] + [hiccup "1.0.5"] [reagent "0.6.0-alpha2"] [cljs-ajax "0.5.4"] - ; only being used to get a tag value with the CSRF token in it - [prismatic/dommy "1.1.0"] [environ "1.0.3"]] @@ -33,8 +31,10 @@ [:cljsbuild :builds :main :compiler :output-to]] :cljsbuild {:builds {:main {:source-paths ["src"] - :compiler {:output-to "resources/public/cljs/app.js" + :compiler {:main todomvc.client + :output-to "resources/public/cljs/app.js" :output-dir "resources/public/cljs/target" + :asset-path "cljs/target" :source-map true :optimizations :none :pretty-print true}}}} diff --git a/examples/todomvc/resources/html/app.html b/examples/todomvc/resources/html/app.html deleted file mode 100644 index 7792a9c..0000000 --- a/examples/todomvc/resources/html/app.html +++ /dev/null @@ -1,26 +0,0 @@ - - - - - todomvc with reagent - - - - - - - -
-

This will become todomvc when the ClojureScript is compiled

-
- {% if dev %}{% endif %} - - {% if dev %}{% endif %} - - - \ No newline at end of file diff --git a/examples/todomvc/src/todomvc/client.cljs b/examples/todomvc/src/todomvc/client.cljs index ee71bad..4e5cdf5 100644 --- a/examples/todomvc/src/todomvc/client.cljs +++ b/examples/todomvc/src/todomvc/client.cljs @@ -2,10 +2,9 @@ (:require [reagent.core :as r] [ajax.core :refer [POST default-interceptors to-interceptor]] - [dommy.core :refer-macros [sel1]] [net.thegeez.browserchannel.client :as browserchannel] [reagent-data-views.client.component :refer [view-cursor] :refer-macros [defvc]] - [reagent-data-views.browserchannel.client :as rdv-browserchannel])) + [reagent-data-views.browserchannel.client :as rdv])) ;; Todo MVC - Reagent Implementation ;; @@ -34,7 +33,8 @@ ;; UI Components -(defn todo-input [{:keys [title on-save on-stop]}] +(defn todo-input + [{:keys [title on-save on-stop]}] (let [val (r/atom title) stop #(do (reset! val "") (if on-stop (on-stop))) @@ -53,7 +53,8 @@ (def todo-edit (with-meta todo-input {:component-did-mount #(.focus (r/dom-node %))})) -(defn todo-stats [{:keys [filt active done]}] +(defn todo-stats + [{:keys [filt active done]}] (let [props-for (fn [name] {:class (if (= name @filt) "selected") :on-click #(reset! filt name)})] @@ -68,7 +69,8 @@ [:button#clear-completed {:on-click clear-done} "Clear completed " done])])) -(defn todo-item [] +(defn todo-item + [] (let [editing (r/atom false)] (fn [{:keys [id done title]}] [:li {:class (str (if done "completed ") @@ -108,7 +110,8 @@ ;; NOTE: ;; view-cursor cannot be used in a Reagent component that was created using defn. -(defvc todo-app [props] +(defvc todo-app + [props] (let [filt (r/atom :all)] (fn [] (let [items (view-cursor :todos) @@ -144,12 +147,12 @@ ;; Some unfortunately necessary set up to ensure we send the CSRF token back with -;; AJAX requests (clj-browserchannel handles this automatically for it's own HTTP -;; requests, so the set up we do is only for our own application code). +;; AJAX requests -(defn get-anti-forgery-token [] - (if-let [tag (sel1 "meta[name='anti-forgery-token']")] - (.-content tag))) +(defn get-anti-forgery-token + [] + (if-let [hidden-field (.getElementById js/document "__anti-forgery-token")] + (.-value hidden-field))) (def csrf-interceptor (to-interceptor {:name "CSRF Interceptor" @@ -161,9 +164,10 @@ ;; Page load -(defn ^:export run [] +(defn ^:export run + [] ; Configure reagent-data-views and then BrowserChannel. - (rdv-browserchannel/configure!) + (rdv/configure!) ; NOTE: We are passing in an empty map for the BrowserChannel event handlers only ; because this todo app is not using BrowserChannel for any purpose other @@ -171,6 +175,6 @@ ; wanted to use it for client/server messaging in our application as well, ; we could pass in any event handlers we want here and it would not intefere ; with reagent-data-views. - (browserchannel/connect! {} {:middleware [rdv-browserchannel/middleware]}) + (browserchannel/connect! {} {:middleware [rdv/middleware]}) (r/render-component [todo-app] (.getElementById js/document "app"))) diff --git a/examples/todomvc/src/todomvc/server.clj b/examples/todomvc/src/todomvc/server.clj index 883b56e..ddca531 100644 --- a/examples/todomvc/src/todomvc/server.clj +++ b/examples/todomvc/src/todomvc/server.clj @@ -4,17 +4,18 @@ [compojure.core :refer [routes GET POST]] [compojure.route :as route] [ring.middleware.defaults :refer [wrap-defaults site-defaults]] - [ring.middleware.anti-forgery :refer [*anti-forgery-token*]] + [ring.util.anti-forgery :refer [anti-forgery-field]] [ring.util.response :refer [response]] [net.thegeez.browserchannel.server :refer [wrap-browserchannel]] [net.thegeez.browserchannel.immutant-async-adapter :refer [wrap-immutant-async-adapter]] [immutant.web :as immutant] - [clj-pebble.core :as pebble] + [hiccup.page :refer [html5 include-css include-js]] + [hiccup.element :refer [javascript-tag]] [environ.core :refer [env]] [clojure.java.jdbc :as jdbc] [views.sql.core :refer [vexec! with-view-transaction]] [views.sql.view :refer [view]] - [reagent-data-views.browserchannel.server :as rdv-browserchannel])) + [reagent-data-views.browserchannel.server :as rdv])) (def dev? (boolean (env :dev))) @@ -28,14 +29,8 @@ ;; View system atom ;; -;; We just declare it, don't need to fill it with anything. The call to views.core/init! -;; will handle initializing it (or reagent-data-views.browserchannel.server/init-views! -;; in this example app's case -- it works exactly the same and is a drop-in replacement -;; for views.core/init!) -;; -;; Depending on your exact needs, you can also opt to not pass in any atom to the init -;; call in which case one is created for you automatically. This may be more convenient -;; when using Component/Mount for example, but is entirely optional. +;; We just declare it, don't need to fill it with anything. The call below to +;; reagent-data-views.browserchannel.server/init-views! will take care of it. (defonce view-system (atom {})) @@ -54,7 +49,8 @@ ;; the actual SQL query and is followed by any number of parameters to be used in ;; the query. -(defn todos-list [] +(defn todos-list + [] ["SELECT id, title, done FROM todos ORDER BY title"]) @@ -83,19 +79,23 @@ ;; analyzes the SQL query being run and dispatches "hints" to the view system which ;; trigger view refrehses for all subscribers of the views that the hints match. -(defn add-todo! [title] +(defn add-todo! + [title] (vexec! view-system db ["INSERT INTO todos (title) VALUES (?)" title]) (response "ok")) -(defn delete-todo! [id] +(defn delete-todo! + [id] (vexec! view-system db ["DELETE FROM todos WHERE id = ?" id]) (response "ok")) -(defn update-todo! [id title] +(defn update-todo! + [id title] (vexec! view-system db ["UPDATE todos SET title = ? WHERE id = ?" title id]) (response "ok")) -(defn toggle-todo! [id] +(defn toggle-todo! + [id] ; note that a transaction is obviously not necessary here as we could have used ; just a single UPDATE query. however, it is being done this way to demonstrate ; using transactions with vexec!. @@ -106,16 +106,34 @@ (vexec! view-system dt ["UPDATE todos SET done = ? WHERE id = ?" (not done?) id])) (response "ok"))) -(defn mark-all! [done?] +(defn mark-all! + [done?] (vexec! view-system db ["UPDATE todos SET done = ?" done?]) (response "ok")) -(defn delete-all-done! [] +(defn delete-all-done! + [] (vexec! view-system db ["DELETE FROM todos WHERE done = true"]) (response "ok")) +;; main page html + +(defn render-page + [] + (html5 + [:head + [:title "todomvc with reagent"] + (include-css "todos.css" "todosanim.css") + (include-js "cljs/app.js")] + [:body + (anti-forgery-field) + [:div#app [:h1 "This will become todomvc when the ClojureScript is compiled"]] + (javascript-tag "todomvc.client.run();")])) + + + ;; Compojure routes and Ring handler (def app-routes @@ -129,44 +147,40 @@ (POST "/todos/delete-all-done" [] (delete-all-done!)) ; main page - (GET "/" [] (pebble/render-resource - "html/app.html" - {:dev dev? - :csrfToken *anti-forgery-token*})) + (GET "/" [] (render-page)) (route/resources "/") (route/not-found "not found"))) (def handler (-> app-routes - (wrap-defaults (assoc-in site-defaults [:security :anti-forgery] (not dev?))) + (wrap-defaults (assoc-in site-defaults [:security :anti-forgery] true #_(not dev?))) ; NOTE: We are passing in an empty map for the BrowserChannel event handlers only ; because this todo app is not using BrowserChannel for any purpose other ; then to provide client/server messaging for reagent-data-views. If we ; wanted to use it for client/server messaging in our application as well, ; we could pass in any event handlers we want here and it would not intefere ; with reagent-data-views. - (wrap-browserchannel {} {:middleware [(rdv-browserchannel/->middleware view-system)]}) + (wrap-browserchannel {} {:middleware [(rdv/->middleware view-system)]}) (wrap-immutant-async-adapter))) ;; Web server startup & main -(defn run-server [] - (pebble/set-options! :cache (not dev?)) - - ; init-views! takes care of initialization views and reagent-data-views at the same +(defn run-server + [] + ; init-views! takes care of initialization of views and reagent-data-views at the same ; time. As a result, we do not need to also call views.core/init! anywhere. The ; same arguments and options you are able to pass to views.core/init! can also be - ; passed in here and they will be forwarded along, as this function is a drop-in - ; replacement for views.core/init!. - ; + ; passed in here and they will be forwarded along, as this function is intended to be + ; a drop-in replacement for views.core/init!. ; if you need to shutdown the views system (e.g. if you're using something like ; Component or Mount), you can just call views.core/shutdown!. - (rdv-browserchannel/init-views! view-system {:views views}) + (rdv/init-views! view-system {:views views}) (immutant/run handler {:port 8080})) -(defn -main [& args] +(defn -main + [& args] (run-server))