This post is part of the Web Application Development with Clojure tutorial. You might want to read the previous posts before this post for continuity’s sake.

Introduction

In the previous part of this tutorial we created a couple of tables using migrations – authors table and posts table. In this part first I’ll describe how to load some test data (a.k.a ‘fixtures‘) into our database tables. We’ll use YAML to define a couple of authors and 3 blog posts and we’ll parse the YAML file and load the data using the clj-yaml library.

Also we’ll create our first template and render the blog’s home page with the sample data from the database.

Source code on github

The code for this series is now available on github and the source code is tagged with part names. If you want to checkout the code for a specific part of this tutorial you can do so using the following command:

git clone git://github.com/vijaykiran/clog.git cd clog git checkout part3 1 2 3 git clone git : / / github .com / vijaykiran / clog .git cd clog git checkout part3

[grey_box]

A quick note for PostgreSQL users: In the previous while creating the tables using migrations, I overlooked and made a mistake in naming the tables. If you are using PostgreSQL then the word “user” is a reserved word, so you should rename the table to authors – I’ve updated the code accordingly.

[/grey_box]

Loading Fixtures

Fixtures are used to populate the database with some initial data. Though fixtures are mostly used for loading test data we can also use fixtures to bootstrap the content. First let us create a file called fixtures.yml under resources folder. If you don’t have a resources folder in your project, create it under the root directory so that will be at the same level as src folder. Edit the fixtures.yml and add the following:

[yellow_box]Pay attention to the formatting of the text in a YAML file, otherwise you might get exceptions during parsing.[/yellow_box]

authors: - id: 1 username: "john" password: "clojure-blogger" email: "john@clojure-blog.org" - id: 2 username: "jane" password: "clojure-blogher" email: "jane@clojure-blog.org" posts: - title: "Hello World!" text: "<em>Welcome to Clog, the World's most advanced Clojure Blog Engine!</em>" status: true author: 1 - title: "Hello World!, again!" text: "Sayin 't 'gain! <em>Welcome to Clog, the World's most advanced Clojure Blog Engine!</em>" status: true author: 2 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 authors : - id : 1 username : "john" password : "clojure-blogger" email : "john@clojure-blog.org" - id : 2 username : "jane" password : "clojure-blogher" email : "jane@clojure-blog.org" posts : - title : "Hello World!" text : "<em>Welcome to Clog, the World's most advanced Clojure Blog Engine!</em>" status : true author : 1 - title : "Hello World!, again!" text : "Sayin 't 'gain! <em>Welcome to Clog, the World's most advanced Clojure Blog Engine!</em>" status : true author : 2

[white_box]Check out part 1, if you want to refresh your memory on how to setup IntelliJ IDE[/white_box]

Now, fire up the Clojure REPL in IntelliJ IDE using Tools -> Start Clojure Console. We’ll load the clj-yaml library and parse the yaml file.

;; load clj-yaml (use 'clj-yaml.core) (parse-string (slurp "./resources/fixtures.yml")) 1 2 3 ;; load clj-yaml ( use ' clj-yaml . core ) ( parse-string ( slurp "./resources/fixtures.yml" ) )

If everything went well, you should see the map with keys :authors and :posts in the console as shown below:

{:authors ({:id 1, :username "john", :password "clojure-blogger", :email "john@clojure-blog.org"} {:id 2, :username "jane", :password "clojure-blogher", :email "jane@clojure-blog.org"}), :posts ({:title "Hello World!", :text "<i>Welcome to Clog, the World's most advanced Clojure Blog Engine!</i>", :status true, :author 1} {:title "Hello World!, again!", :text "Sayin 't 'gain! <i>Welcome to Clog, the World's most advanced Clojure Blog Engine!</i>", :status true, :author 2})} 1 2 3 4 5 6 7 8 9 10 { : authors ( { : id 1 , : username "john" , : password "clojure-blogger" , : email "john@clojure-blog.org" } { : id 2 , : username "jane" , : password "clojure-blogher" , : email "jane@clojure-blog.org" } ) , : posts ( { : title "Hello World!" , : text "<i>Welcome to Clog, the World's most advanced Clojure Blog Engine!</i>" , : status true , : author 1 } { : title "Hello World!, again!" , : text "Sayin 't 'gain! <i>Welcome to Clog, the World's most advanced Clojure Blog Engine!</i>" , : status true , : author 2 } ) }

Now to add the authors to the database all you need is the following couple of lines:

As you can see, you don’t need to write the code in a file, compile, redeploy and refresh to modify your program. All you need is a REPL which you use to build your program bottom-up – one little function at a time.

;;load korma library and models (use 'korma.db 'korma.core 'clog.models) (insert authors (values (:authors (parse-string (slurp "./resources/fixtures.yml"))))) 1 2 3 ;;load korma library and models ( use ' korma . db ' korma . core ' clog . models ) ( insert authors ( values ( : authors ( parse-string ( slurp "./resources/fixtures.yml" ) ) ) ) )

The second line in the above code snippet reads the fixtures file using slurp, parses the yaml using parse-string which returns a map with keys :authors and :posts. We use clojure’s maps-as-functions-of-keys features to get the list of authors and pass them to Korma’s insert function. Once this is executed you can see the data is now inserted into the Users table.

In a real-world-application you never use password, but instead you will probably store some encrypted hash. I’ll leave that as an exercise to the reader (not the clojure reader!).

(select authors) ;;output [{:id 1, :username "john", :password "clojure-blogger", :email "john@clojure-blog.org"} {:id 2, :username "jane", :password "clojure-blogher", :email "jane@clojure-blog.org"}] (select posts) .... 1 2 3 4 5 6 ( select authors ) ;;output [ { : id 1 , : username "john" , : password "clojure-blogger" , : email "john@clojure-blog.org" } { : id 2 , : username "jane" , : password "clojure-blogher" , : email "jane@clojure-blog.org" } ] ( select posts ) . . . .

Templates using Enlive

Now that we have our sample data populated in the database, it is time to get started with our first template. Clojure has a couple of libraries that can help you with dealing with HTML viz, Hiccup and Enlive. Hiccup is a DSL for generating HTML and Enlive is a selector based templating engine. I’m a bit biased towards Enlive – since I have more freedom of styling and HTML stays HTML. So in this tutorial I’m using Enlive.

Defining Home Page Template

Enlive provides a macro called deftemplate to define template functions. The macro is defined as follows:

(defmacro deftemplate "Defines a template as a function that returns a seq of strings." [name source args & forms] `(def ~name (template ~source ~args ~@forms))) 1 2 3 4 ( defmacro deftemplate "Defines a template as a function that returns a seq of strings." [ name source args & amp ; forms] ` ( def ~ name ( template ~ source ~ args ~ @ forms ) ) )

The forms you pass in are actually used to transform the html. I think it will be easier to understand with an example that you can follow along. First let us create the home.html under resources folder. By convention the templates are loaded from the resources directory.

Title Here Clog - Home Page! 1 2 3 Title Here Clog - Home Page !

We will place all our template definitions in clog.templates namespace which lives in cleverly named templates.clj

(ns clog.templates (:use [net.cgrand.enlive-html])) (deftemplate home-page "home.html" [] [:title] (content "Clog - the clojure blog engine!")) 1 2 3 4 5 ( ns clog . templates ( : use [ net . cgrand . enlive-html ] ) ) ( deftemplate home-page "home.html" [ ] [ : title ] ( content "Clog - the clojure blog engine!" ) )

In the above snippet we are using deftemplate macro to create a template function called home-page which takes the file home.html and transforms the file using the forms, in our case only one which is:

[:title] (content "Clog - the clojure blog engine!") 1 [ : title ] ( content "Clog - the clojure blog engine!" )

This says find out the tag :title in the home.html and replace its contents with “Clog – the clojure blog engine!”. To test this out you can load the namespace in repl and run the home-page function. That will print out the transformed template as shown below.

(use 'clog.templates) nil user=> (home-page) ("n" "" "n" "" "n " "" "Clog - the clojure blog engine!" "" "n" "" "n" "nClog - Home Page!n" "nnn" "") 1 2 3 4 ( use ' clog . templates ) nil user =& gt ; (home-page) ( "n" "" "n" "" "n " "" "Clog - the clojure blog engine!" "" "n" "" "n" "nClog - Home Page!n" "nnn" "" )

Now this template function can be used to generate the transformed html we need to send to the client. To connect the these views to the requests, we will use simple controller functions. These functions/handlers are then used to transform the templates using the request parameter and data from the database. For example we want our blog to respond to something like http://host:port/posts/1 by sending out the html for the post with id 1. This logic is wrapped inside a controller function.

A simple Controller

We’ll put our controller functions in the clog.controller namespace. Here’s the initial version of the controller which has handler for the index page.

(ns clog.controller (:use clog.templates clog.models ring.util.response)) (defn index "Index page handler" [req] (->> (home-page) response)) ;; A sexier way to write (response (home-page)) 1 2 3 4 5 6 7 8 9 ( ns clog . controller ( : use clog . templates clog . models ring . util . response ) ) ( defn index "Index page handler" [ req ] ( - & gt ;> (home-page) response)) ;; A sexier way to write (response (home-page))

Now to see this function in action, we need to update the routes of the application in core.clj to call clog.controller/index. Here’s the complete core.clj after the required modifications:

Notice that delegate call in routes ? This is due to small gotcha in mustache route syntax. We can’t use the function directly as the handler, since we want the parameters of the handler, in our case ‘req’ to be passed to function. So we use delegate to pass the request as the first argument.

(ns clog.core (:use ring.adapter.jetty ring.middleware.resource ring.middleware.reload ring.util.response net.cgrand.moustache clog.controller)) ;; Routes definition (def routes (app [""] (delegate index))) ;;; start function for starting jetty (defn start [port] (run-jetty #'routes {:port (or port 8080) :join? false})) (defn -main [] (let [port (Integer/parseInt (System/getenv "PORT"))] (start port))) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 ( ns clog . core ( : use ring . adapter . jetty ring . middleware . resource ring . middleware . reload ring . util . response net . cgrand . moustache clog . controller ) ) ;; Routes definition ( def routes ( app [ "" ] ( delegate index ) ) ) ;;; start function for starting jetty ( defn start [ port ] ( run-jetty # ' routes { : port ( or port 8080 ) : join ? false } ) ) ( defn -main [ ] ( let [ port ( Integer / parseInt ( System / getenv "PORT" ) ) ] ( start port ) ) )

Start the server as shown below, and you should see the home page with title in the window title bar “Clog – the clojure blog engine!”.

(use 'clog.core) (start 9000) 1 2 ( use ' clog . core ) ( start 9000 )

List of Posts

The home is working, but it is rather boring and doesn’t show any real data. Let us try to show the two posts we added in the database. First we need to update the home.html to create a place holder for a post.

Title Here 1 Title Here

Title of the Post Post Content

Now let us update the template and add another transformation. In this case we want to “clone” the div with class post and replace the content of divs with classes title and content. Here’s the updated deftemplate’s code that does exactly the same. We are using clone-for macro and using the forms to transform the sub elements.

(deftemplate home-page "home.html" [posts] [:title] (content "Clog - the clojure blog engine!") [:div.post] (clone-for [post posts] [:div.title] (content (:title post)) [:div.content (content (:content post))])) 1 2 3 4 5 ( deftemplate home-page "home.html" [ posts ] [ : title ] ( content "Clog - the clojure blog engine!" ) [ : div . post ] ( clone-for [ post posts ] [ : div . title ] ( content ( : title post ) ) [ : div . content ( content ( : content post ) ) ] ) )

Now we need to make sure that our controller function sends the required data to the template.

(ns clog.controller (:use clog.templates clog.models ring.util.response korma.core)) (defn index "Index page handler" [req] (->> (select posts) home-page response)) ;; Equivalent to (response (home-page (select posts)) 1 2 3 4 5 6 7 8 9 10 ( ns clog . controller ( : use clog . templates clog . models ring . util . response korma . core ) ) ( defn index "Index page handler" [ req ] ( - & gt ;> (select posts) home-page response)) ;; Equivalent to (response (home-page (select posts))

We are selecting all the posts using Korma select function and passing it on to home-page function. The result of the home-page template function – which is the html with posts populated is passed on to response.

After making these changes, you should see the list of posts in the home page.

Don’t worry about styling of the page, we’ll add a pretty CSS in the next part of the tutorial.

Conclusion

In this part we saw how to glue things together and get the content from database, render it in a page using templates. In the next part we’ll finish by updating the home template and adding another template to display the post. Also, in the next part we’ll start working in creating an admin area with authentication.

Make sure you subscribe to the RSS feed or follow me on Twitter to get notified.