ckirkendall / kioo

Enlive/Enfocus style templating for Facebook's React and Om in ClojureScript.
Eclipse Public License 1.0
404 stars 39 forks source link

Add some way to compose selectors #52

Open levand opened 9 years ago

levand commented 9 years ago

Say I have something like this:

 (defsnippet Container "template.html" [:.container]
  [data]
  {[:.widget1 :.foo] (content "foo")
   [:.widget1 :.bar] (content "bar")
   [:.widget2 :.foo] (content "foo")
   [:.widget2 :.bar] (content "bar")})

Is there a way to factor out the common elements? Something like this, perhaps?

(def selector-fragment
  {[:.foo] (content "foo")
   [:.bar] (content "bar")})

(defsnippet Container "template.html" [:.container]
  [data]
  {[:.widget1] (selector-fragment)
   [:.widget2] (selector-fragment)})

I don't care about the syntax, but I can't figure out any way to get this kind of composition/abstraction without hacking Kioo itself.

  1. If I do the composition in "transform" position, on the right hand side, I can't do any more selecting because selection is unavailable at runtime.
  2. I can't compose on the left hand side, in the selector position, because evaluation of that is controlled exclusively by the Kioo macro.

Any ideas on how this might be supported?

levand commented 9 years ago

If you have any ideas on how to do this, I'd be happy to do the implementation if you gave me a few pointers. I'd love to use this on the project I'm working on right now, but I'd need something relatively soon.

Thanks!

solussd commented 9 years ago

Maybe look at how "at" works in enfocus (for inspiration).

levand commented 9 years ago

@solussd Enfocus has runtime selectors, which that uses. Kioo selection happens exclusively in Clojure at macro expansion time (as far as I can tell).

solussd commented 9 years ago

@levand right-- I was thinking syntactically, but thinking about it more it's not ideal, e.g.:

{[:.widget1]   (at this
                        selector-fragment)}
ckirkendall commented 9 years ago

The most likely way to do this is to port enlive to cljs. You might be able to start with hickory and a translation from enlive selectors to hickory selectors. The data structure you're getting in 'at' here is the clojure-xml format with a minor difference that some of your children nodes could be react nods and xml nodes. So any zipper would have to ignore those nodes when walking for the select.

levand commented 9 years ago

I have started an effort to port Enlive to cljs - will let you know how it goes.

One side effect of this is that, if I do it right, Kioo can become much smaller and deal only with translating Enlive-produced data structures to React components, not shimming out Enlive as much.

I'll let you know what I come up with.