wget https://raw.github.com/technomancy/leiningen/preview/bin/lein
lein self-install
lein plugin install lein-noir 1.2.1
lein noir new guestbook
cd guestbook
#Add dependencies
edit project.clj
and add jdbc dependencies
(defproject guestbook "0.1.0-SNAPSHOT"
:description "FIXME: write this!"
:dependencies [[org.clojure/clojure "1.3.0"]
[org.clojure/java.jdbc "0.2.3"]
[org.xerial/sqlite-jdbc "3.7.2"]
[noir "1.2.1"]]
:main guestbook.server)
run the project
lein run
update common namespace with our layout
(ns guestbook.views.common
(:use [noir.core :only [defpartial]]
[hiccup.page-helpers :only [include-css html5]]))
(defpartial layout [& content]
(html5
[:head
[:title "guestbook"]
(include-css "/css/reset.css")]
[:body
[:section#wrapper content]
[:footer#footer "My awesome guestbook"]]))
add the main page to welcome namespace
(ns guestbook.views.welcome
(:require [guestbook.views.common :as common]
[noir.content.getting-started]
[guestbook.models.db :as db])
(:use noir.core hiccup.core hiccup.form-helpers))
(defn show-guests []
(into [:ul.guests]
(for [{:keys [message name timestamp]} (db/read-guests)]
[:li
[:blockquote message]
[:p "-" [:cite name]]
[:time timestamp]])))
(defpage "/" {:keys [name message error]}
(common/layout
[:h1 "Guestbook"]
[:p "Welcome to my guestbook!"]
[:p error]
(show-guests)
[:hr]
(form-to [:post "/"]
[:p "Name:" (text-field "name" name)]
[:p "Message:" (text-area {:rows 10 :cols 40} "message" message)]
(submit-button "comment"))))
(defn error [params error]
(assoc params :error error))
(defpage [:post "/"] params
(cond
(empty? (:name params )) (render "/" (error params "Some dummy who forgot to leave a name"))
(empty? (:message params )) (render "/" (error params "WOW THIS IS THE BEST WEBSITE EVER"))
:else
(do
(db/save-message params)
(render "/"))))
create the database handler
(ns guestbook.models.db
(:require [clojure.java.jdbc :as sql])
(:import java.sql.DriverManager))
(def db {:classname "org.sqlite.JDBC",
:subprotocol "sqlite",
:subname "db.sq3"})
(defn create-table []
(sql/with-connection
db
(sql/create-table
:guestbook
[:id "INTEGER PRIMARY KEY AUTOINCREMENT"]
[:timestamp "TIMESTAMP DEFAULT CURRENT_TIMESTAMP"]
[:name "TEXT"]
[:message "TEXT"])
(sql/do-commands "CREATE INDEX timestamp_index ON guestbook (timestamp)")))
(defn db-read [query & args]
(sql/with-connection
db
(sql/with-query-results res (vec (cons query args)) (doall res))))
(defn read-guests []
(db-read "SELECT * FROM guestbook ORDER BY timestamp DESC"))
(defn save-message [{:keys [name message]}]
(sql/with-connection
db
(sql/insert-values
:guestbook
[:name :message :timestamp]
[name message (new java.util.Date)])))
and we're done.
Just because you happen to be unfamiliar with the syntax doesn't mean the code is not clean or hard to read for somebody who actually works with the language. I certainly find it a hell of a lot more readable than PHP myself. Also, can you point out what specifically is hard to read or understand in there?