npm i -D mithril-templatevar mithrilTemplate = require("mithril-template")
console.log(mithrilTemplate('<h1 class="greetings">Hello World</h1>'))The most basic form of data binding is text interpolation using the “Mustache” syntax (double curly braces):
<div class="greeting">
Hello {{ name }}!
</div>that will output:
m(".greeting","Hello "+name+"!")Awesome, right? So let's dive deeper.
Interpolations can't be used within html tag definiition (also in attributes), so this code is invalid:
<div key="{{ foo }}" class="bar">
Hello World!
</div>instead use a binding attribute:
<div :key="foo" class="bar">
Hello World!
</div>output:
m(".bar",{key:foo},"Hello World!")Note that { and } characters are reserved in templates for interpolation, so if you have to write them use this workaround:
<span>This is how to use {{ "{" }} and {{ "}"+"}" }} chars.</span>You can't use { and } html entities because mithril will escape them
To embed component, his name must end on -component, be kebab-case (a.k.a. snake-case) that will be automatically converted to camelCase and can't be self-closed tag:
<custom-component></custom-component>output:
m(customComponent)Attributes that are not followed by : (colon) will be ommited.
<custom-component class="custom-class"></custom-component>output:
m(customComponent)so if you want to pass data into component use binding syntax instead:
<custom-component :class="'custom-class'"></custom-component>output:
m(customComponent,{class:'custom-class'})You can nest anything inside the component:
<custom-component :key="'unique420'">
<span style="color: red;">Hello!</span>
</custom-component>output:
m(customComponent,{key:'unique420'},m("span[style='color: red;']","Hello!"))Nested data will be available in vnode.children component view property:
<!--customComponent view-->
<div class="styled-message">{{ vnode.children }}</div>output:
m(".styled-message",vnode.children)You probably noticed that html attributes are compiled to hardcoded selectors:
<input type="text" name="name" value="name">output:
m("input[type=text][name=name][value=name]")if you want to bind html attribute just put : (colon) before attribute name:
<input type="text" name="name" :value="name">output:
m("input[type=text][name=name]",{value:name})you can also bind events and lifecycle hooks:
<div :oninit="initialize" :onclick="doSomething">
Hello World!
</div>output:
m("div",{oninit:initialize,onclick:doSomething},"Hello World!")Directives are putted as html attributes that are previxed by * (asterisk).
The result hyperscript code will be surrounded by javascript flow statements.
There are four available directives, that can be mixed togheder:
forifelseifelse
Let's explain, but note that examples' outputs below are unminified, for better readability.
usage:
<div class="foo" *if="varr % 2 == 0">
odd
</div>output:
varr % 2 == 0
? m(".foo","odd")
: ""<div class="foo" *if="varr % 2 == 0">
odd
</div>
<div *elseif="varr % 5 == 0">
divisible by 5
</div>
<div *else>
other
</div>output:
[
varr % 2 == 0
? m(".foo","odd")
: varr % 5 == 0
? m("div","divisible by 5")
: m("div","other")
]<ul>
<li *for="item in items">
{{ item.name }}
</li>
</ul>output:
m("ul", items.map(function(n){
return m("li", n.name)
}))<ul>
<li *for="item, index in items">
#{{ index }}: {{ item.name }}
</li>
</ul>output:
m("ul", items.map(function(n, a){
return m("li","#"+a+": "+n.name)
}))for loop can be used with else (or elseif) statement:
<ul>
<li *for="item, index in items">
#{{ index }}: {{ item.name }}
</li>
<li *else>
items not found
</li>
</ul>output:
m("ul", items.length
? items.map(function(n, t){
return m("li","#"+t+": "+n.name)
})
: m("li","items not found")
)so if items array is empty (loop won't execute even once) then else statement will be executed
To maximally compress output- whitespaces whose belongs to tags are not properly handled, so if you write this code:
foo <span>bar</span> baz quxthe transpiled code will be:
["foo",m("span","bar"),"baz qux"]instead of:
["foo ",m("span","bar")," baz qux"]that you may expected. So if you need space between text and tag do it by this workaround:
foo{{ " " }}<span>bar</span>{{ " " }}baz qux- properly support splats for better minification
- produce maximally minified js code (also minify literal selectors)