ckirkendall / kioo Goto Github PK
View Code? Open in Web Editor NEWEnlive/Enfocus style templating for Facebook's React and Om in ClojureScript.
License: Eclipse Public License 1.0
Enlive/Enfocus style templating for Facebook's React and Om in ClojureScript.
License: Eclipse Public License 1.0
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!
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
Do you have any plans to upgrade supported React version?
Could you release the current version as a snapshot on Clojars? I'd like to put a reliable dependency in my project.
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.
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)
.
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...
I just checked out the reagent-template and added kioo "0.4.1-SNAPSHOT" to the dependencies. Now I get the complie error
Referred var reagent.impl.template/as-component does not exist at line 1
Is the commit for changing the var missing in the snapshot?
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 ?
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?
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.
It would be great to have replace-vars in kioo.
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
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
If the HTML is
...
<li>something</li>
...
then
...
[:li] (add-class "some-class")
...
throws an error.
Currently, the simple workaround is to add 'class=""'.
I don't know what the intended semantics of "add-class" are but I had assumed that you can "add" the first class.
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,
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!
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.
Any ideas on how this might be supported?
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?
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.
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.
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.
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!
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.
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
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:
These errors appear when using the kioo template on this third-party HTML. Do you have advice?
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..
Would really appreciate some input before I embark on trying to fill this gap :-p
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.
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.
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).
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!
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).
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.
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
I have written a guide for troubleshooting Kioo templates and would be happy to get feedback and improvement suggestions and see the good parts integrated into the README so that other users can also benefit from it:
http://theholyjava.wordpress.com/2014/04/08/kioo-how-to-troubleshoot-template-processing/
Thank you!
Regards, Jakub Holy
I tried to find some information on this but couldn't find anything. Anyone tried kioo with quiescent please? Do they work together?
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...
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.
ClojureScript recently introduced a type-error when re-find is called with a non-string: clojure/clojurescript@774d458
This breaks has-class and add-class, for elements, that don't have any class, because then has-class calls re-matches with nil.
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.
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.
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?)})
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.