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>&lt;a 
href=\"http://www.google.com/\"&gt;google&lt;/a&gt;</h1><div 
class=\"no-msg\">Sorry, I'm too lazy to post.</div>&lt;a 
href=\"http://www.google.com/\"&gt;google&lt;/a&gt;</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>&lt;a 
href=\"http://www.google.com/\"&gt;google&lt;/a&gt;</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
-~----------~----~----~----~------~----~------~--~---

Reply via email to