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 [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---