Skip to content

Commit

Permalink
Introduce ClojureScript
Browse files Browse the repository at this point in the history
- Enable figwheel-main for client development
- Figwheel will now watch mango.css for changes, speeding up styling
  development
- Remove build/minification process and dependency on asset
  minification plugin
- Remove unnecessary lein plugin "shell"
- Delete mango.js and begin to replace it with ClojureScript
- Port (pretty much directly) the file uploading JavaScript with
  ClojureScript and handle multiple file upload
- Update README
  • Loading branch information
Lee Adams authored and Lee Adams committed Jul 17, 2019
1 parent 5368dda commit d5ff6d3
Show file tree
Hide file tree
Showing 19 changed files with 277 additions and 153 deletions.
9 changes: 5 additions & 4 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
/target
/classes
/checkouts
/resources/public/cljs-out
/resources/public/js/cljs-out-prod
/resources/public/js/*.js
pom.xml
pom.xml.asc
*.jar
Expand All @@ -9,9 +12,7 @@ pom.xml.asc
/.nrepl-port
.hgignore
.hg/
/resources/public/js/mango*.js
/resources/public/css/mango*.css
/dev-resources/js/mango*.min.js
/dev-resources/css/mango*.min.css
/src/version.clj
/scripts/tunnel.sh
figwheel_server.log
/scripts/tunnel.sh
73 changes: 69 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
# mango

```
__ ___
/ |/ /___ _____ ____ _____
/ /|_/ / __ `/ __ \/ __ `/ __ \
/ / / / /_/ / / / / /_/ / /_/ /
/_/ /_/\__,_/_/ /_/\__, /\____/
/____/
```

A blog written in Clojure for learning Clojure... and blogging.

## To Cut a Version
Expand All @@ -8,21 +17,77 @@ A blog written in Clojure for learning Clojure... and blogging.
## Configuring
You can configure three profiles: `dev`, `test`, and `prod`. Each profile can have separate urls, databases, and other fields configured to isolate them from each other.

### Database
### config.edn
Each profile, `dev`, `test`, and `prod` can be configured by editing its corresponding `config.edn` file:

```
{
:db-name "blog"
:db-article-collection "articles"
:db-page-collection "pages"
:db-media-collection "media"
:db-users-collection "users"
:site-url "http://localhost"
:site-title "My Mango Site"
:site-description "A site I made with mango"
:site-copyright "My copyright message"
:twitter-site-handle "{your twitter handle}"
:twitter-creator-handle "{your twitter handle}"
:admin-email "your-email@your-domain.com"
:port 8080
:logo-url "https://s3-us-west-1.amazonaws.com/{your bucket}/logo.png"
:aws-media-bucket "{your bucket}"
:aws-region "us-west-1"
:cdn-url "https://s3-us-west-1.amazonaws.com/{your bucket}/blog/"
:app-css "/css/mango.css"
:app-js "/cljs-out/dev-main.js"}
```

#### CDN / Media Storage
You'll need to supply your Amazon credentials and S3 bucket

#### Database
Mango is currently strictly tied to mongoDB and you must have an instance running that you can connect to.

## Developing
Running locally for development: `$ lein with-profile dev run`.
Running locally for development:

### Server
Run the server from the command line with `$ lein with-profile dev run`. If you're only developing the back end you can stop here and simply open a browser window to the url of your server (http://localhost:8080 by default).

### Client
In order to develop the front end with [clojurescript](https://clojurescript.org), you can fire up [figwheel](https://figwheel.org) and have all the interactive development (REPL, live code reloading, etc) you could wish for.

You can run the client code with figwheel watching for live updates with `$ lein fig`. If you want to use the command line REPL you can use `$ lein fig-repl`

I use the CIDER REPL from [Emacs](https://www.gnu.org/s/emacs).

The `dev.cljs.edn` file configures the development build and figwheel-main to connect to the running server above:

```
^{:open-url "http://localhost:8080"}
{:main mango.core}
```
To start CIDER:

- `M-x cider-jack-in-cljs`
- When asked what type of ClojureScript REPL to start, choose `figwheel-main`
- When asked the name of the build choose `dev`. NOT `:dev` and NOT the default!

The REPL will eventually come up, and load the server url above. Happy hacking!

## Testing
- To run the default tests: `$ lein test`
- To run integration tests (requires database connection): `$ lein test :integration`

## Deploying / Hosting
For now I just build an uberjar and run it on an instance somewhere: `$ lein with-profile prod uberjar`
Run `$ lein build-server-uberjar` and deploy the resulting `mango-{version}-standalone.jar` file. I just `scp` it to my Amazon EC2 instance and run it with `$ java -jar mango-{version}-standalone.jar`.

## Changelog
**v0.1**
2019/07/16

* Integrate figwheel-main for developing the front end in clojurescript

2019/02/19

* First commit in prep for open source. Hope all my secrets are scrubbed!
Expand Down
4 changes: 3 additions & 1 deletion config/dev/config.edn
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,6 @@
:logo-url "https://s3-us-west-1.amazonaws.com/dev-mango-media/logo.png"
:aws-media-bucket "dev-mango-media"
:aws-region "us-west-1"
:cdn-url "https://s3-us-west-1.amazonaws.com/dev-mango-media/blog/"}
:cdn-url "https://s3-us-west-1.amazonaws.com/dev-mango-media/blog/"
:app-css "/css/mango.css"
:app-js "/js/dev-main.js"}
6 changes: 4 additions & 2 deletions config/prod/config.edn
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
:admin-email ""
:port 8080
:logo-url ""
:aws-media-bucket "prod-media"
:aws-media-bucket "prod-mango-media"
:aws-region "us-west-1"
:cdn-url "https://s3-us-west-1.amazonaws.com/prod-media/blog/"}
:cdn-url "https://s3-us-west-1.amazonaws.com/prod-mango-media/blog/"
:app-css "/css/mango.css"
:app-js "/js/prod-main.js"}
20 changes: 0 additions & 20 deletions dev-resources/js/mango.js

This file was deleted.

13 changes: 13 additions & 0 deletions dev.cljs.edn
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
^{:open-url "http://localhost:8080"}
^{:css-dirs ["resources/public/css"]}
{:main mango.core
:asset-path "/cljs-out"
:output-to "resources/public/js/dev-main.js"
:output-dir "resources/public/cljs-out"
:source-map true
:source-map-timestamp true
:infer-externs true
:closure-warnings {:externs-validation :off}
;; To console.log CLJS data-structures make sure you enable devtools in Chrome
;; https://github.com/binaryage/cljs-devtools
:preloads [devtools.preload]}
6 changes: 6 additions & 0 deletions prod.cljs.edn
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
^{:open-url "http://localhost:8080"}
{:main mango.core
:output-to "resources/public/js/prod-main.js"
:infer-externs true
:closure-warnings {:externs-validation :off}
:optimizations :whitespace}
36 changes: 23 additions & 13 deletions project.clj
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
:dependencies [[org.clojure/clojure "1.9.0"]
[org.clojure/data.json "0.2.6"]
[org.clojure/core.incubator "0.1.4"]
[org.clojure/clojurescript "1.10.339"]
[com.bhauman/figwheel-main "0.2.0"]
[environ "1.1.0"]
[com.novemberain/monger "3.1.0"]
[ring/ring-core "1.6.3"]
Expand All @@ -20,25 +22,33 @@
[amazonica "0.3.76"]
[yogthos/config "1.1.4"]
[com.taoensso/timbre "4.10.0"]]
:plugins [[lein-asset-minifier "0.4.4"]
[com.roomkey/lein-v "6.2.2"]
[lein-shell "0.5.0"]]
:minify-assets [[:css {:source "dev-resources/css/mango.css" :target "dev-resources/css/mango.min.css"}]
[:js {:source "dev-resources/js/mango.js" :target "dev-resources/js/mango.min.js" :opts {:optimization :none}}]]
:plugins [[com.roomkey/lein-v "6.2.2"]]

:profiles {
:dev {:resource-paths ["config/dev"]}
:prod {:resource-paths ["config/prod"]}
:test {:resource-paths ["config/test"]}
:dev {:dependencies [[org.clojure/clojurescript "1.10.339"]
[com.bhauman/figwheel-main "0.2.0"]]
:resource-paths ["config/dev"]
:clean-targets ^{:protect false} ["target"
"resources/public/js/prod-main.js"]}
:prod {:resource-paths ["config/prod"]
:clean-targets ^{:protect false} ["target"
"resources/public/cljs-out"
"resources/public/js/dev-main.js"]}
:test {:resource-paths ["config/test"]
:clean-targets ["target"]}
:uberjar {:aot :all}
:repl {:init-ns mango.core
:init (use 'mango.core :reload)}
}

:aliases {"fig" ["trampoline" "run" "-m" "figwheel.main" "-b" "dev"]
"fig-repl" ["trampoline" "run" "-m" "figwheel.main" "-b" "dev" "-r"]
"build-dev-client" ["trampoline" "run" "-m" "figwheel.main" "-bo" "dev"]
"build-prod-client" ["trampoline" "run" "-m" "figwheel.main" "-bo" "prod"]
"build-dev-server" ["with-profile" "dev" "uberjar"]
"build-prod-uberjar" ["with-profile" "prod" "uberjar"]}

:prep-tasks [["v" "cache" "src"]
["minify-assets"]
["shell" "rm" "-f" "resources/public/js/mango-*.js"]
["shell" "cp" "dev-resources/js/mango.min.js" "resources/public/js/mango-${:version}.min.js"]
["shell" "rm" "-f" "resources/public/css/mango-*.css"]
["shell" "cp" "dev-resources/css/mango.min.css" "resources/public/css/mango-${:version}.min.css"]
"javac" "compile"]
:release-tasks [["vcs" "assert-committed"]
["v" "update"]]
Expand Down
File renamed without changes.
File renamed without changes.
18 changes: 0 additions & 18 deletions resources/public/js/media-edit.js

This file was deleted.

44 changes: 0 additions & 44 deletions resources/public/js/upload.js

This file was deleted.

4 changes: 2 additions & 2 deletions src/mango/config.clj
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@
:endpoint (:aws-endpoint env)})
(def aws-media-bucket (:aws-media-bucket env))
(def aws-media-bucket-region (:aws-region env))
(def app-js (str "js/mango-" version/version ".min.js"))
(def app-css (str "css/mango-" version/version ".min.css"))
(def app-js (or (:app-js env) (str "js/mango-" version/version ".min.js")))
(def app-css (or (:app-css env) "/css/mango.css"))
(def ads-enabled (:ads-enabled env))
(def google-analytics-id (:google-analytics-id env))
74 changes: 74 additions & 0 deletions src/mango/core.cljs
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
(ns ^:figwheel-hooks mango.core
(:require [mango.media] [mango.xhr]))

(enable-console-print!)
;(set! *warn-on-infer* true)

(println " __ ___
/ |/ /___ _____ ____ _____
/ /|_/ / __ `/ __ \\/ __ `/ __ \\
/ / / / /_/ / / / / /_/ / /_/ /
/_/ /_/\\__,_/_/ /_/\\__, /\\____/
/____/ v1.0")

;; Initialize Twitter Widgets
(let [fjs (first (array-seq (.getElementsByTagName js/document "script")))
t (or (.-twttr js/window) (js-obj))]
(if-not (.getElementById js/document "twitter-wjs")
(let [s (.createElement js/document "script")]
(set! (.-id s) "twitter-wjs")
(set! (.-src s) "https://platform.twitter.com/widgets.js")
(.insertBefore (.-parentNode fjs) s fjs)
(set! (.-_e t) #js [])
(set! (.-ready (fn [f] (.push (.-_e t) f))))
t)))

;; Highlight code blocks
(.initHighlightingOnLoad js/hljs)

(defn bind-upload-form
[upload-form]
(println "Binding upload form")
(let [file-select (.getElementById js/document "file-select")
upload-status (.getElementById js/document "upload-status")
anti-forgery (.getElementById js/document "anti-forgery-token")
article-id (.getElementById js/document "article-id")
file-upload (.getElementById js/document "file-upload")]
(set! (.-onsubmit upload-form) (fn [event]
(.preventDefault event)
(set! (.-value file-upload) "Uploading...")
(set! (.-innerHTML upload-status) "Uploading...")
(let [form-data (js/FormData.)]
(.append form-data "__anti-forgery-token" (.-value anti-forgery))
(.append form-data "article-id" (.-value article-id))
(doseq [file (array-seq (.-files file-select))]
(.append form-data "files[]" file (.-name file)))
(mango.xhr/send (.-method upload-form)
(.-action upload-form)
form-data
(fn [status message] (set! (.-innerHTML upload-status) message) (set! (.-value file-upload) "Upload"))
(fn [event] (set! (.-innerHTML upload-status) (.-loaded event)))))))))

(defn unbind-upload-form
[upload-form]
(set! (.-onsubmit upload-form) nil))

(defn bind
[]
(when-let [upload-form (.getElementById js/document "upload-form")]
(bind-upload-form upload-form)))

(defn unbind
[]
(when-let [upload-form (.getElementById js/document "upload-form")]
(unbind-upload-form upload-form)))

(.addEventListener js/window "DOMContentLoaded" bind)

(defn ^:after-load setup []
(println "setup")
(bind))

(defn ^:before-load teardown []
(println "teardown")
(unbind))
Loading

0 comments on commit d5ff6d3

Please sign in to comment.