diff options
| author | sostler <sbostler@gmail.com> | 2010-02-10 01:08:44 -0500 |
|---|---|---|
| committer | sostler <sbostler@gmail.com> | 2010-02-10 01:08:44 -0500 |
| commit | d3fcf8d56122514c3dcbac004fcf105a4e899352 (patch) | |
| tree | 484ded214ddba3a6cc44e40d129fe1fc403e91fc /compojure-3.2/src/compojure/html | |
| parent | 079e2e9c1d3d5fb0f19515bfb566864565c43213 (diff) | |
Added custom compojure tree
Diffstat (limited to 'compojure-3.2/src/compojure/html')
| -rwxr-xr-x | compojure-3.2/src/compojure/html/form_helpers.clj | 169 | ||||
| -rwxr-xr-x | compojure-3.2/src/compojure/html/gen.clj | 124 | ||||
| -rwxr-xr-x | compojure-3.2/src/compojure/html/page_helpers.clj | 103 |
3 files changed, 396 insertions, 0 deletions
diff --git a/compojure-3.2/src/compojure/html/form_helpers.clj b/compojure-3.2/src/compojure/html/form_helpers.clj new file mode 100755 index 0000000..9da2ef9 --- /dev/null +++ b/compojure-3.2/src/compojure/html/form_helpers.clj @@ -0,0 +1,169 @@ +;; Copyright (c) James Reeves. All rights reserved. +;; The use and distribution terms for this software are covered by the Eclipse +;; Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) which +;; can be found in the file epl-v10.html at the root of this distribution. By +;; using this software in any fashion, you are agreeing to be bound by the +;; terms of this license. You must not remove this notice, or any other, from +;; this software. + +(ns compojure.html.form-helpers + "Functions for generating HTML forms and input fields." + (:use compojure.html.gen + compojure.control + compojure.str-utils + clojure.contrib.def + clojure.contrib.seq-utils)) + +;; Global parameters for easy default values + +(defvar *params* {} + "Parameter map var that form input field functions use to populate their + default values.") + +(defmacro with-params + "Bind a map of params to *params*." + [params & body] + `(binding [*params* ~params] + ~@body)) + +;; Form input fields + +(defn- input-field + "Creates a form input field." + [type name value] + (let [name (str* name) + attrs {:type type, :name name, :id name} + attrs (if value + (assoc attrs :value value) + attrs)] + [:input attrs])) + +(defn hidden-field + "Creates a hidden input field." + ([name] (hidden-field name (*params* name))) + ([name value] (input-field "hidden" name value))) + +(defn text-field + "Creates a text input field." + ([name] (text-field name (*params* name))) + ([name value] (input-field "text" name value))) + +(defn password-field + "Creates a password input field." + [name] + (input-field "password" name "")) + +(defn check-box + "Creates a check box." + ([name] + (check-box name (*params* name))) + ([name checked?] + (check-box name checked? "true")) + ([name checked? value] + [:input {:type "checkbox" + :name (str* name) + :id (str* name) + :value value + :checked checked?}])) + +(defn radio-button + "Creates a radio button." + ([group] + (radio-button group (*params* group))) + ([group checked?] + (radio-button group checked? "true")) + ([group checked? value] + [:input {:type "radio" + :name (str* group) + :id (str* group "_" value) + :value value + :checked checked?}])) + +(defn select-options + "Turn a collection into a set of option tags." + ([options] + (select-options options nil)) + ([options selected] + (let [select (fn [opt attrs] + (if (and selected (= opt (str* selected))) + (merge attrs {:selected "selected"}) + attrs))] + (domap [opt options] + (if (vector? opt) + (let [text (opt 0) + value (str* (opt 1))] + [:option (select value {:value value}) text]) + [:option (select opt {}) opt]))))) + +(defn drop-down + "Creates a drop-down box using the 'select' tag." + ([name options] + (drop-down name options (*params* name))) + ([name options selected] + [:select {:name (str* name) :id (str* name)} + (select-options options selected)])) + +(defn text-area + "Creates a text area element." + ([name] + (text-area name (*params* name))) + ([name value] + [:textarea {:name (str* name) :id (str* name)} value])) + +(defn file-upload + "Creates a file upload input." + [name] + [:input {:type "file", :name (str* name), :id (str* name)}]) + +(defn label + "Create a label for an input field with the supplied name." + [name text] + [:label {:for (str* name)} text]) + +(defn submit-button + "Create a submit button." + [text] + [:input {:type "submit" :value text}]) + +(defn reset-button + "Create a form reset button." + [text] + [:input {:type "reset" :value text}]) + +(defn form-to + "Create a form that points to a particular method and route. + e.g. (form-to [:put \"/post\"] + ...)" + [[method action] & body] + (let [method-str (upcase-name method)] + (into [] + (concat + (if (includes? [:get :post] method) + [:form {:method method-str :action action}] + [:form {:method "POST" :action action} + (hidden-field "_method" method-str)]) + body)))) + +(decorate-with optional-attrs + hidden-field + text-field + check-box + drop-down + text-area + file-upload + label + submit-button + reset-button + form-to) + +(defmacro decorate-fields + "Wrap all input field functions in a decorator." + [decorator & body] + `(decorate-bind ~decorator + [text-field + password-field + check-box + drop-down + text-area + file-upload] + (list ~@body))) diff --git a/compojure-3.2/src/compojure/html/gen.clj b/compojure-3.2/src/compojure/html/gen.clj new file mode 100755 index 0000000..617190d --- /dev/null +++ b/compojure-3.2/src/compojure/html/gen.clj @@ -0,0 +1,124 @@ +;; Copyright (c) James Reeves. All rights reserved. +;; The use and distribution terms for this software are covered by the Eclipse +;; Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) which +;; can be found in the file epl-v10.html at the root of this distribution. By +;; using this software in any fashion, you are agreeing to be bound by the +;; terms of this license. You must not remove this notice, or any other, from +;; this software. + +(ns compojure.html.gen + "A library for generating HTML output from a tree of vectors. The first item + of the vector is the tag name, the optional second item is a hash of + attributes, and the rest is the body of the tag." + (:use compojure.str-utils + clojure.contrib.def)) + +(defn optional-attrs + "Adds an optional attribute map to the supplied function's arguments." + [func] + (fn [attrs & body] + (if (map? attrs) + (let [[tag func-attrs & body] (apply func body)] + (apply vector tag (merge func-attrs attrs) body)) + (apply func attrs body)))) + +(defn escape-html + "Change special characters into HTML character entities." + [string] + (.. (str string) + (replace "&" "&") + (replace "<" "<") + (replace ">" ">") + (replace "\"" """))) + +(defvar h escape-html + "Shortcut for escape-html") + +(defn- map-to-attrs + "Turn a map into a string of HTML attributes, sorted by attribute name." + [attrs] + (map-str + (fn [[key val]] + (if key + (str " " key "=\"" (h val) "\""))) + (sort + (map (fn [[key val]] + (cond + (true? val) [(str* key) (str* key)] + (not val) [nil nil] + :else [(str* key) (str* val)])) + attrs)))) + +(defn- create-tag + "Wrap some content in an HTML tag." + [tag attrs content] + (str* "<" tag (map-to-attrs attrs) ">" + content + "</" tag ">")) + +(defn- create-closed-tag + "Make a closed XML tag with no content." + [tag attrs] + (str* "<" tag (map-to-attrs attrs) " />")) + +(defn- expand-seqs + "Expand out all the sequences in a collection." + [coll] + (mapcat + #(if (or (seq? %) (nil? %)) + % + (list %)) + coll)) + +(defn- ensure-attrs + "Ensure the tag has a map of attributes." + [[tag & body]] + (if (map? (first body)) + (list* tag body) + (list* tag {} body))) + +(defvar- css-lexer #"([^\s\.#]+)(?:#([^\s\.#]+))?(?:\.([^\s#]+))?") + +(defn- parse-css-tag + "Pulls the id and class attributes from a tag name formatted in a CSS style. + e.g. :div#content -> [:div {:id \"content\"}] + :span.error -> [:span {:class \"error\"}]" + [tag attrs] + (let [[_ tag id classes] (re-matches css-lexer (str* tag)) + attrs (merge attrs + (if id {:id id}) + (if classes + {:class (.replace classes "." " ")}))] + [tag attrs])) + +(declare html) + +(defvar- container-tags + #{:a :b :body :dd :div :dl :dt :em :fieldset :form :h1 :h2 :h3 :h4 :h5 :h6 + :head :html :i :label :li :ol :pre :script :span :strong :style :textarea + :ul} + "A list of tags that need an explicit ending tag when rendered.") + +(defn explicit-ending-tag? + "Returns true if tag needs an explicit ending tag, even if the body of the + tag is empty." + [tag] + (container-tags (keyword (str* tag)))) + +(defn html-tree + "Turns a tree of vectors into a string of HTML. Any sequences in the + tree are expanded out." + [tree] + (if (vector? tree) + (let [[tag attrs & body] (ensure-attrs tree) + [tag attrs] (parse-css-tag tag attrs) + body (expand-seqs body)] + (if (or (seq body) (explicit-ending-tag? tag)) + (create-tag tag attrs (apply html body)) + (create-closed-tag tag attrs))) + (str tree))) + +(defn html + "Format trees of vectors into a string of HTML." + [& trees] + (map-str html-tree (expand-seqs trees))) diff --git a/compojure-3.2/src/compojure/html/page_helpers.clj b/compojure-3.2/src/compojure/html/page_helpers.clj new file mode 100755 index 0000000..8c10e30 --- /dev/null +++ b/compojure-3.2/src/compojure/html/page_helpers.clj @@ -0,0 +1,103 @@ +;; Copyright (c) James Reeves. All rights reserved. +;; The use and distribution terms for this software are covered by the Eclipse +;; Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php) which +;; can be found in the file epl-v10.html at the root of this distribution. By +;; using this software in any fashion, you are agreeing to be bound by the +;; terms of this license. You must not remove this notice, or any other, from +;; this software. + +(ns compojure.html.page-helpers + "Functions for generating document and header boilerplate." + (:use compojure.control + compojure.html.gen + compojure.str-utils + clojure.contrib.str-utils) + (:import java.net.URLEncoder)) + +(def doctype + {:html4 + (str "<!DOCTYPE html PUBLIC \"-//W3C//DTD HTML 4.01//EN\" " + "\"http://www.w3.org/TR/html4/strict.dtd\">\n") + + :html5 + (str "<!DOCTYPE html>") + + :xhtml-strict + (str "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" " + "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n") + + :xhtml-transitional + (str "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" " + "\"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n")}) + +(defn xhtml-tag + "Create an XHTML tag for the specified locale. + e.g. (xhtml \"en\" + [:head ...] + [:body ...])" + [lang & contents] + [:html {:xmlns "http://www.w3.org/1999/xhtml" + "xml:lang" lang + :lang lang} + contents]) + +(defn include-js + "Include a list of external javascript files." + [& scripts] + (domap [script scripts] + [:script {:type "text/javascript" :src script}])) + +(defn include-css + "Include a list of external stylesheet files." + [& styles] + (domap [style styles] + [:link {:type "text/css" :href style :rel "stylesheet"}])) + +(defn javascript-tag + "Wrap the supplied javascript up in script tags and a CDATA section." + [script] + [:script {:type "text/javascript"} + (str "//<![CDATA[\n" script "\n//]]>")]) + +(defn link-to + "Wraps some content in a HTML hyperlink with the supplied URL." + [url & content] + [:a {:href url} content]) + +(defn url-encode + "Encodes a single string or sequence of key/value pairs." + [string-or-map] + (let [enc #(URLEncoder/encode (str* %))] + (if (string? string-or-map) + (enc string-or-map) + (str-join "&" + (map (fn [[key val]] (str (enc key) "=" (enc val))) + string-or-map))))) + +(defn url-params + "Encodes a map of parameters and adds them onto the end of an existing + address. + e.g. (url-params \"http://example.com\" {:lang \"en\", :offset 10}) + => \"http://example.com?lang=en&offset=10\"" + [address param-map] + (str address "?" (url-encode param-map))) + +(defn unordered-list + "Wrap a collection in an unordered list" + [coll] + [:ul {} + (domap [x coll] + [:li x])]) + +(defn ordered-list + "Wrap a collection in an unordered list" + [coll] + [:ol {} + (domap [x coll] + [:li x])]) + +(decorate-with optional-attrs + xhtml-tag + link-to + unordered-list + ordered-list) |
