Browse files

Post about webnoir and enlive

  • Loading branch information...
1 parent e9d3766 commit f777aaa023e07db006a101f212aeadc6c1ad1ad5 @paulosuzart committed Mar 26, 2012
Showing with 102 additions and 2 deletions.
  1. +100 −0 source/_posts/2012-03-25-web-noir-plus-enlive-template.markdown
  2. +2 −2 source/about/index.markdown
View
100 source/_posts/2012-03-25-web-noir-plus-enlive-template.markdown
@@ -0,0 +1,100 @@
+---
+layout: post
+title: "Web Noir plus enlive template"
+date: 2012-03-25 21:43
+comments: true
+categories: clojure
+---
+
+Hi again! Long time without writing here. But for a good reason.
+
+One of the most promising web frameworks for [clojure](http://clojure.org/) is [noir](http://www.webnoir.org/). It is actually an abstraction on top of [ring](https://github.com/mmcgrana/ring/) and [Compojure](https://github.com/weavejester/compojure), both successful clojure products.
+
+By default, noir comms with the excellent [hiccup](https://github.com/weavejester/hiccup), which allows one write html in clojure like this:
+
+
+``` clojure Html in clojure
+ (use 'hiccup.core)
+ (def name "Nacho")
+ (html [:span {:id "dog"} name])
+
+ ;; produces:
+ ;;"<span id=\"dog\">Nacho</span>"
+```
+
+It doesn't look designer friendly, right? I would still use hiccup for admin pages or small chunks of html strictly generated by clojure code with a good css to help presenting it.
+
+Enters enlive. I've already used enlive [before](http://codemountain.wordpress.com/2010/10/09/clojure-macros/), without understanding it that much, I would say. It's been almost two years since that post. And what makes me happy with enlive is the possibility to be closer to [Scala's](http://www.scala-lang.org/) web framework [Lift](http://liftweb.net/). That is, put some attention on the view with actually working with actions. So, combine this:
+
+``` html Login form
+ <form method="post" id="login_form">
+ <div id="errors">
+ <span class="error"/>
+ </div>
+ <label for="username">Username</label>
+ <input type="text" id="username" name="username"/>
+ <label for="password">Password</label>
+ <input type="text" id="password" name="password"/>
+ <input type="submit" value="Login"/>
+ </form>
+```
+
+With a snippet from enlive:
+
+``` clojure Form snippet
+
+(defn show-errors [msgs]
+ (h/clone-for [i msgs]
+ [:span.error]
+ (h/content i)))
+
+(h/defsnippet _login "mayapp/views/_login.html" [:#login_form]
+ [username password & [errors]]
+
+ [:div#errors]
+ (show-errors errors)
+
+ [:input#username]
+ (h/set-attr :value username)
+
+ [:input#password]
+ (h/set-attr :value password))
+```
+
+And you have the html output that can be referenced this way:
+
+``` clojure Login page
+(defpage "/login" {:as login}
+ (_login (:username login)
+ (:password login)
+ (:error login)))))
+
+;;handling the form submit
+(defpage [:post "/login"] {:as login}
+ (if (valid? login)
+ (format "Yeah!! Welcome %s" (:username login))
+ (render "/login" (assoc login :error (v/get-errors)))))
+```
+
+We still have sort of action base framework but with good attention to the view. Not the `show-errors` function, that can be reused every where with a `:div#errors > :span.error`. It will repeat the span for every error in `msgs`.
+
+The error messages may be produce by `noir.validation` package. In the `POST` route you can see the snippet being activated with the `[errors]` argument in case of any errors.
+
+Snippets should be natural for you, and can be used in situations where you define parts of an html, you you have a bigger html resource grouping many parts that cane be a snippet. That is why you passes a selector to `defsnipet` right after the resource name. That is, transformations will start from this point.
+
+The other option is the `deftemplate`, it works similar to `defsnippet`, but doesn't take any selector as an argument, because it process the entire resource.
+
+A great usage of enlive you can find at [Facebook/Heroku sample app -- Clojure](https://github.com/metadaddy-sfdc/facebook-template-clojure/).
+
+And to help you starting with noir plus enlive, I've created a template project using [lein-newnew](https://github.com/Raynes/lein-newnew), a way to pack a project as a template, so anyone can reuse it. Please refer to [https://clojars.org/clj-enlive-template](https://clojars.org/clj-enlive-template) and the [clj-enlive-template](https://github.com/paulosuzart/clj-enlive-template) source code. Just:
+
+```
+lein plugin install clj-enlive-template 0.0.1
+lein new clj-enlive-template myproj
+cd myproj
+lein run
+```
+
+And start having fun with enlive and noir. This project template may be evolved to have [korma](http://sqlkorma.com/) or any persistence framework.
+
+Hope it may be useful for you. Don't forget to visit the [about](/about) page. And follow me on Twitter: [@paulosuzart](http://twitter.com/paulosuzart)
View
4 source/about/index.markdown
@@ -7,6 +7,6 @@ sharing: true
footer: true
---
-My name is Paulo Suzart and I'm on the Java platform for the last 8 years. Now my priority is functional programming (mostly with clojure) and cloud computer.
+My name is Paulo Suzart and I'm on the Java platform for the last 8 years. Now my priority is functional programming (mostly with clojure) and cloud computing.
-Don't be deceived by my [Linked In profile](http://br.linkedin.com/in/paulosuzart "Profile"), my real interest you can find on my [Github repos](https://github.com/paulosuzart/) and my other [blog](http://codemountain.wordpress.com/).
+Don't be deceived by my [Linked In profile](http://br.linkedin.com/in/paulosuzart "Profile"), my real interest you can find in my [Github repos](https://github.com/paulosuzart/) and my other [blog (Codemountain - pt_BR)](http://codemountain.wordpress.com/).

0 comments on commit f777aaa

Please sign in to comment.