Hiccup を JSP 対応させてみたのでメモ

★この日記の内容は無視して、修正版の日記を参照のこと(2013-06-27)★

自分以外のニーズは全くないと思うが、HiccupをJSPの特殊タグ(%のやつ)とアクション(jsp:のやつ)に強引に対応させてみたのでメモ。
せっかくオープンソースなので、改変してみようということで。

改変内容

Hiccupバージョン:1.0.3
対象ファイル:hiccup/compiler.clj
置き換え対象関数:render-element

(defn- render-element
  "Render an element vector as a HTML element."
  [element]
  (let [[tag attrs content] (normalize-element element)]
    (if (or content (container-tags tag))
      (if (= tag "%")							;Add for JSP(%)
        (str "<" tag (:type attrs) " " (render-html content) " %>")	;Add for JSP(%)
        (str "<" tag (render-attr-map attrs) ">"
           (render-html content)
           "</" tag ">"))
    (str "<" tag (render-attr-map attrs) (end-tag)))))

置き換え対象関数:normalize-element

(defn normalize-element
  "Ensure an element vector is of the form [tag-name attrs content]."
  [[tag & content]]
  (when (not (or (keyword? tag) (symbol? tag) (string? tag)))
    (throw (IllegalArgumentException. (str tag " is not a valid element name."))))
  (let [[_ tag id class] (re-matches re-tag 
                            (if (.startsWith (as-str tag) "jsp_")	;Add for JSP(jsp:)
                                (.replace (as-str tag) "_" ":")		;Add for JSP(jsp:)
                                (as-str tag)))
        tag-attrs        {:id id
                          :class (if class (.replace ^String class "." " "))}
        map-attrs        (first content)]
    (if (map? map-attrs)
      [tag (merge tag-attrs map-attrs) (next content)]
      [tag tag-attrs content])))

ビルド

lein jar

利用例

(use :reload 'hiccup.core)

(html [:% {:type "@"} "page contentType=\"text/html;charset=Shift_JIS\""])
; -> "<%@ page contentType=\"text/html;charset=Shift_JIS\" %>"

(html [:% {:type "="} "hoge"])
; -> "<%= hoge %>"

(html [:jsp_forward {:page "hoge.jsp"}])
; -> "<jsp:forward page=\"hoge.jsp\" />"

(html [:jsp_forward {:page "hoge.jsp"}
        [:jsp_param {:name "param1" :value "hoge"}]])
; -> "<jsp:forward page=\"hoge.jsp\"><jsp:param name=\"param1\" value=\"hoge\" /></jsp:forward>"