GithubHelp home page GithubHelp logo

ckirkendall / kioo Goto Github PK

View Code? Open in Web Editor NEW
403.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 Issues

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!

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

Snapshot release

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

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.

"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).

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...

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 ?

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).

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?

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.

replace-vars

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

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

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

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,

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!

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?

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?

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.

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 ;-)

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.

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!

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 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

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?

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

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.

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.

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).

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!

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).

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.

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

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...

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.

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.

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.

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?)})

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.