-
Notifications
You must be signed in to change notification settings - Fork 175
/
util.clj
96 lines (82 loc) · 2.4 KB
/
util.clj
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
(ns hiccup.util
"Utility functions for Hiccup."
(:require [clojure.string :as str])
(:import java.net.URI
java.net.URLEncoder))
(def ^:dynamic *base-url* nil)
(defmacro with-base-url
"Sets a base URL that will be prepended onto relative URIs. Note that for this
to work correctly, it needs to be placed outside the html macro."
[base-url & body]
`(binding [*base-url* ~base-url]
~@body))
(defprotocol ToString
(^String to-str [x] "Convert a value into a string."))
(extend-protocol ToString
clojure.lang.Keyword
(to-str [k] (name k))
clojure.lang.Ratio
(to-str [r] (str (float r)))
java.net.URI
(to-str [u]
(if (or (.getHost u)
(nil? (.getPath u))
(not (-> (.getPath u) (.startsWith "/"))))
(str u)
(let [base (str *base-url*)]
(if (.endsWith base "/")
(str (subs base 0 (dec (count base))) u)
(str base u)))))
Object
(to-str [x] (str x))
nil
(to-str [_] ""))
(defn ^String as-str
"Converts its arguments into a string using to-str."
[& xs]
(apply str (map to-str xs)))
(defprotocol ToURI
(^URI to-uri [x] "Convert a value into a URI."))
(extend-protocol ToURI
java.net.URI
(to-uri [u] u)
String
(to-uri [s] (URI. s)))
(defn escape-html
"Change special characters into HTML character entities."
[text]
(.. ^String (as-str text)
(replace "&" "&")
(replace "<" "<")
(replace ">" ">")
(replace "\"" """)))
(def ^:dynamic *encoding* "UTF-8")
(defmacro with-encoding
"Sets a default encoding for URL encoding strings. Defaults to UTF-8."
[encoding & body]
`(binding [*encoding* ~encoding]
~@body))
(defprotocol URLEncode
(url-encode [x] "Turn a value into a URL-encoded string."))
(extend-protocol URLEncode
String
(url-encode [s] (URLEncoder/encode s *encoding*))
java.util.Map
(url-encode [m]
(str/join "&"
(for [[k v] m]
(str (url-encode k) "=" (url-encode v)))))
Object
(url-encode [x] (url-encode (to-str x))))
(defn url
"Creates a URL string from a variable list of arguments and an optional
parameter map as the last argument. For example:
(url \"/group/\" 4 \"/products\" {:page 9})
=> \"/group/4/products?page=9\""
[& args]
(let [params (last args), args (butlast args)]
(to-uri
(str (apply str args)
(if (map? params)
(str "?" (url-encode params))
params)))))