GithubHelp home page GithubHelp logo

ckirkendall / kioo Goto Github PK

View Code? Open in Web Editor NEW
404.0 22.0 39.0 564 KB

Enlive/Enfocus style templating for Facebook's React and Om in ClojureScript.

License: Eclipse Public License 1.0

HTML 2.14% Clojure 97.86%

kioo's Introduction

kioo

Kioo brings Enlive/Enfocus style templates to React. This allows for much better separation between the view and logic layers of the application.

This project is very early on in development and the API is expected to change as development progresses.

What does kioo mean?

Kioo is Swahili for mirror. Facebook's React library is built around the idea that the view is a reflection of your application state.

Artifact

All artifacts are published to clojars. Latest stable version is 0.4.2:

[kioo "0.5.0"] ;stable

[kioo "0.5.1-SNAPSHOT"] ;experimental

Concepts

component is a unit of your page such as header, footer, page element. A kioo component is logically the same as a Facebook's React.js component. What makes kioo components different from React's is they take raw html from the class path and compile it into React.js nodes. This allows you to define the structure of your page as standard html. React.js provides something similar with JSX but it still mixes the content and the logic. Kioo takes a different aproach by allowing you to bring in static content and transform it with selectors in a manner similar to Enlive/Enfocus templates.

The biggest difference you will see between Enlive and Kioo is that Kioo only supports unordered transforms. This means that you pass a map of transforms to the component and you can not guarantee what order they will be processed in. This is due to, selection being done at compile time and transforms being done at runtime. Selections cannot take the structure of the content at runtime into consideration.

Templates and Snippets

A snippet is a function that returns a kioo component, it can be used as a building block for more complex templates, snippets and components.

You define a snippet by providing a remote resource, a selector and series of transformations.

The snippet definition below selects a table body from the remote resource templates/template1.html and grabs the first row. It then fills the content of the row.

(defsnippet snippet2 "templates/template1.html" [:tbody :> first-child]
  [fruit quantity]
  {[:tr :> first-child] (content fruit)
   [:tr :> last-child] (content (str quantity))})

A template is very similar to a snippet except it does not require a selector to grap a sub section, instead the entire remote resource is used as the dom. If the remote resource is a full html document only what is inside the body tag is brought into the template.

(deftemplate template2 "/templates/template1.html" 
  [fruit-data]
  {[:#heading1] (content "fruit")
   [:thead :tr :> last-child] (content "quantity")
   [:tbody] (content
              (map #(snippit2 % (fruit-data %)) (keys fruit-data)))})

Troubleshooting

The best way to troubleshoot the processing of Kioo templates and snippets and the matching of selectors is to use Clojure's macroexpand-1 together with clojure.tools.trace/trace-ns applied to 'kioo.core to see the resulting ClojureScript and log of what happened during the processing. You can also call manually the resulting JavaScript function <your ns>.<snippet/template name> and examine the React component it produces.

Read more and additional tips in the post Kioo: How to Troubleshoot Template Processing by Jakub Holy.

Quickstart tutorial

Working With Om

Let's take a look at and example. Here we work with David Nolen's om.

<!DOCTYPE html>
<html lang="en">
  <body>
    <header>
      <h1>Header placeholder</h1>
      <ul id="navigation">
        <li class="nav-item"><a href="#">Placeholder</a></li>
      </ul>
    </header>
    <div class="content">place holder</div>
  </body>
</html>
(ns kioo-example.core
  (:require [kioo.om :refer [content set-attr do-> substitute listen]]
            [kioo.core :refer [handle-wrapper]]
            [om.core :as om :include-macros true]
            [om.dom :as dom :include-macros true])
  (:require-macros [kioo.om :refer [defsnippet deftemplate]]))


(defsnippet my-nav-item "main.html" [:.nav-item]
  [[caption func]]
  {[:a] (do-> (content caption)
              (listen :onClick #(func caption)))})

(defsnippet my-header "main.html" [:header]
  [{:keys [heading navigation]}]
  {[:h1] (content heading)
   [:ul] (content (map my-nav-item navigation))})


(deftemplate my-page "main.html"
  [data]
  {[:header] (substitute (my-header data))
   [:.content] (content (:content data))})

(defn init [data] (om/component (my-page data)))

(def app-state (atom {:heading "main"
                      :content    "Hello World"
                      :navigation [["home" #(js/alert %)]
                                   ["next" #(js/alert %)]]}))

(om/root init app-state {:target  (.-body js/document)})

To view the example:

$ git clone https://github.com/ckirkendall/kioo.git
$ cd kioo/example/om
$ lein cljsbuild once

Once the javascript compiles you can open index.html in a browser.

For a more fleshed-out example, please see the Kioo implementation of TodoMVC exists here.

Working With Reagent

Here we work with Dan Holmsand's Reagent.

<!DOCTYPE html>
<html lang="en">
  <body>
    <header>
      <h1>Header placeholder</h1>
      <ul id="navigation">
        <li class="nav-item"><a href="#">Placeholder</a></li>
      </ul>
    </header>
    <div class="content">place holder</div>
  </body>
</html>
(ns kioo-example.core
  (:require [kioo.reagent :refer [content set-attr do-> substitute listen]]
            [reagent.core :as reagent :refer [atom]])
  (:require-macros [kioo.reagent :refer [defsnippet deftemplate]]))

(declare data nav)


(defsnippet my-nav-item "main.html" [:.nav-item]
  [[caption func]]
  {[:a] (do-> (content caption)
              (listen :on-click func))})


(defsnippet my-header "main.html" [:header] []
  {[:h1] (content (:header @data))
   [:ul] (content (map my-nav-item (:navigation @nav)))})


(deftemplate my-page "main.html" []
  {[:header] (substitute [my-header])
      [:.content] (content (:content @data))})


(def data (atom {:header "main"
                 :content "Hello World"}))

(def nav (atom {:navigation [["home" #(swap! data
                                             assoc :content "home")]
                             ["next" #(swap! data
                                             assoc :content "next")]]}))

(reagent/render-component [my-page] (.-body js/document))

To view the example:

$ git clone https://github.com/ckirkendall/kioo.git
$ cd kioo/example/reagent
$ lein cljsbuild once

Once the javascript compiles you can open index.html in a browser.

Selector Syntax

Kioo uses enlive based selectors. See syntax.html

Some examples:

Enlive                                       CSS
=======================================================
[:div]                                       div
[:body :script]                              body script
#{[:ul.outline :> :li] [:ol.outline :> li]}  ul.outline > li, ol.outline > li
[#{:ul.outline :ol.outline} :> :li]          ul.outline > li, ol.outline > li
[[#{:ul :ol} :.outline] :> :li]              ul.outline > li, ol.outline > li
[:div :> :*]                                 div > *
[:div :> text-node]                          (text children of a div)
[:div :> any-node]                           (all children (including text nodes and comments) of a div)
{[:dt] [:dl]}                                (fragments starting by DT and ending at the *next* DD)

Notice that some of the predefined selector steps are used as naked symbols, i.e. you can just use them (no require :refer etc.). Example:

(defsnippet shop-html "templates/shops.html" [[:.shop first-of-type]]
  [_] ;;                                                 ^- a naked symbol
  {[:.content] (content "Kioo is mighty!")})

Transformations

A transformation is a function that returns either a react node or collection of react nodes.

Kioo transforms mirror most of the base enlive transformations:

New Transforms

;; attached event listeners to the component
(listen :on-click (fn [...] ...))

;;supported react events
:on-mount
:on-render
:on-update

;;all standard dom events are supported

Enlive Based Transforms

;; Replaces the content of the element. Values can be nodes or collection of nodes.
(content "xyz" a-node "abc")


;; Replaces the content of the element with the html provided.
(html-content "<h1>this is html text</h1>")

;; Wraps selected node into the given tag
(wrap :div)
;; or
(wrap :div {:class "foo"})

;; Opposite to wrap, returns the content of the selected node
unwrap

;; Sets given key value pairs as attributes for selected node
(set-attr :attr1 "val1" :attr2 "val2")

;; Removes attribute(s) from selected node
(remove-attr :attr1 :attr2)

;; Sets class attr of the selected node
(set-class "foo bar")

;; Adds class(es) on the selected node
(add-class "foo" "bar")

;; Removes class(es) from the selected node
(remove-class "foo" "bar")

;; Set styles on to the selected node
(set-style :display "none" :backgroud-color "#cfcfcf")

;; Removes styles from the selected node
(remove-style :display :background-color)

;; Chains (composes) several transformations. Applies functions from left to right.
(do-> transformation1 transformation2)

;; Appends the values to the content of the selected element.
(append "xyz" a-node "abc")

;; Prepends the values to the content of the selected element.
(prepend "xyz" a-node "abc")

;; Inserts the values after the current selection (node or fragment).
(after "xyz" a-node "abc")

;; Inserts the values before the current selection (node or fragment).
(before "xyz" a-node "abc")

;; Replaces the current selection (node or fragment).
(substitute "xyz" a-node "abc")

Not supported yet

;; Clones the selected node, applying transformations to it.
(clone-for [item items] transformation)
(;; or
(clone-for [item items]
  selector1 transformation1
  selector2 transformation2)

;;;; Takes all nodes (under the current element) matched by src-selector, removes
;; them and combines them with the elements matched by dest-selector.
(move)

Thanks

This library is based on Christophe Grand's enlive library.

License

Copyright © 2014 Creighton Kirkendall

Distributed under the Eclipse Public License either version 1.0 or (at your option) any later version.

kioo's People

Contributors

alesya-h avatar astahfrom avatar ckirkendall avatar dthume avatar jaen avatar jjbohn avatar krisajenkins avatar led avatar levand avatar oliverm avatar pasviegas avatar rmoehn avatar scttnlsn avatar tdammers avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

kioo's Issues

Support for re-frame

It would be great if kioo offered support for the relatively new reagent library re-frame. I've been messing around with it and have been able to get it working, somewhat, with kioo's reagent support, but the difficulty is that kioo only seems to generate "Form 1" (using re-frame's terminology) components, so it's difficult to chain reactions together and you wind up having to write a lot of messy wrapper code.

I'm not entirely sure what a pleasant kioo interface to this would be, since defsnippet and friends already have fairly long and complex sets of arguments, but some way to specify a let-binding on initialization (rather than render) which could let the user bind stuff to re-frame/subscribe might work out well.

I may try to play around with this a bit myself, but I still don't understand kioo's internals terribly well and as I said I don't have a clear idea of what an ideal interface would look like in the first place.

local state example with reagent

Hi,

I'm struggling here trying to find out how to have local state using reagent, could you guys please provide an example on that?

Thanks.

custom selector support

Custom selectors like the following work fine in Enlive but aren't supported in Kioo yet:

(defn text= [s] (pred #(= s (text %))))

Attempting to use text= in a kioo selector currently gives a null-pointer error on compilation.

Hard dependencies

Why does kioo need to specify hard dependencies regarding om, etc? Wouldn't it be better to let the user pull dependencies himself?

I've just tried to update 4.0.0 to 4.0.1 and saw that it breaks my app. This is because kioo pulls an older cljsjs/react version that gets selected over mine.

[!] cljsjs/react
    ✘ 0.13.3-0
      org.omcljs/om
    ✔ 0.12.2-5
      kioo

Release of 0.4.1?

Hi Creighton,

Is there any chance of getting a non-snapshot release of the changes that are currently pending for 0.4.1? There have been a number of useful changes since 0.4.0, and it would be really great to have a dependency that isn't a moving target.

Thanks for your time,
Tom Hickey

kioo + progressive enhancement

Do be honest this isn't an issue with kioo, but more of a question: How possible would it be to load templates at runtime instead of compile time?

I'd ideally like to use something like kioo to do progressive enhancement (i.e. receive generated HTML from the server, and then enhance it with JS). In more code-y terms, something like:

(kioo/component (.-body js/document) [:#main]
     {[:h1] (content (:header @data))
      ; ...etc 
       })

Has this not been done because..

  • a) parsing html at runtime is hard?
  • b) it's a terrible idea for other reasons?
  • c) it just hasn't been done yet?
  • d) what are you talking about that's totally a thing you can do already!

Would really appreciate some input before I embark on trying to fill this gap :-p

Safari performance with Kioo-generated React nodes

Kioo's output causes Safari browsers to hang when moderately complex HTML structures are used. There's a discussion of this issue on the news group here:
https://groups.google.com/forum/#!topic/enfocus/vfS63QhnRXs

A sample project that exhibits the issue is here:
https://github.com/OliverM/kiooform

This was encountered with Kioo 0.4.1 but 0.4.2 still shows the issue.

Creighton, you mentioned there that you'd encountered a similar issue previously, did you have a chance to capture what was going on there?

Kioo and lein-figwheel

Hello,

I'm trying to use kioo with lein-figwheel and reagent. No changes are detected on HTML files.

Is there a simple way to make this work ?

Aside question from a novice: why not putting HTML templates into the src folder since they actually are source files? Wouldn't they automatically be watched by figwheel this way?

Thanks

Ordering Inside Do->

Not sure if I'm missing something here, but I wanted to report some behavior that seems strange.

The following snippet performs as expected:

(defsnippet home-page "public/assets/html/home.html" [:div.home]
  [data]
  {[:div.home] (do-> (content "content")
                               (after "after")
                               (before "before"))})

However, if I reverse the order of the before and after transformations, it prints a seemingly random string "1659376468192659294528192", between the "content" and "after". I think I've seen Om do this in situations where you're not passing in a component where one is expected. Am I missing something here? Thanks for the library!

replace-vars

It would be great to have replace-vars in kioo.

Having trouble building this project

Is there some setup required in advance of trying to build Kioo? I'm trying to diagnose issues 55 and 60 but can't get a cloned repo to build. Do I need to install phantomjs to get to a REPL I can poke at the source with? Thanks!

update om example code

I'd help out but I can't figure out how to get kioo to work with the newest Om (0.5.0, and the example code is at 0.1.5). There are several breaking changes, for example, om/component no longer exists.

Improper tag nesting

I was playing around with the Om example and changed part of main.html from:

<li class="nav-item"><a href="#">Placeholder</a></li>

to

<li class="nav-item">
    <a href="#">
        <h1>Placeholder</h1>
    </a>
</li>

Additionally, I changed the nav item snippet from:

(defsnippet my-nav-item "main.html" [:.nav-item]
  [[caption func]]
  {[:a] (do-> (content caption)
              (listen :onClick #(func caption)))})

to

(defsnippet my-nav-item "main.html" [:.nav-item]
  [[caption func]]
  {[:a] (listen :onClick #(func caption))
   [:h1] (content caption)})

The resulting HTML is:

<li class="nav-item" data-reactid=".0.0.1.0">
    <a href="#" data-reactid=".0.0.1.0.0"></a>
    <h1 data-reactid=".0.0.1.0.1">home</h1>
</li>

Why doesn't the h1 tag remain nested inside the a tag? I'm compiling against the lastest Kioo version from master (https://github.com/ckirkendall/kioo/tree/c5cf99cb9ddcf6758d6daaeb68621457dd8cc942).

"WARNING: File does not contain selector" should skip over attr?

IMHO, attr? selector is meant for cases where the selector may or may not match any dom element. I use this selector for generic selection

e.g. I use data-message attribute on dom elements for internationalization and later change it in a generic way using (attr? :data-message).

Add some way to compose selectors

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?

do-> with a lifecycle or a listen on react events seems to short circuit renders

When we have some code like:

(do->
  (listen :onUpdate (fn [e] (.log js/console "not printing")))
  (content "Not rendered"))

The same thing happens with the lifecycle

(do->
  (lifecycle {:will-mount blah :will-update blah}))
  (content "Not rendered"))

Flipping the order of the expressions also short circuits.

Here is the funny bit: listening to the onRender gets the events, but the kioo content still doesn't happen

(do->
  (listen :onRender (fn [e] (.log js/console "does print!")))
  (content "Not rendered"))

onRender's behavior stays the same even if you swap expression order.

Parsing Error with HTML comments

Okay, moving forward with the project! We found a case that gives a NPE:

    <div id="timer" class="row">
    </div> <!-- / timer -->

I'm not sure which layer this affects, so reporting it here.

Here's the stacktrace:

aused by: java.lang.NullPointerException
    at clojure.core$name.invoke(core.clj:1505)
    at kioo.om$get_om_sym.invoke(om.clj:12)
    at kioo.om$emit_node.invoke(om.clj:24)
    at kioo.core$compile_node.invoke(core.clj:110)
    at kioo.core$compile$fn__47513.invoke(core.clj:117)
    at clojure.core$map$fn__4207.invoke(core.clj:2485)
    at clojure.lang.LazySeq.sval(LazySeq.java:42)
    at clojure.lang.LazySeq.seq(LazySeq.java:60)
    at clojure.lang.RT.seq(RT.java:484)
    at clojure.lang.LazilyPersistentVector.create(LazilyPersistentVector.java:31)
    at clojure.core$vec.invoke(core.clj:354)
    at kioo.core$compile.invoke(core.clj:117)
    at kioo.core$compile_node.invoke(core.clj:106)
    at kioo.core$compile$fn__47513.invoke(core.clj:117)
    at clojure.core$map$fn__4207.invoke(core.clj:2485)
    at clojure.lang.LazySeq.sval(LazySeq.java:42)
    at clojure.lang.LazySeq.seq(LazySeq.java:60)
    at clojure.lang.RT.seq(RT.java:484)
    at clojure.lang.LazilyPersistentVector.create(LazilyPersistentVector.java:31)
    at clojure.core$vec.invoke(core.clj:354)
    at kioo.core$compile.invoke(core.clj:117)
    at kioo.core$compile_node.invoke(core.clj:106)
    at kioo.core$compile$fn__47513.invoke(core.clj:117)
    at clojure.core$map$fn__4207.invoke(core.clj:2485)
    at clojure.lang.LazySeq.sval(LazySeq.java:42)
    at clojure.lang.LazySeq.seq(LazySeq.java:60)
    at clojure.lang.RT.seq(RT.java:484)
    at clojure.lang.LazilyPersistentVector.create(LazilyPersistentVector.java:31)
    at clojure.core$vec.invoke(core.clj:354)
    at kioo.core$compile.invoke(core.clj:117)
    at kioo.core$component_STAR_.invoke(core.clj:97)
    at kioo.om$component.doInvoke(om.clj:40)
    at clojure.lang.RestFn.applyTo(RestFn.java:146)
    at clojure.lang.AFunction$1.doInvoke(AFunction.java:29)
    at clojure.lang.RestFn.applyTo(RestFn.java:137)
    at clojure.core$apply.invoke(core.clj:621)
    at cljs.analyzer$macroexpand_1.invoke(analyzer.clj:1376)
    at cljs.analyzer$analyze_seq.invoke(analyzer.clj:1412)
    at cljs.analyzer$analyze$fn__3162.invoke(analyzer.clj:1505)
    at cljs.analyzer$analyze.invoke(analyzer.clj:1498)
    ... 76 more

kioo with quiescent?

I tried to find some information on this but couldn't find anything. Anyone tried kioo with quiescent please? Do they work together?

Request: support html-content

I'm looking to try using this, but have a requirement to include raw HTML from a database. I know it's listed as "won't be supported" but it would be quite useful in this case...

Compile-time transforms?

We have this situation here where we want to add translation / i18n to our templates.

Most of the translatable strings are hard-coded into the HTML templates, so what we would ideally want is a way to hook into the compilation process that detects translation syntax and injects calls to a translation function. IMO, the cleanest way for this would be to add an optional field to the emitter options where one could inject a transformation function which will be run after parsing the HTML template, but before handing it to the emitter.

Does that sound like a reasonable idea, and how would I go about it? It seems to me that this would require patching kioo itself, but maybe there are other ways of getting what I want?

access to owner inside on-mount listener?

is there any way to access the compoment's owner inside on-mount (and other react events) listener? I would like to call om/get-node and have no idea where should I get the owner from...

Unsupported style properties

I am trying this library to put a bunch of verbose third-party HTML content into Om components. For the most part it is working well, but some of the HTML appears to use explicit style settings and other things that perhaps kioo is not supporting:

screen shot 2015-11-09 at 11 12 31 am

These errors appear when using the kioo template on this third-party HTML. Do you have advice?

Inserting Custom Tags (a la WebComponents)

Can we insert custom tags using Kioo (ex: <div>Hello <my-tag>World</my-tag></div>)? I'm in the market for using webcomponents, and react certainly allows it (see here).

I ask because it looks like Om Next still employs whitelisting (see here), which React doesn't do anymore (at least from JSX).

lein cljx at the wrong place

Thanks for kioo, looks promising.

The instructions from the README.md says to run lein cljx from kioo/example/reagent but I guess this is from kioo, where the profile contains :cljx.

Just reporting in case.

Thanks,

kioo 0.4.0 throws NPE if deftemplate filename does not exist

I'm guessing this is actually a problem in enlive / tagsoup, but it manifests as a kioo problem. If the filename specified in (deftemplate) is not found, lein cljsbuild will fail with a NullPointerException.

I added a gist with a minimal case here, and can provide more detail if needed but this is very easy to reproduce. The full stack trace is here, but the guts of it are basically:

Caused by: java.lang.NullPointerException
    at net.cgrand.tagsoup$parser$fn__4889.invoke(tagsoup.clj:31)
    at net.cgrand.tagsoup$parser.invoke(tagsoup.clj:31)
    at net.cgrand.enlive_html$eval4930$fn__4931.invoke(enlive_html.clj:88)

Possibly this is more of a kioo -> enlive -> tagsoup dependency tree issue, but in the interests of user-friendliness, it would be nice if kioo checked to make sure the filenames specified in deftemplate / defsnippet are accessible, and throw a nicer error if they are not.

Om cursors?

Given the following example:

(defsnippet my-header "main2.html" [:header]
  [{:keys [points] :as data}]
  {[:h1] (content points)
    [:h1] (listen :on-click (fn [e] (om/transact! data :points inc))})

(deftemplate my-page "main2.html"
  [data]
  {[:header] (substitute (my-header data))})

I'm using kioo with Om, and in Om all application state is being shared via Om cursors. I would have expected that the template / snippet local state thus would be cursors, too. But instead they seem to be normal Clojure data structures, as I'm getting the following error when trying to do use transact on the data (as in the example, clicking the h1):

Uncaught Error: No protocol method ITransact.-transact! defined for type cljs.core/PersistentHashMap: 

Is there a setting I need to define to get cursors, or how would I get the appropriate cursor in the snippets / templates? I'm sorry if I misunderstood something obvious :)

Cheers & Thanks,
Benedikt

Multiple transformations on one node?

It appears that kioo cannot do two transformations on the same node. Doing so produces a rather spectacular parse error during cljs compilation.

Take for example /example/om/src/kioo_example/core.cljs and add a transformation targeting all divs:

(deftemplate my-page "main.html"
  [data]
  {[:header] (substitute (my-header data))
   [:.content] (content (:content data)) ; Targets a div with class content
   [:div] (set-attr :style "color: red;")}) ; ADDED - Targets all divs

The offending piece of code in the generated JavaScript appears to be:

// kioo.core.node is not a valid function parameter name
(function (kioo.core.node) { /* Transformations targeting div.content */ })

The README doesn't seem to mention multiple transformations on one node as a limitation, but I may be missing something. In some cases, (do-> …) is an acceptable workaround, but in other cases this leads to rather verbose code. Here's a case that could benefit from multiple transformations on one node:

(defsnippet login-template "templates/login.html" [:#content]
  [login-disabled? login-fn]
  {[:#email-field]       (set-attr :ref "emailField")
   [:#password-field]    (set-attr :ref "passwordField")
   [:#login-button]      (set-attr :onClick login-fn)
   #{[:input] [:button]} (set-attr :disabled login-disabled?)})

deftemplate breaks under advanced compilation if html contains script tags

This has taken me quite some time to figure out ...

It makes sense that source html containing scripts are not supported. However, since this only breaks under advanced compilation when the compiled code is actually running in the browser, and that the browser stack trace and error message aren't helpful at all, it would be much better that such errors are caught earlier, for example at compile time.

Kioo 0.4.1-SNAPSHOT + Reagent 0.4.2 component not updated when using lifecycle

After a clear of my .js files and a fresh cljsbuild I'm experiencing a very frustrating and new issue I did not have before (TM) with kioo's lifecycle function.

I can't explain why, but my components aren't updated anymore IF I implement ANY lifecycle method in a defsnippet.

In order to reproduce it and isolating any specificity of my own project I've copied the example project in kioo's repository and the behavior is the same.

I've created a specific repository in order for you to test, the issue is here : https://github.com/arnaudbos/kioo-reagent/blob/master/src/kioo_example/core.cljs#L25

The only difference with the original example is I bumped the dependencies and used the lifecycle function:

kioo 0.3.0 -> 0.4.1-SNAPSHOT
clojure 1.5.1 -> 1.6.0
cljsbuild 1.0.1 -> 1.0.4
clojurescript 0.0-2138 -> 0.0-2511
reagent 0.2.1 -> 0.4.2

Is it a problem with react ? reagent ? kioo ? me ?

Thanks!

Snapshot release

Could you release the current version as a snapshot on Clojars? I'd like to put a reliable dependency in my project.

Integrating with ClojureScript's auto

It's not exactly kioo's problem, but if you update a kioo template, the ClojureScript compiler doesn't recompile. Not sure if anything can be done about this (short of a modification to the ClojureScript compiler, which would require a lot of thought).

Transformation on a set of elements not working

If I'm reading the docs correctly, I should be able to apply a transformation to two different selectors using a set, e.g. #{[:h1] [:h2]} (some-transformation…). The set syntax seems to be working if there's only one selector in the set, e.g. #{[:h1]}, but adding a second selector causes nothing to happen.

I was able to reproduce this by editing /example/om/src/kioo_example/core.clj as follows:

(defsnippet my-header "main.html" [:header]
  [{:keys [heading navigation]}]
  {[:h1] (content heading)
   [:ul] (content (map my-nav-item navigation))
   #{[:h1] [:ul]} (set-style :font-style "italic")}) ; This does not work

Using either #{[:h1]} or #{[:ul]} has the expected effect.

clone-for?

is there an equivalent to enlive's clone-for in the API? I'd love to add this, or see best practices about how to get around it.

Om: Add example of a component with local state

The current examples show how to create Om components that depend on the global app state but it is not clear how to create one that uses a local component state. Having an example would be therefore nice.

This is what I do, though I am not sure it is the best way - essentially wrapping a snippet in a stateful component:

(defsnippet search-html "index.html"
  [:#search]
  [{:keys [value]} owner]
  {[:#search-input] (kioo/do->
                          (kioo/set-attr :value value)
                          (kioo/set-attr :onChange #(handle-search % owner)))})

(defn search-input 
  "Stateful wrapper around the search Kioo template"
  [app owner]
    (reify
      om/IInitState
      (init-state [_] {:value nil})
      om/IRenderState
      (render-state [this state] (search-html state owner))))

;;;; Somewhere later, when attaching to a root:
;; (om/build search-input (om/graft {} app))

Thank you!

Using lifecycle appears to break rendering

Hello! It's possible I'm using lifecycle incorrectly, but it doesn't seem to be working as expected.

Lifecycle functions get called, but snippets don't get rendered. E.g.,

(defsnippet mysnippet "some.html" [:#snippet]
  [data]
  {[:h1] (content "hello")})

(deftemplate mytemplate "main.html"
  [data]
  {[:#container] (do-> (content (mysnippet data))
                       (lifecycle {:will-mount (fn [this] (.log js/console "mounted!"))}))})

"mounted" will be printed to the console, but mysnippet doesn't render.

kioo.utils/WrapComponent supplies implementations for lifecycle functions as well as render and shouldComponentUpdate, but it looks like it expects them all to be implemented in a lifecycle function map.

kioo 0.5.0?

Hi

I‘ve noticed that there is a 0.5.0 release of kioo on Clojars, but the corresponding commit doesn’t appear to be on github. Now I’m wondering if it’s a good idea to use that version or not.

  • maybe 0.5.0 is an official release, and you just forgot to push to github
  • maybe 0.5.0 is an official release, but you won’t or can’t publish the source code on github, at least not now (I’ve seen this happen for all sorts of good reasons with open source projects)
  • maybe releasing 0.5.0 was an accident, and I shouldn’t use it (I can imagine that removing a version from clojars would be difficult)
  • maybe I’m no good at mind-reading and I should just ask, hence this issue ;-)

colSpan disappearing from <td>

I am defining a td in my HTML file as:

<td colSpan="2">

But the resultant element is just a plain

<td data-reactid...>

... without the colSpan.

Eliminate warning about replace in kioo/util

I'd prefer not to have to repeatedly see this:

WARNING: replace already refers to: #'clojure.core/replace in namespace: kioo.util, being replaced by: #'clojure.string/replace

Would it be possible to tweak the code to eliminate it?
For the one time you call replace, maybe just call clojure.string/replace ?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.