<!-- #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.
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
but 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.
---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.