rauhs / hicada Goto Github PK
View Code? Open in Web Editor NEWHiccup compiler similar to sablono
License: Eclipse Public License 1.0
Hiccup compiler similar to sablono
License: Eclipse Public License 1.0
I have some boring components which take no parameters. Currently [:> Example]
doesn't handle that at all. Would a PR to add that be welcome?
I'm obviously failing to get my head round using hicada with Rum. Could do with a more detailed example.
After reading the current docs I tried the setup in this gist:
https://gist.github.com/gmp26/b02c7b1068f45747a4d43e4ea4a4370a
but it's complaining about a missing compiler/compile-attrs var.
Full details in the gist.
Hi @rauhs, I have a fork of Hicada that includes an interpreter and uses cljs type inference to reduce overhead. I'd love to privately discuss merging upstream and get your feedback.
If you're interested, please email me: [email protected]
I plan to blog about my work in a week, and would love to hear from you before then.
In any event, thanks for your work on Hicada. It's great!
I have been playing with the :server-side?
option of hicada and I stumbled upon a weird behavior. Right now hicada uses compile-config
to change the HTML attributes of an element to a camelCase version (among other things).
:class -> :className
and :for -> :htmlFor
only makes sense for React:style
attribute keys get converted to camelCase even though I specified :camelcase-key-pred
to be (constantly false)
.The solution I propose is: when we :server-render?
any kind of attribute conversion should be delegated to the library that does the SSR and not by hicada. That means that joining the classes and camelCasing the style keys are decisions that should be made by the SSR library.
diff --git a/src/hicada/compiler.clj b/src/hicada/compiler.clj
index 513015f..6af65de 100644
--- a/src/hicada/compiler.clj
+++ b/src/hicada/compiler.clj
@@ -379,7 +379,7 @@
"Emits the final react js code"
[tag attrs children]
(let [{:keys [transform-fn emit-fn inline? wrap-input?
- create-element array-children?]} *config*
+ create-element array-children? server-render?]} *config*
[tag attrs children] (transform-fn [tag attrs children *env*])]
(if inline?
(let [type (or (and wrap-input? (util/controlled-input-class tag attrs))
@@ -405,7 +405,7 @@
wrapper-class
(tag->el tag))
(tag->el tag))
- cfg (to-js (compile-config attrs))]
+ cfg (if server-render? attrs (to-js (compile-config attrs)))]
(if emit-fn
(emit-fn el cfg children)
(apply list create-element el cfg children))))))
What do you think?
I've tried a few things:
attrs
into {:attrs attrs}
- but it was recursively changedBut haven't found a way to bypass the to-js part of hicada, this would be really useful in order to have pure clojurescript components which define an interface of some kind (in this case, taking a js object with attrs
set to a clojurescript map).
I'm not sure how I would make this change to hicada exactly. It could look for metadata perhaps? But that might be a little hacky.
Thanks for the lib! It seems to be a good alternative to Sablono. I'm especially very pleased by the support for compiling when
, if-not
, etc. forms that were (suprisingly!) missing in Sablono.
I'm just slightly annoyed with the syntax used in case the attributes are a variable (or function call, I suppose). I'm talking about [:> :div props child0 child1]
.
Could you possibly use the same technique that is used in Sablono for attribute hinting, e.g. [:div ^:attrs props child0 child1]
? I find it more readable, what do you think?
Imagine you have this html
macro defined:
(defmacro my-html
[body]
(let [opts {:create-element 'js/create-element
:rewrite-for? true
:array-children? false}]
(-> body (hicada.compiler/compile opts {} &env))))
When you use this macro on hiccup that contain cond with more than 4 conditions, the last condition does not respects the :create-element
option and just uses js/React.createElement
. Example:
(macroexpand-all '(my-html (cond (nil? a) [:div {}] (number? a) [:div {}] (= 1 2) [:div {}] (= 4 5) [:div {}] :else [:div {}])))
=> (if (nil? a) (js/create-element "div" nil) (if (number? a) (js/create-element "div" nil) (if (= 1 2) (js/create-element "div" nil) (if (= 4 5) (js/create-element "div" nil) (if :else (js/React.createElement "div" nil) nil)))))
Look at the last if
, where the js/React.createElement
is used instead of js/create-element
defined in the macro options.
Hello,
It's unclear from the Readme (and the Medium post). Does hicada supoort rendering the same component in both CLJ to a string and in CLJS ? We're using rum in a isomorphic setup and I'm interested to try out hicada.
Hi @rauhs
At penpot, today we upgraded from 0.1.8 to 0.1.9 and found a little regression introduced in 6f3df03
diff --git a/src/hicada/compiler.clj b/src/hicada/compiler.clj
index 99167cd..60b5159 100644
--- a/src/hicada/compiler.clj
+++ b/src/hicada/compiler.clj
@@ -17,8 +17,13 @@
[hicada.normalize :as norm]
[hicada.util :as util]))
-(def default-handlers {:> (fn [_ klass attrs & children]
- [klass attrs children])
+(def default-handlers {:> (fn
+ ([_ klass]
+ [klass {} nil])
+ ([_ klass attrs & children]
+ (if (map? attrs)
+ [klass attrs children]
+ [klass {} (cons attrs children)])))
When we build props as a javascript object and then pass it as props, the result is that hicada does not identifies that is a map (because at compile time is just a symbol) and passes it together with children.
The workaround is just overwrite :>
handler on our codebase. But still wanted open the issue because this commit changes the previous behavior.
Edit: wording.
Hello,
It seems like Hicada is useful to compile Hiccup-like syntax to Javascript code for React.js-like libraries. What do you think about having it compile to HTML directly so it can be used server side ?
Hello,
I'm trying hicada on a toy project and on this form:
(defn footer [props]
...)
(el/html
[:> footer])
I get the following error: clojure.lang.ArityException: Wrong number of args (0) passed to: hicada.compiler/fn--24353
This comes from the fact that on 0.1.8, the handler function for :>
still doesn't handle this arity but it does on master.
0.1.8:
hicada/src/hicada/compiler.clj
Lines 20 to 21 in 555db38
hicada/src/hicada/compiler.clj
Lines 20 to 26 in 90994bd
That would be nice to have a 0.1.9 version.
Thanks a lot
It looks like Hicada could walk the entire sexp tree by adding additional clause to compile-html
:
(defn compile-html
"Pre-compile data structures"
[content]
(cond
(vector? content) (compile-element content)
+ (sequential? content) (doall (map -compile-html content))
(literal? content) content
:else (compile-form content)))
This could leave behind minor annoyance when creating a sequence of elements in map
or similar functions and make it possible to write Hiccup in local bindings, etc. etc:
(html
(let [el [:h1]]
[:div
el
(map (fn [n]
[:li n])
(range 4))]))
;; outputs
(let
[el (js/React.createElement "h1" nil nil)]
(js/React.createElement
"div"
nil
el
(map (fn [n] (js/React.createElement "li" nil n)) (range 4))))
Not sure if this can slow down compilation, but in general there's not much Hiccup per component.
What do you think? Any potential issues?
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.