News for hackers. Stuff that matters.
Re:Show HN: I built a 4kb alternative to React, Vue, etc for... by scotty79 on Friday January 08, 2021 @06:24AM (#25683571)
This is a very cool experiment and possiby a tool. I have nothing to comment on custom html elements, binding or flow but templating engines always interested me.

I like how your templating language is minimalistic (not embedding whole js syntax inside) and is valid HTML (could be prepared using HTML authoring tools).

I have few remarks comming from my expeirinece in wirting and using minimalistic templating engines.

--

This templates tightly integrate with html and magically interpret the view model values depending on the context they are used in html.

I think it could be better to explicitely indicate in place of use that the value will not be used directly.

Not

    <div hidden="{{hide}}">
but

    <div :hidden="{{hide}}"> 
    <div _hidden="{{hide}}">
    <div :hidden="hide">
This would make it explicit, aria would not need to be an exception and HTML and your syntax would be clearly separated. You could just pass argument through funcion named `hidden` (or `class` or `style`) and even make whole thing pluggable with custom functions that preprocess the argument into the attribute. (Or even multiple attributes if necessary).

---

Passing current item from `#each` loops into event handlers implicitly is very cool, but you might want to think about what if you have nested loops.

Maybe it would be cooler to pass not just the element but sort of `context` object that contains current elements of all nested loops and perhaps some other stuff in the future?

Also you might consider passing it not only into event handlers but all functions called from template.

Again you could use `:onclick` instead of `onclick` to indicate that there's some additional magic happening.

---

You might want to consider making loop variable optionally anonymous to reduce the noisiness of looping.

    <!-- #each in people -->
    <li>Hello {{ .name }}</li>
    <!-- /each -->
---

You could do form binding though `:name` to indicate that something beyond just usual HTML is happening and allow people to opt-out for some controls by using just `name` instead of `name`.

---

All of this could easily work with pre-rendering and hydration by not removing `:something` attributes when `something` function is called to do the appropriate magic.

Re:Show HN: I built a 4kb alternative to React, Vue, etc for... by defx on Friday January 08, 2021 @08:47AM (#25684658)
RE "Also you might consider passing it not only into event handlers but all functions called from template": By design, there's no support for calling functions from templates other than via event handlers, or via getters (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Refe...), which are treated just like any other property as far as the template is concerned.
Re:Show HN: I built a 4kb alternative to React, Vue, etc for... by defx on Friday January 08, 2021 @08:46AM (#25684650)
Thanks Scotty, your feedback is greatly appreciated! Yes - with nested loops you simply get the datum for whichever block item raised the event, nested or not.
Re:Show HN: I built a 4kb alternative to React, Vue, etc for... by scotty79 on Friday January 08, 2021 @11:16AM (#25686158)
What I meant was that sometimes in the handler you might need datum both for the item that the handler is in and the item of the surrounding block (or even blocks).

    <!-- #each row in rows -->
    <tr>
    <!-- #each field in row -->
    <td>{{field}}<button onclick="edit">...</button></td>
    <!-- /each -->    
    </tr>
    <!-- /each -->
`edit` might need both row and field to perform the edit, and even possiby # of row and # of field.

So a richer context passed to handler might be useful.

---

Regarding not calling functions from template by design it's all good, but you might consider introducing the ability to call some functions (through html attributes prefixed with : or _) during template interpolation.

Those could be plugins of your templating system that perform some operations (like generating attribute "hidden" or not depending on boolean argument, or binding form field to view model, or binding event handler, or something else).

Those functions might benefit from knowlege of template context they were called from (for example handler binders might want to pass this context along into bound handlers, like you already do with current item and your built-in handler binding solution).

I understand that this a bit different from what you made, but by extracting all of that functionality into separate self-contained functions exposed to the user, instead keeping it as integral, internal part of your template interpolation process, you could do yourself a favor. Because people who are missing some funtionality you haven't thought of yet might implement it themselves easily. This might increase usage of your framework and contributions from users.

---

Those are just some ideas where you might go further with your templating engine while keeping it simple. I hope I communicated them clearly enough, but if not and you are interested, please ask.

Re:Show HN: I built a 4kb alternative to React, Vue, etc for... by defx on Saturday January 09, 2021 @08:18AM (#25700114)
Thanks Scotty, you communicated these ideas very clearly and this all makes perfect sense to me. One of my main goals with Synergy is simplicity, which in the context of this discussion would mean a lower level of configurability / customisation, so pulling that template functionality out and moving decisions on to the user would (as you say) take the design in quite a different direction. A perfectly valid direction though, and one that would doubtlessly better suit some folk more than my approach - I'd love to see you fork Synergy and implement these ideas!