Skip to content


Subversion checkout URL

You can clone with
Download ZIP
Browse files

add in custom-handler, lots of little doc fixes, history

Signed-off-by: Chris Granger <>
  • Loading branch information...
commit eae90a85578a4a834ab9267b6ca1be8709eec92d 1 parent 53e8e99
@ibdknox ibdknox authored
@@ -1,3 +1,29 @@
+##Changes for 1.2.0
+* Refactored for Clojure 1.3.0 support
+* Refactored server to enable custom noir handler creation
+* Added url decoding for routes. (defpage "/hey how" ...) will work now.
+* Added noir.util.gae to get Noir up on Google App Engine
+* Added named routes
+* Added noir.request/ring-request
+* Added url-for to query named routes
+* Added noir.server/load-view-ns
+* Added a :resource-root option to the server
+* Added a :cookie-attrs option to the server
+* Added post-route
+* Added signed cookies
+* Added compojure-route and custom-handler to handle integration with other libs
+* Changed noir.validation/errors? will now return if any errors exist if no fields are supplied.
+* Fixed noir.validation/is-email? to use a better regex
+* Fixed and improved noir.util.s3
+* Fixed incorrect header setting for noir.response/xml
+* Fixed custom middleware preserves order
+* Fixed bugs in cookie handling that would cause incorrect retrieval
+* Fixed some issues with exceptions to make the 500 page more resilient
+* Moved to latest compojure/ring/hiccup
+* Added tons of tests
##Changes for 1.1.0
* Added session/flash-put! and sesion/flash-get
7 project.clj
@@ -3,14 +3,13 @@
:dependencies [[org.clojure/clojure "1.2.1"]
[compojure "0.6.5"]
[org.clojure/tools.namespace "0.1.0"]
- [clj-json "0.3.2"]
+ [clj-json "0.4.3"]
[ring "0.3.11"]
[cssgen "0.2.4"]
[hiccup "0.3.6"]
[clj-stacktrace "0.2.3"]
- [org.ibdknox.clojars/ring-reload-modified "0.1.1"]
+ [ring-reload-modified "0.1.1"]
[ "0.8.0"]
[org.mindrot/jbcrypt "0.3m"]]
- :dev-dependencies [[marginalia "0.6.0"]
- [org.clojars.rayne/autodoc "0.8.0-SNAPSHOT"]]
+ :dev-dependencies [[org.clojars.rayne/autodoc "0.8.0-SNAPSHOT"]]
:autodoc {:name "Noir" :page-title "Noir Docs" :load-except-list [#"noir\/content.*"]})
23 src/noir/core.clj
@@ -50,7 +50,7 @@
(assoc :destruct cur)
(assoc :body (rest all))))
-(defn parse-args
+(defn ^{:skip-wiki true} parse-args
"parses the arguments to defpage. Returns a map containing the keys :name :action :url :destruct :body"
(-> args
@@ -89,7 +89,7 @@
-(defn route-arguments
+(defn ^{:skip-wiki true} route-arguments
"returns the list of route arguments in a route"
(->> route
@@ -110,8 +110,7 @@
(string/replace path (str k) (str v))) url route-args)))
(defmacro url-for
- "given a named route, i.e. (url-for foo), where foo is a named
- route, i.e. (defpage foo \"/foo/:id\"), returns the url for the
+ "given a named route, i.e. (defpage foo \"/foo/:id\"), returns the url for the
route. If the route takes arguments, the second argument must be a
map of route arguments to values
@@ -157,6 +156,20 @@
(defn compojure-route
"Adds a compojure route fn to the end of the route table. These routes are queried after
- those created by defpage and before the generic catch-all and resources routes."
+ those created by defpage and before the generic catch-all and resources routes.
+ These are primarily used to integrate generated routes from other libs into Noir."
(swap! post-routes conj compojure-func))
+(defmacro custom-handler
+ "Adds a handler to the end of the route table. This is equivalent to writing
+ a compojure route using noir's [:method route] syntax.
+ (custom-handler [:post \"/login\"] {:as req} (println \"hello \" req))
+ => (POST \"/login\" {:as req} (println \"hello\" req))
+ These are primarily used to interface with other handler generating libraries, i.e. async alpeh handlers."
+ [& args]
+ (let [{:keys [action destruct url body]} (parse-args args)]
+ `(compojure-route (~action ~url ~destruct ~@body))))
2  src/noir/server/handler.clj
@@ -71,6 +71,6 @@
(options/wrap-options opts))))
(defn base-handler
- "Get the most basic Noir request handler, that only adds wrap-custom-middleware."
+ "Get the most basic Noir request handler, only adding wrap-custom-middleware and wrap-request-map."
[& [opts]]
(init-routes opts))
5 src/noir/util/gae.clj
@@ -17,7 +17,10 @@
[noir.validation :as validation]))
-(defn gae-handler [opts]
+(defn gae-handler
+ "Create a Google AppEngine friendly handler for Noir. Use this instead
+ of server/gen-handler for AppEngine projects."
+ [opts]
(-> (handler/base-handler opts)
7 src/noir/util/s3.clj
@@ -21,6 +21,13 @@
`(binding [*s3* (service ~server-spec)]
+(defn rename!
+ "Rename the given file on S3"
+ [bucket file new-file]
+ (let [new-obj (new S3Object new-file)]
+ (. new-obj setAcl (. AccessControlList REST_CANNED_PUBLIC_READ))
+ (. *s3* renameObject bucket file new-obj)))
(defn put!
"Put the given file on S3 where bucket is the string name of the S3 bucket to use."
[bucket file]
2  src/noir/validation.clj
@@ -68,7 +68,7 @@
(defn errors?
"For all fields given return true if any field contains errors. If none of the fields
- contain errors, return false"
+ contain errors, return false. If no fields are supplied return true if any errors exist."
[& field]
(if-not (seq field)
(not (empty? @*errors*))
Please sign in to comment.
Something went wrong with that request. Please try again.