A template language for incremental-dom or DSL for javascript views
APACHE-2.0 License
Documentation | http://tailhook.github.io/khufu/ |
Demo | http://tailhook.github.io/khufu/demo.html |
Status | beta ¹ |
At a glance, Khufu is a template-engine for incremental-dom.
But more characteristically I call it is a domain-specific language (DSL) for view-driven single-page applications.
The boring list of features:
[1] More verbose status: I feel that the language itself (the syntax) is 90% complete (thanks to it's predecessor). There are ugly edge cases of the compiler here and there. And the server-side render is not implemented yet. Otherwise, the project is small enough to just work.
npm install [email protected] --save-dev
npm install [email protected] --save
[2] Indentation-based syntax is a bonus. [3] Sure, the model proposed here doesn't work for everyone.
It's mostly a DSL around HTML, that looks a lot like just a template language similar to Jade, that compiles into Incremental DOM. Additionally Khufu:
It means when you design an application you build a single powerful view. And all server-side data are fetched when a user enters some subview and is disposed when user leaves the view (of course, data can be prefetched and cached, but that's optimization orthogonal to what we're discussing here).
For example:
import {search, set_query} from 'myapp/search'
import {image, load} from 'myapp/util/image_loading'
import {select} from 'myapp/action_creators'
view main():
<div>
store @results = search
<form>
<input type="text" placeholder="search">
link {change, keyup} set_query(this.value) -> @results
if @results.current_text:
if @results.loading:
<div.loading>
"Loading..."
else:
<div.results>
for item of @results.items:
<div.result>
store @icon_loaded = image | load(item.img)
if @icon_loaded.done:
<img src=item.img>
else:
<div.icon-loading>
<div.title>
item.title
This example displays a search box. When some search query is typed into the input box, search request is sent to the server immediately⁴. This displays "Loading..." stub and replaces the stub with the results when they are loaded from a server. There is also the code to download images asynchronously.
Some explanations:
div.cls
is shortcut for <div class="cls">
store
denotes a redux storelink
allows to bind events to an action (or an action creator)The store thing might need a more comprehensive explanation:
@
to get nice property access syntax⁶
[4] Sure, you can delay requests by adding RxJS or redux-saga
or any other middleware to the store
[5] Yes, we attach resources (such as network requests) to stores,
using middleware
[6] Otherwise would need to call getState()
each time. We also
cache the result of the method for subsequent attribute access
Right. You do a Khufu view, add events and everything works. Just like you have been doing HTML page and add jQuery plugins to make that work.
There are few crucial improvements, however:
You can also think of each view function being a component similar to what you find in react or angular. Have I said that syntax is much more readable?