Open alienscience opened 14 years ago
It's possible in theory. It might need a bit of rearranging to do, but I'd be okay with it in principle. I've been meaning to tidy up Hiccup's source code for a while, as all that precompilation has made the code a bit labyrinthine.
Connecting hiccup and enlive would really be very useful. I have written a render-nodes function that takes a hiccup form and turns it into a node or seq of nodes that enlive is happy with. I had to write it inside src/hiccup/core.clj because it uses the normalize-element private function defined there. I did not spend time yet developing something to pre-compile the nodes like hiccup does for HTML. It would be great to have that too.
Here is the code I have written. Please, feel free to use it to add to hiccup. If you do not have time for it, please, let me know and I will continue work on my fork. Thank you for such a useful library. fxt
(defn- nodalize-attribute [[name value]]
(cond
(true? value) [(as-str name) (escape-html name)]
(not value) nil
:else [(as-str name) (escape-html value)]))
(defn- nodalize-attr-map [attrs]
(if (nil? attrs)
nil
(->> attrs seq (map nodalize-attribute) (remove nil?)
(apply concat) (apply sorted-map))))
(defmulti render-nodes
"Turn a Clojure data type into a seq of XML nodes."
{:private false}
type)
(defn- nodalize-element
"Render an tag vector as an XML node."
[element]
(let [[tag attrs content] (normalize-element element)]
{:tag tag
:attrs (nodalize-attr-map attrs)
:content (render-nodes content)}))
(defmethod render-nodes IPersistentVector [element]
(nodalize-element element))
(defmethod render-nodes ISeq [coll]
(map render-nodes coll))
(defmethod render-nodes nil [_]
nil)
(defmethod render-nodes :default [x]
(str x))
BTW, I did some little bit of testing of the type (html [hiccup stuff]) == (enlive-html/emit* (render-nodes [hiccup stuff])) and got the two to agree. That is why I did a bit of transformation on the attribute map and used a sorted-map for it.
I think if I was going to add this capability, I'd want the library refactored so that the output was controlled by a protocol that could be changed depending on whether you wanted a string of HTML, a string of XML or a tree of XML node maps.
So I don't think there should be a separate render-nodes
function, but what you're written is a good start and feel free to continue refining it.
since #36, normalize-element is a public function, so you can use @fxt's code in your project like so:
(ns myproject.utils.hiccup2xml
(:require [hiccup.compiler :as cpl])
(:use [hiccup.util :only [as-str escape-html]])
(:import (clojure.lang IPersistentVector ISeq)))
; ... as above
Enlive added a hiccup-like helper about a year ago (v1.1.0), so I wonder if this feature request is necessary anymore? @weavejester, mind taking a look and closing this ticket if you agree?
I think there's benefit in allowing hiccup to emit different output structures. Having an output to a Clojure XML structure doesn't sound a bad idea. Aside from Enlive, it would allow the use of the clojure.xml libraries.
Hey James, I was wondering what the status of this issue and the refactor
branch mentioned in #64 is?
The latest branch is 2.0
. I haven't done any more work on it in a while.
Hello, This is a feature request and not a bug. I was recently using Hiccup with Enlive and found that I had to parse Hiccup output into Clojure-XML format. This resulted in the following conversions:
hiccup datastructure -> string -> clojure-xml datastructure -> html page
This is a bit clunky and could potentially lead to performance problems.
The author of Enlive suggested that a function to convert Hiccup datastructures into clojure-xml form would be optimal for use with Enlive.
Developers on the #clojure-web freenode channel thought that such a facility would be useful elsewhere to produce clojure-xml compatible datastructures, since the Hiccup representation is much more convenient to write.
Would it be possible to add such a function to Hiccup? If not, would a patch to do this be accepted in principle?
Thanks in advance for your help. Saul