Nando @ Aria Media

( learning Clojure ColdFusion Lucee Javascript jQuery Angular CSS Linux Apache HTML5 & etc )

First Steps With the Clojure Version of FW/1

| Comments

Sean Corfield has built a Clojure version of the popular CFML framework FW/1. I’ve been using FW/1 for a number of years, so I thought it might help me learn Clojure to begin developing an app in fw1-clj.

The first step to get up and running is to head on over to the fw1-clj GitHub repository and follow the directions to install Boot, which is a build tool for Clojure. Next, as per the instructions on the fw1-clj GitHub repository, we run a boot command in a terminal to create a new fw1-clj app, which currently looks like this:

1
boot -d seancorfield/boot-new new -t fw1 -n myfw1app

(Sean has indicated this invocation may change in the future, so best to follow the fw1-clj repository instructions.)

Then, we “cd” into the application directory we specified above, in this example “myfw1app”, and start the application up like so:

1
2
cd myfw1app
PORT=8111 boot run

Specifying the PORT variable isn’t required, but may be necessary to avoid conflicts. If omitted, the default port is 8080.

Navigating to localhost:8111, we see a lovely default page that says “Framework One - Welcome to FW/1”. Yay! It certainly is impressive how easy that is. No server to install. Nothing to download. No settings to find and configure. We’re ready to start developing.

There are several options to choose from in terms of an IDE for Clojure. Many experienced Clojure developers use Emacs with CIDER, or the Cursive plugin for Intellij. Both of those have a learning curve that you may prefer to avoid to focus on getting the basics of Clojure down first.

For beginners, good IDE’s for experimentation are Light Table or Atom with a few Clojure packages installed, such as language-clojure, proto-repl and parinfer. I’m using Atom at the moment because I’m also using it for CFML development, and also because the Clojure packages seem to work very well.

One of the first things I wanted to figure out was how to visualize the rc map (or struct as it would be known in CFML). With a tip from Sean, I navigated to src/projectName/controllers/main.clj in the project that boot generated for me, and within the default function definition, I added (println rc)

1
2
3
(defn default "/main/default handler" [rc]
  (println rc)
  rc)

reloaded the app in the browser, and then checked the terminal window where I had started the app with the boot command for the output. Nothing was output there. After a moment, I remembered that I probably had to reload the application to get the changes picked up. Checking the somewhat sparse documentation on the Github page, I found the default reload query string would be “?reload=secret”. Hitting localhost:8111?reload=secret in the browser then generated the rc map in my terminal window - all in one very long line. After another suggestion from Sean, I replaced the print line function (println rc) with the clojure pretty print function (clojure.pprint/pprint rc)

1
2
3
(defn default "/main/default handler" [rc]
  (clojure.pprint/pprint rc)
  rc)

hit localhost:8111?reload=secret again, and now the keys within the rc map were nicely separated by line breaks in the terminal output. Much more readable that way.

I noticed within the output that the :reload-application-on-every-request key was set to false. Better in development to have that set to true, so reading the docs, I found “the call to (fw1/start) can be passed configuration parameters either as a map or as an arbitrary number of inline key / value pairs”

Ok, so opening src/projectName/main.clj, I found the call to (fw1/start) and changed it from

1
2
3
4
(defn -main []
  (let [port (Integer/parseInt (get (System/getenv) "PORT" "8080"))]
    (run-jetty (fw1/start :application-key "easycalclj")
               {:port port})))

to

1
2
3
4
(defn -main []
  (let [port (Integer/parseInt (get (System/getenv) "PORT" "8080"))]
    (run-jetty (fw1/start :application-key "easycalclj" :reload-application-on-every-request "true")
               {:port port})))

Then I reloaded the app with “?reload=secret”, and the rc output for :reload-application-on-every-request didn’t change. Hmmm …

After a bit of investigation, (I asked Sean again on Slack), I found that to reload changes to the configuration params, I needed to go to the terminal window where I started the app with boot run, shut the app down with control-c, and then start it up again with PORT=8111 boot run.

Checking the rc output in the console again, I saw that :reload-application-on-every-request was now true!

These were all small baby steps, but unless I take them, I won’t learn.

Comments