A clojure library for generating URLs.
Documentation by autodoc: here
The easiest way to install resource-url is by using Leiningen. Just add the following dependency to your project.clj file:
[resource-url "0.1.0"]
You define functions that will return URLs based on a template. The simplest case is
(named-url home-path "home" "en")
This will create a function named home-path
that will return the path
/home/en
.
You can pass additional URL parameters to home-path
(home-path :order "by date" :page 4 :anchor "post-list")
This will expand to /home/en/?order=by+date&page=4#post-list
But the real power starts when you use functions as path elements in the template:
(named-url picture-path "users" :url-slug "pictures" :id)
Then you could user picture-path
in the following way:
(def user {:id 4, :name "John Doe", :url-slug "john-doe"})
(def picture {:id 45, :path "public/images/image.jpg"})
(picture-path [user picture] :thumb :big)
That will expand into /users/john-doe/pictures/45/?thumb=big
.
The first argument to picture-path
is the object that will be used
to expand the function parts of the URL template, if more than one, pass a vector.
Notice that in named-url
call, :url-slug
and :id
are functions, since in clojure keywords can be used as functions. But you could
use any function you want.
Finally, you can create polymorphic URL generating functions, that will map to a
different path depending on the received object. First you need to create the
polymorphic function:
(polymorphic-url url-for by-type)
This will define a function named url-for
that will dispatch to
different path templates based on object type. Then you declare to which path
each object type corresponds
(named-url user-path "users" :url-slug)
(named-url picture-path "users" :url-slug "pictures" :id)
(defrecord User [id url-slug name])
(defrecord Picture [id path])
(resource-url url-for
User user-path
Picture picture-path)
Now url-for
will dispatch to the corresponding URL generating
function:
(def user (User. 1 "john-doe" "John Doe"))
(def pict (Picture. 2 "/tmp/pict.jpg"))
(url-for user) ; will generate /users/john-doe
(url-for [user pict]) ; will generate /users/john-doe/pictures/2
Notice that by-type
dispatches based on object type or last element
type if you pass a vector.
There is another predefined dispatch by-member
which dispatches
using a keyword: (polymorphic-url url-for (by-member :tag))
or you can create your own dispatchers like in:
(polymorphic-url url-for (dispatch my-dispatch)
In fact, by-member
exists only to increase readability:
(defn by-member [mem] (dispatch mem))
Check the full documentation generated by autodoc: here