Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

New clojurescript app stuff, bump to 0.5.0

* New syntax for clojurescript apps
* Update lein-template nsfw version
* Update lien-template to use new cs :entry config opt
  • Loading branch information...
commit 9642be05959f2f49458c0b2d4919ac9bae59dd43 1 parent 9d68a67
Zachary Kim authored
114 .notes.zk.org
View
@@ -850,4 +850,118 @@ Responsive design.
Box sizing: http://paulirish.com/2012/box-sizing-border-box-ftw/
+* 2013-03-04 Mon 18:13
+With routes, there should be some common setup, init routes which
+watches for changes on the hash and loads new content when the page
+changes.
+
+Challenges: How is global set up handled?
+
+The idea is:
+
+1. There's some common page setup, maybe initialization of query
+ services, polling, websockets connections, whatever. Stuff that's
+ common to the entire lifecycle of the app.
+
+2. There's per-route setup.
+
+
+Q: what's the right level of setup done by the initial page load / vs
+subsequent js 'page' changes. Should be as easy to make single page
+apps as it is to make more traditional 'dynamically enhanced' apps.
+
+What's this mean for routing? Seems like a lot of bookkeeping you have
+to do manually.
+
+I'm worried that the overhead of shipping an entire app in one js page
+might not be feasable, even with dead code removal.
+
+Maybe I should be opinionated here -- There's one backend route that
+ships the entire application, and all other routes are api routes.
+
+I'm pretty comfortable with that for now. Clojurescript app at
+root. What about the loader script?
+
+Since we put js tags in the body, the initial page load structure
+should ship the loading screen, then get wiped out as a first action
+by the javascript. So, we need to have a nice way of providing the
+loading screen. Let's look at that now. `webapp.cs` should default to
+a nice nsfw loading screen, with the ability to override.
+
+Ok, so now we're shipping a loading screen, but the jump is pretty
+jarring. Fade out / fade in? Also, if you're dynamically loading data
+in the background that's two jumps. Perhaps a way to signal that the
+initial UI is ready to be viewed?
+
+Meh, I'm on the fence on this. It's nice to have the animated
+transition, but it's clear that the transition should only happen on
+initial page load. Also, maybe it should only load if the :loading
+opt is set on `webapp/cs`. If this is the case, then we'll need to
+provide some page load helper. So what goes into page load?
+
++ Getting a handle on data injected into the page
++ Initial js transfer and load.
++ Initial background color for load
+
+Looks like we need to make some state available for the page. This
+feels good though, we're starting at the beginning.
+
+JHC just spent the last hour tracking down an Undefined Identifier
+error, no line number. Ended up being I was passing in something to
+util/timeout without wrapping it in a function first. AARRRGGGGHHH.
+
+Ok so it looks like loading is a non-issue, it dosen't seem like
+there's a reliable way to get some page content to load before the js
+anyway, so any HTML shipped wouldn't show anyway. It's important to
+keep the js as small as possible though, so that's something I'll have
+to make easy. Revised initial stuff below:
+
++ Initial background color for load
++ Getting a handle on data injected into the page
++ Initial js transfer and load.
+
+
+Order of ops
++ Request comes in
++ One route for the app
++ Load the
+
+
++ App Setup
+ + Clojurescript app
+ + Session storage
+ + entry ns
+ + route handling
+ + css
+ + extra js
+ + handles all traffic (push state)
+ + has the ability to pretty seriously break 404, as all your
+ routes will resolve as a 200 now. Perhaps can handle this with a
+ route whitelist, patterns of valid pages.
+ + API slug, everything there is handled by api routes
+
+
+
+** New clojurescript app syntax
+
+#+begin_src clojure
+
+(def routes
+ (app/clojurescript
+ :session-atom session-atom
+ :entry 'bigboard.app/entry
+ :css [:bootstrap.min :bootstrap-responsive.min :app]
+ :data (fn [r]
+ {:issues (take 10 @!gh-issues)
+ :user (when-let [gh-user (-> r :session :gh-user)] gh-user)})
+ :api (app/route
+ ["label-ac"] (label-ac !gh-issues !gh-labels)
+ ["issues" number] {:post (post-issue !gh-issues number)}
+ ["issues"] (fn [{:keys [params]}]
+ (let [{:keys [d t] :or {d 0 t 10}} params]
+ {:body (pr-str (->> @!gh-issues
+ (drop (nu/parse-int d))
+ (take (nu/parse-int t))))})))))
+
+#+end_src
14 README.md
View
@@ -4,6 +4,20 @@ Proving ground for library code.
[![Build Status](https://travis-ci.org/zkim/nsfw.png)](https://travis-ci.org/zkim/nsfw)
+## Usage
+
+`lein new nsfw <project name>`
+
+If you get:
+
+```bash
+Retrieving nsfw/lein-template/maven-metadata.xml (1k)
+ from http://clojars.org/repo/
+Could not find metadata nsfw:lein-template/maven-metadata.xml in central (http://repo1.maven.org/maven2)
+```
+
+Just `rm -rf ./<project dir>` and try again.
+
## License
Copyright (C) 2010-2012 Zachary Kim
12 bin/local-deploy
View
@@ -0,0 +1,12 @@
+#!/bin/bash
+
+SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+
+REPO=$SCRIPT_DIR/..
+
+cd $SCRIPT_DIR/.. && lein install
+
+
+REPO=$SCRIPT_DIR/../lein-template
+
+cd $REPO && lein install
6 lein-template/src/leiningen/new/nsfw.clj
View
@@ -16,6 +16,6 @@
["src/clj/{{sanitized}}/run.clj" (render "run.clj" data)]
["src/clj/{{sanitized}}/entry.clj" (render "entry.clj" data)]
["src/cljs/{{sanitized}}/app.cljs" (render "app.cljs" data)]
- ["src/sass/app.scss" (render "app.scss" data)]
- ["resources/public/css/bootstrap-responsive.min.css" (render "bootstrap-responsive.min.css" data)]
- ["resources/public/css/bootstrap.min.css" (render "bootstrap.min.css" data)])))
+ ["src/scss/app.scss" (render "app.scss" data)]
+ ["src/scss/nsfw.scss" (render "nsfw.scss" data)]
+ ["README.md" (render "README.md" data)])))
4 lein-template/src/leiningen/new/nsfw/Procfile
View
@@ -1,4 +1,4 @@
web: lein run -m {{name}}.run
-cljs: lein cljsbuild auto
-sass: sass --watch src/sass:resources/public/css
+cljs: lein cljsbuild auto dev
+sass: sass --watch src/scss:resources/public/css
refresher: lein run -m nsfw.refresher
18 lein-template/src/leiningen/new/nsfw/app.cljs
View
@@ -6,11 +6,13 @@
(def $body (dom/$ "body"))
-(dom/append
- $body
- [:div
- [:h1 "Hello {{name}}"]
- [:p
- "This file can be found at " [:code "src/cljs/{{sanitized}}/app.cljs"] ". "
- "Any changes to this file (and any other cljs files) will automatically be "
- "reloaded in your browser."]])
+(def $page
+ [:div
+ [:h1 "Hello {{name}}."]
+ [:p
+ "This file can be found at " [:code "src/cljs/{{sanitized}}/app.cljs"] ". "
+ "Any changes to this file (and any other cljs files) will automatically be "
+ "reloaded in your browser."]])
+
+(defn entry []
+ (dom/append $body $page))
4 lein-template/src/leiningen/new/nsfw/build
View
@@ -1,4 +1,4 @@
#!/bin/sh
-lein cljsbuild once
-lein with-profile production compile :all
+lein cljsbuild once prod
+lein with-profile production compile :all
21 lein-template/src/leiningen/new/nsfw/entry.clj
View
@@ -1,9 +1,16 @@
(ns {{name}}.entry
- (:require [nsfw.webapp :as webapp]))
+ (:require [nsfw.app :as app]))
-(def routes
- (webapp/routes
- [""] (webapp/cs :app
- :css [:bootstrap.min
- :bootstrap-responsive.min
- :app])))
+(defonce session (app/session-store :encrypted-cookie))
+
+(def app
+ (app/clojurescript
+ :entry '{{name}}.app/entry
+ :session-store session
+ :css [:nsfw :app]
+ :data (fn [r]
+ ;; Key / val pairs are embedded into the page as js vars
+ {:unique-value (str (gensym))})
+ :api (app/route
+ ;; Routes mounted at /api
+ ["name"] (fn [r] {:body (pr-str (rand))}))))
1  lein-template/src/leiningen/new/nsfw/nsfw.scss
View
17 lein-template/src/leiningen/new/nsfw/project.clj
View
@@ -2,12 +2,19 @@
:description "A Clojure web app using NSFW."
:min-lein-version "2"
:dependencies [[org.clojure/clojure "1.4.0"]
- [nsfw "0.4.3"]]
+ [nsfw "0.5.0"]]
:source-paths ["src/clj"]
:test-paths ["test/clj"]
:plugins [[lein-cljsbuild "0.2.10"]]
:cljsbuild {:builds
- [{:source-path "src/cljs"
- :compiler {:output-to "resources/public/js/app.js"
- :optimizations :whitespace}
- :jar true}]})
+ {:dev {:source-path "src/cljs"
+ :compiler {:output-to "resources/public/js/app.js"
+ :optimizations :whitespace
+ :pretty-print true}
+ :jar true}
+
+ :prod {:source-path "src/cljs"
+ :compiler {:output-to "resources/public/js/app.js"
+ :optimizations :advanced
+ :pretty-print false}
+ :jar true}}})
2  lein-template/src/leiningen/new/nsfw/run.clj
View
@@ -9,7 +9,7 @@
(repl/start-server :port port))
(def root-entry
- (-> #'entry/routes
+ (-> #'entry/app
(reload/wrap-reload-modified ["src/clj"])))
(defn -main [& args]
3  project.clj
View
@@ -1,4 +1,4 @@
-(defproject nsfw "0.4.4"
+(defproject nsfw "0.5.0"
:description "No Such Framework -- Experimental"
:dependencies [[org.clojure/clojure "1.4.0"]
[clj-stacktrace "0.2.5"]
@@ -21,6 +21,7 @@
:source-paths ["src/clj" "examples/clj"]
:test-paths ["test/clj"]
:jar-name "nsfw.jar"
+ :hooks [leiningen.cljsbuild]
:cljsbuild {:builds
[{:source-path "src/cljs"
:compiler {:output-to "resources/test.js"
2  site
@@ -1 +1 @@
-Subproject commit d67b170ab842d06023e2c45a929915fc194c84df
+Subproject commit 1c7390e4de7c0fc7bc122f1b03bd2616a2f9b2fc
15 src/clj/nsfw/app.clj
View
@@ -2,7 +2,8 @@
(:use [nsfw.util]
(ring.middleware file file-info resource params nested-params
keyword-params multipart-params session)
- [ring.middleware.session.memory :only (memory-store)])
+ [ring.middleware.session.memory :only (memory-store)]
+ [ring.middleware.session.cookie :only (cookie-store)])
(:require [net.cgrand.moustache :as moustache]
[nsfw.html :as html]
[nsfw.middleware :as nm]
@@ -56,6 +57,18 @@
[:script {:type "text/javascript"}
(str entry-js "()")])])})))
+(defn session-store
+ [type & rest]
+ (condp = type
+ :atom (if-not (empty? rest)
+ (memory-store (first rest))
+ (memory-store))
+
+ ;; encrypted cookie
+ (if-not (empty? rest)
+ (cookie-store (first rest))
+ (cookie-store))))
+
(defmacro route [& routes]
`(moustache/app ~@routes))
18 src/cljs/nsfw/console.cljs
View
@@ -117,3 +117,21 @@
(apply str))]
(render-result data)]))))))
$el))
+
+(defn on-cmd-space [el f]
+ (dom/keydown
+ js/document
+ (fn [{:keys [key-code meta-key ctrl-key] :as e}]
+ (when (and (= 32 key-code)
+ meta-key)
+ (f e)))))
+
+(defn panel []
+ (let [el (dom/$ [:div.console-panel "COMMAND PANEL"])
+ toggle (util/toggle
+ #(dom/style el {:display "block"})
+ #(dom/style el {:display "none"}))]
+ (on-cmd-space
+ el
+ toggle)
+ el))
10 src/cljs/nsfw/dom.cljs
View
@@ -343,7 +343,9 @@
(if-not so
(conj out fo)
(recur (rest os)
- (conj out (assoc fo :done (fn []
- ((or (:done fo) #()))
- (trans* el so))))))))]
- (trans* el (first os))))
+ (conj out (assoc fo
+ :done (fn []
+ ((or (:done fo) #()))
+ (trans* el so))))))))]
+ (trans* el (first os))
+ el))
Please sign in to comment.
Something went wrong with that request. Please try again.