Hi Tom! Thanks for your interest in Enlive.
Tom Hickey a écrit : > I am trying out Enlive and had some questions regarding it's feature > set and your future plans in terms of functionality. > I grow it as I go: I haven't a clearly outlined future features list (I'm thinking about JS/jQuery integration, selector priority, cross-template reuse and, maybe, xml support). > 1) Component Templates > I was wondering if you had any plans to support component templates? > I.e., templates that represent just a portion of a page (via an html > snippet). > While I don't use the word "component" I plan to add support for defining template snippets that could be reused in other templates (templates are functions after all). > I tried to figure out how to do this myself, but TagSoup always wraps > the snippets in <html> and <body> tags. If I don't pass startparse- > tagsoup to xml/parse, I am able to get the results I am looking for. > (Note: I also tried to use the root-bogons feature in tagsoup, as that > sounded like it should accomplish this, but to no avail.) > > Is tagsoup always necessary, or could this perhaps be optional? > Tagsoup could certainly be optional when you are dealing with xhtml but, to me, tagsoup adding <html> and <body> tags isn't a problem. I want template files to be regular html files even for files that would be a mere collection of snippets so these files would have <html> and <body> tags. The syntax I was thinking about was something like this: (defsnippet snippet-name "template/support/file.html" [selector to single out this snippet] [args] template stuff) and/or: (defsnippets "template/support/file.html" (snippet-name1 [selector to single out this snippet] [args] template stuff) (snippet-name2 [selector to single out this snippet] [args] template stuff) ...) What do you think? > 2) Setting content vs. removing elements > How do you specify whether you want to set the content of an element > versus replacing/removing the element? Take for example these > modifications to the :div.no-msg portion of your example: > > [:div.no-msg] (when true "fred") ; this will replace the div element > with the string "fred", versus: > [:div.no-msg] "fred" ; which will set the divs content to "fred" > > Is it true that if any code other then a string or parameter is used > it will always replace the element? > It's true but I'm not quite happy with this behavior: I wanted to preserve the brevity of setting content from a parameter without resorting to (text my-parameter) but it makes things irregular. Right now there are several cases: 1/ If the right hand side of a rule is a list and expands to a template-macro, it is applied without needing to unquote it. The matched element is replaced by the result of the template-macro. 2/ If the right hand side of a rule is a list and does not expand to a template-macro, it's random clojure code (which can apply template-macros on the matched element using unquote). The matched element is replaced. 3/ Otherwise the right hand side form is implicitly surrounded by the 'text template-macro and go to 1/ ('text replaces the content). If you want to replace the content while being inside some clojure code you have to write: [:div.no-msg] (when (some test) ~(html/text "fred")) > 3) Selectors > Do you support descendent selectors? Yup but I don't compute selector specificity so you have to put more specific selectors first. This doesn't work: [:a] "every link" [:h1 :a] "never seen" This works: [:h1 :a] "link in a h1" [:a] "other links" > What about grouping selectors? Patch welcome :-) > If so, how would I write the equivalent for the following css selectors: > #currentEvents .post {} > (I believe the first on would be [:#currentEvents :.post] but I can't > quite tell if that's correct.) > It's correct > Do you have any plans to support additional selectors (e.g. child, > sibling, universal, attribute and/or ppseudo-class selectors)? > child is already supported :> The current implementation of selectors relies exclusively on the elements hierarchy hence every selector that needs to know the siblings of the current element (sibling, :odd :first-child etc.) can't be supported without some refactoring. Universal and attribute selectors can be easily added. Right now you can use predicates or incomplete form to mimick those selectors: ;; predicate as selector (def universal (constantly true)) [:#foo :> universal] ; #foo > * ;; incomplete form [(-> :attrs :href (= "http://clojure.org/")] ; *[href="http://clojure.org/"] is equivalent to: [#(-> % :attrs :href (= "http://clojure.org/")] You can also select the intersection of several selectors by grouping them into a vector: [[:a #(-> % :attrs :href (= "http://clojure.org/")]]; a[href="http://clojure.org/"] > 4) Attributes > Do you have any plans to support setting attributes on elements? > set-attr and remove-attr > 5) Escaping HTML > Is there any way to control when HTML is escaped or not? For instance, > if I had the following function and template: > (defn get-link [] "<a href=\"http://www.google.com/\">google</a>") > (deftemplate links-template "net/cgrand/enlive_html/example.html" [a] > [:h1] a > [:.post] (get-link)) > > (let [my-link (get-link)] > (links-template my-link)) > > The link is escaped in the h1, but not in the .post (or, more > specifically, when .post is replaced). Here it is escaped in both cases: user=> (apply str (links-template (get-link))) "<html><head><title>An Enlive example</title></head><body><h1><a href=\"http://www.google.com/\">google</a></h1><div class=\"no-msg\">Sorry, I'm too lazy to post.</div><a href=\"http://www.google.com/\">google</a></body></html>" By default, Enlive escapes everything but you can mark already escaped data: (deftemplate links-template "net/cgrand/enlive_html/example.html" [a] [:h1] a [:.post] (html/escaped (get-link))) user=> (apply str (links-template (get-link))) "<html><head><title>An Enlive example</title></head><body><h1><a href=\"http://www.google.com/\">google</a></h1><div class=\"no-msg\">Sorry, I'm too lazy to post.</div><a href=\"http://www.google.com/\">google</a></body></html>" > Thanks in advance for your help. I hope my questions are clear. Please > don't take them as criticism, I'm just trying to get a better handle > on how Enlive works. > Thanks for trying Enlive despite its lack of documentation! I'm really interested in your feedback. Christophe -- Professional: http://cgrand.net/ (fr) On Clojure: http://clj-me.blogspot.com/ (en) --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~----------~----~----~----~------~----~------~--~---