A template engine. The goal is to be portable: khala should be easily ported to any language, the templates are supposed to work in each implementation and should be writeable by anyone who knows HTML. To achieve this, we define the following characteristics:
- Parseable, valid HTML:
- To parse khala, you should be able to use an HTML parser that is available in your language of choice.
- This also means that you can open a khala template in a browser. It can contain example data so it makes sense.
- It is logic-less so the templates can be used with different host languages.
- Components are first class citizens.
- A template with all its modules should always be converted to a single function in the host language.
Every valid HTML document is a valid khala template. You can add attributes to your nodes to make the template dynamic.
<h1 data-replace="title">My Example Title</h1>
This will replace the content of the tag with the value of title
. What is the
value of title? This depends on the object you provide. Here is an example:
class ViewModel
def title
"My Title"
end
end
template = Khala::Template.new('<h1 data-replace="title">My Example Title</h1>')
template.execute(ViewModel.new) # "<html><body><h1>My Title</h1></body></html>"
This is how it works in Ruby. Depending on the language, this can also work without Objects – the template could for example be converted into a function that takes a data structure and returns a String.
We can also iterate over collections with data-each
. It takes the form
item: collection
, where collection
is the name of the list you want to
iterate, and item
is the variable name it takes during the iteration:
<ul class="shopping-list">
<li class="shopping-item" data-each="item: items" data-replace="item">
Example Item
</li>
</ul>
The replacement can also happen in a nested tag:
<ul class="shopping-list">
<li class="shopping-item" data-each="item: items">
Item: <strong data-replace="item">Example Data</strong>
</li>
</ul>
You can also ignore certain tags if you only need them for example data:
<ul class="shopping-list">
<li class="shopping-item" data-each="item: items" data-replace="item">
Example Item 1
</li>
<li class="shopping-item" data-ignore>
Example Item 2
</li>
</ul>
You can only show a tag if a certain condition is fulfilled:
<h1>Hello World</h1>
<a href="/admin" data-if="is_admin">Admin Area</a>
We want to be able to reuse components. In order to do that, we store the template
for a component in a file and then reference it. Let's put the following content
in a file called strong.html
:
<strong class="really-strong" data-replace="label">Example Item</strong>
Now we can reference it like this from another template:
<h1 data-replace="name">Example Shopping List</h1>
<ul class="shopping-list">
<li class="shopping-item" data-each="item: items">
<c-strong label="item.name">Example Item</c-strong>
</li>
</ul>
Tags that start with c-
(in this example: c-strong
) will be replaced by
rendering the template. The attributes allow you to pass data from the
current context to the rendered template (in this case, there will be
a variable label
assigned to the value of item.name
).
Currently, the "inner HTML" of these items will be removed. But I'm thinking
about passing it to the rendered template (for example as yield
). Among other
things, this will enable a use-case like a c-layout
to render something in
a shared layout.
I imagine the workflow to work something like this:
- A frontend developer works in a pattern library. They write khala templates and no presentation logic.
- Within the pattern library, components can be reused without copying.
- In the pattern library, the provided example data is shown.
- All applications that use this pattern library can use these templates, they just need to provide the presentation logic in the form of simple ViewModels or data structures.
khala is inspired by Mustache, Thymeleaf and JSX. The implementation is inspired by Erubi. It is also inspired by conversations with my amazing colleagues at @INNOQ, especially:
- @nerdbabe
- @joyheron
- @fnd
- @martinei
khala is licensed under the Apache 2.0 License.