Compojure Demystified with an example – Part 3
In part2 we saw how to setup a skeleton project with Compojure. In this part we will see how to add static files to a Compojure project.
For our application, we will use JQuery as front end and Clojure as a backend. I will concentrate more on Compojure.
1) Create folders for static files.
mkdir public mkdir public/css mkdir public/js
It is better to have static files under a seperate directory that way you could use your webserver to serve these files. For now we will use Compojure to serve these files.
2) Create index.html under public folder
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>My Address book</title>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.2/jquery.min.js"></script>
</head>
<body id="main">
<p>
My Address Book
</p>
<body>
</html>
3) Start your server
lein repl src/address_book/core.clj
4) Access index.html
Go to http://localhost:8080/index.html . You will get “Page not found” instead of “My Address Book”. This is happening because we have not told compojure about our static files folder.
Route helper functions in Compojure
In Compojure we have two route helper functions. We have seen one already in core.clj file.
1) not-found :
This function is used to capture all other routes that are not defined in Compojure. As we still have not defined index.html we got “Page not found”.
2) files :
This function is used to inform Compojure where static files are present.
Lets change our core.clj to handle static files
(ns address_book.core
(:use [compojure.core]
[ring.adapter.jetty])
(:require [compojure.route :as route]))
(defroutes example
(GET "/" [] "<h1>My Address Book!</h1>")
(route/files "/" {:root "public"})
(route/not-found "Page not found"))
(run-jetty example {:port 8080})
Restart your server (there is a way to avoid restarting using futures. I will show that in a later blog) and access http://localhost:8080/index.html . Now you should see “My Address Book”.
In this part we saw how we can handle static files. In next part we will implement Add , View and View All functionalities.
PS: Using Hiccup you can create HTML and css in clojure. I will try to cover this in future blogs.
Source code is now available at github . Created branches for each part.
Checkout PART4 …

Yes, very good tutorial, and I am translate it to chinese at http://www.javaeye.com, link: http://limux.javaeye.com/admin/blogs/742947, Would not you mind it?
Waiting the next…
Thanks.
limux
August 20, 2010 at 12:15 am
Sorry, The actual link is http://limux.javaeye.com/blog/742947
limux
August 20, 2010 at 12:17 am
That is great … please go ahead … I am working on next part ( it is kind of big one) so should be out in 1 or 2 days
Siva Jagadeesan
August 20, 2010 at 12:19 am
More compact way of creating multiple directories
mkdir -p public/{css,js}
.. and you might as well update to clojure 1.2
looking forward to the next part
klang
August 20, 2010 at 12:54 am
Thanks Klang.
Yah now that it is released I will update to 1.2
Siva Jagadeesan
August 20, 2010 at 1:34 am
Hi Siva
Great introduction to compojure, thanks a lot! I can’t wait for your next posts.
— Ben
Ben
August 21, 2010 at 6:46 am
Thanks Ben.
The next part should be out by this weekend.
– Siva Jagadeesan
Siva Jagadeesan
August 21, 2010 at 8:40 am
Hi Siva
Just a very quick note: I’ve been looking with a lot of interest to the Clojure HTML templating system called Enlive. It looks amazingly flexible. There a good introduction here: http://github.com/swannodette/enlive-tutorial
Hope this could help and inspire!
— Ben
Ben
August 24, 2010 at 12:47 am
I plan to refactor Siva’s next part to use enlive. The changes will be available on github. Let’s get a bit of social coding going here
Clojure, compojure, ring, enlive, hiccup .. everything is moving fast and many of the tutorials currently available simply woun’t work with the newest versions of the different libraries.
klang
August 24, 2010 at 1:17 am
Yah Klang. They are moving fast.
Yah go ahead and refactor my code to use enlive. I would like to contribute too.
Siva Jagadeesan
August 24, 2010 at 8:56 am
Hi klang, lovely, I would love to see that I must say I’m fairly excited with compojure and enlive too.
Please let us know about your work klang.
Siva, I hope you don’t mind I’ve translated your tutorial in French. The (temp) address is:
http://bao.maleloria.org/misc/compojure-demystifie.html
You’re fully credited of course. Actually I’ve a few questions for you Siva while translating your posts and that’s the topic of my first section: “TODO Questions”. The two main points being:
1. why do you have an address entry on the same level of the rest of the stuff? I guess what you meant was: an address is defined by: name, street1, street2, etc.
2. I would suggest to switch to Clojure 1.2 as the new release is now out. What would you say about that? do the dependencies work correctly?
Kind regards,
— Ben
Ben
August 24, 2010 at 2:47 am
Hi Ben:
Go ahead … the more people this tutorial reaches the better it is.
Address being in same level as other fields is a formatting issue. Thanks for pointing out I will fix it.
Siva Jagadeesan
August 24, 2010 at 8:58 am
oops my bad, your source already contains:
:dependencies [[org.clojure/clojure "1.2.0"]
Thanks Siva!
Ben
August 24, 2010 at 3:11 am
No problem.
I am working on next part. It is taking more time than I expected. Sorry for the wait
Siva Jagadeesan
August 24, 2010 at 8:58 am
Hey since you’ve now posted part 4, you should add a link to it here on part 3! Thanks for writing this!
Jeremy
August 27, 2010 at 2:26 am
Jeremy, I added a link pointing to Part 4
Siva Jagadeesan
August 27, 2010 at 9:02 am
please indicate where to create the “public” subfolder: in the project folder, at the same level as the “src” and “lib”
zmila
September 20, 2010 at 3:21 am
yah same level as src and lib folders.
Siva Jagadeesan
September 20, 2010 at 10:41 am
Stands back from the keyboard in amaemzent! Thanks!
Kristabelle
April 15, 2011 at 11:13 pm